// Copyright 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/output/shader.h"

#include <algorithm>

#include "base/basictypes.h"
#include "base/logging.h"
#include "cc/output/gl_renderer.h"  // For the GLC() macro.
#include "gpu/command_buffer/client/gles2_interface.h"

#define SHADER0(Src) #Src
#define VERTEX_SHADER(Src) SetVertexTexCoordPrecision(SHADER0(Src))
#define FRAGMENT_SHADER(Src)    \
  SetFragmentTexCoordPrecision( \
      precision,                \
      SetFragmentSamplerType(sampler, SetBlendModeFunctions(SHADER0(Src))))

using gpu::gles2::GLES2Interface;

namespace cc {

namespace {

static void GetProgramUniformLocations(GLES2Interface* context,
                                       unsigned program,
                                       size_t count,
                                       const char** uniforms,
                                       int* locations,
                                       int* base_uniform_index) {
  for (size_t i = 0; i < count; i++) {
    locations[i] = (*base_uniform_index)++;
    context->BindUniformLocationCHROMIUM(program, locations[i], uniforms[i]);
  }
}

static std::string SetFragmentTexCoordPrecision(
    TexCoordPrecision requested_precision,
    std::string shader_string) {
  switch (requested_precision) {
    case TexCoordPrecisionHigh:
      DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
      return "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
             "  #define TexCoordPrecision highp\n"
             "#else\n"
             "  #define TexCoordPrecision mediump\n"
             "#endif\n" +
             shader_string;
    case TexCoordPrecisionMedium:
      DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
      return "#define TexCoordPrecision mediump\n" + shader_string;
    case TexCoordPrecisionNA:
      DCHECK_EQ(shader_string.find("TexCoordPrecision"), std::string::npos);
      DCHECK_EQ(shader_string.find("texture2D"), std::string::npos);
      DCHECK_EQ(shader_string.find("texture2DRect"), std::string::npos);
      return shader_string;
    default:
      NOTREACHED();
      break;
  }
  return shader_string;
}

static std::string SetVertexTexCoordPrecision(const char* shader_string) {
  // We unconditionally use highp in the vertex shader since
  // we are unlikely to be vertex shader bound when drawing large quads.
  // Also, some vertex shaders mutate the texture coordinate in such a
  // way that the effective precision might be lower than expected.
  return "#define TexCoordPrecision highp\n" + std::string(shader_string);
}

TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
                                            int* highp_threshold_cache,
                                            int highp_threshold_min,
                                            int x,
                                            int y) {
  if (*highp_threshold_cache == 0) {
    // Initialize range and precision with minimum spec values for when
    // GetShaderPrecisionFormat is a test stub.
    // TODO(brianderson): Implement better stubs of GetShaderPrecisionFormat
    // everywhere.
    GLint range[2] = {14, 14};
    GLint precision = 10;
    GLC(context,
        context->GetShaderPrecisionFormat(
            GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, range, &precision));
    *highp_threshold_cache = 1 << precision;
  }

  int highp_threshold = std::max(*highp_threshold_cache, highp_threshold_min);
  if (x > highp_threshold || y > highp_threshold)
    return TexCoordPrecisionHigh;
  return TexCoordPrecisionMedium;
}

static std::string SetFragmentSamplerType(SamplerType requested_type,
                                          std::string shader_string) {
  switch (requested_type) {
    case SamplerType2D:
      DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
      DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
      return "#define SamplerType sampler2D\n"
             "#define TextureLookup texture2D\n" +
             shader_string;
    case SamplerType2DRect:
      DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
      DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
      return "#extension GL_ARB_texture_rectangle : require\n"
             "#define SamplerType sampler2DRect\n"
             "#define TextureLookup texture2DRect\n" +
             shader_string;
    case SamplerTypeExternalOES:
      DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
      DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
      return "#extension GL_OES_EGL_image_external : require\n"
             "#define SamplerType samplerExternalOES\n"
             "#define TextureLookup texture2D\n" +
             shader_string;
    case SamplerTypeNA:
      DCHECK_EQ(shader_string.find("SamplerType"), std::string::npos);
      DCHECK_EQ(shader_string.find("TextureLookup"), std::string::npos);
      return shader_string;
    default:
      NOTREACHED();
      break;
  }
  return shader_string;
}

}  // namespace

TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
                                            int* highp_threshold_cache,
                                            int highp_threshold_min,
                                            const gfx::Point& max_coordinate) {
  return TexCoordPrecisionRequired(context,
                                   highp_threshold_cache,
                                   highp_threshold_min,
                                   max_coordinate.x(),
                                   max_coordinate.y());
}

TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
                                            int* highp_threshold_cache,
                                            int highp_threshold_min,
                                            const gfx::Size& max_size) {
  return TexCoordPrecisionRequired(context,
                                   highp_threshold_cache,
                                   highp_threshold_min,
                                   max_size.width(),
                                   max_size.height());
}

VertexShaderPosTex::VertexShaderPosTex() : matrix_location_(-1) {
}

void VertexShaderPosTex::Init(GLES2Interface* context,
                              unsigned program,
                              int* base_uniform_index) {
  static const char* uniforms[] = {
      "matrix",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  matrix_location_ = locations[0];
}

std::string VertexShaderPosTex::GetShaderString() const {
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      attribute vec4 a_position;
      attribute TexCoordPrecision vec2 a_texCoord;
      uniform mat4 matrix;
      varying TexCoordPrecision vec2 v_texCoord;
      void main() {
        gl_Position = matrix * a_position;
        v_texCoord = a_texCoord;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

VertexShaderPosTexYUVStretchOffset::VertexShaderPosTexYUVStretchOffset()
    : matrix_location_(-1), tex_scale_location_(-1), tex_offset_location_(-1) {
}

void VertexShaderPosTexYUVStretchOffset::Init(GLES2Interface* context,
                                              unsigned program,
                                              int* base_uniform_index) {
  static const char* uniforms[] = {
      "matrix", "texScale", "texOffset",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  matrix_location_ = locations[0];
  tex_scale_location_ = locations[1];
  tex_offset_location_ = locations[2];
}

std::string VertexShaderPosTexYUVStretchOffset::GetShaderString() const {
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      precision mediump float;
      attribute vec4 a_position;
      attribute TexCoordPrecision vec2 a_texCoord;
      uniform mat4 matrix;
      varying TexCoordPrecision vec2 v_texCoord;
      uniform TexCoordPrecision vec2 texScale;
      uniform TexCoordPrecision vec2 texOffset;
      void main() {
        gl_Position = matrix * a_position;
        v_texCoord = a_texCoord * texScale + texOffset;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

VertexShaderPos::VertexShaderPos() : matrix_location_(-1) {
}

void VertexShaderPos::Init(GLES2Interface* context,
                           unsigned program,
                           int* base_uniform_index) {
  static const char* uniforms[] = {
      "matrix",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  matrix_location_ = locations[0];
}

std::string VertexShaderPos::GetShaderString() const {
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      attribute vec4 a_position;
      uniform mat4 matrix;
      void main() { gl_Position = matrix * a_position; }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

VertexShaderPosTexTransform::VertexShaderPosTexTransform()
    : matrix_location_(-1),
      tex_transform_location_(-1),
      vertex_opacity_location_(-1) {
}

void VertexShaderPosTexTransform::Init(GLES2Interface* context,
                                       unsigned program,
                                       int* base_uniform_index) {
  static const char* uniforms[] = {
      "matrix", "texTransform", "opacity",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  matrix_location_ = locations[0];
  tex_transform_location_ = locations[1];
  vertex_opacity_location_ = locations[2];
}

std::string VertexShaderPosTexTransform::GetShaderString() const {
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      attribute vec4 a_position;
      attribute TexCoordPrecision vec2 a_texCoord;
      attribute float a_index;
      uniform mat4 matrix[8];
      uniform TexCoordPrecision vec4 texTransform[8];
      uniform float opacity[32];
      varying TexCoordPrecision vec2 v_texCoord;
      varying float v_alpha;
      void main() {
        int quad_index = int(a_index * 0.25);  // NOLINT
        gl_Position = matrix[quad_index] * a_position;
        TexCoordPrecision vec4 texTrans = texTransform[quad_index];
        v_texCoord = a_texCoord * texTrans.zw + texTrans.xy;
        v_alpha = opacity[int(a_index)];  // NOLINT
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

std::string VertexShaderPosTexIdentity::GetShaderString() const {
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      attribute vec4 a_position;
      varying TexCoordPrecision vec2 v_texCoord;
      void main() {
        gl_Position = a_position;
        v_texCoord = (a_position.xy + vec2(1.0)) * 0.5;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

VertexShaderQuad::VertexShaderQuad()
    : matrix_location_(-1), quad_location_(-1) {
}

void VertexShaderQuad::Init(GLES2Interface* context,
                            unsigned program,
                            int* base_uniform_index) {
  static const char* uniforms[] = {
      "matrix", "quad",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  matrix_location_ = locations[0];
  quad_location_ = locations[1];
}

std::string VertexShaderQuad::GetShaderString() const {
#if defined(OS_ANDROID)
  // TODO(epenner): Find the cause of this 'quad' uniform
  // being missing if we don't add dummy variables.
  // http://crbug.com/240602
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      attribute TexCoordPrecision vec4 a_position;
      attribute float a_index;
      uniform mat4 matrix;
      uniform TexCoordPrecision vec2 quad[4];
      uniform TexCoordPrecision vec2 dummy_uniform;
      varying TexCoordPrecision vec2 dummy_varying;
      void main() {
        vec2 pos = quad[int(a_index)];  // NOLINT
        gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
        dummy_varying = dummy_uniform;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
// clang-format on
#else
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      attribute TexCoordPrecision vec4 a_position;
      attribute float a_index;
      uniform mat4 matrix;
      uniform TexCoordPrecision vec2 quad[4];
      void main() {
        vec2 pos = quad[int(a_index)];  // NOLINT
        gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
// clang-format on
#endif
}

VertexShaderQuadAA::VertexShaderQuadAA()
    : matrix_location_(-1),
      viewport_location_(-1),
      quad_location_(-1),
      edge_location_(-1) {
}

void VertexShaderQuadAA::Init(GLES2Interface* context,
                              unsigned program,
                              int* base_uniform_index) {
  static const char* uniforms[] = {
      "matrix", "viewport", "quad", "edge",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  matrix_location_ = locations[0];
  viewport_location_ = locations[1];
  quad_location_ = locations[2];
  edge_location_ = locations[3];
}

std::string VertexShaderQuadAA::GetShaderString() const {
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      attribute TexCoordPrecision vec4 a_position;
      attribute float a_index;
      uniform mat4 matrix;
      uniform vec4 viewport;
      uniform TexCoordPrecision vec2 quad[4];
      uniform TexCoordPrecision vec3 edge[8];
      varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.

      void main() {
        vec2 pos = quad[int(a_index)];  // NOLINT
        gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
        vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
        vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
        edge_dist[0] = vec4(dot(edge[0], screen_pos),
                            dot(edge[1], screen_pos),
                            dot(edge[2], screen_pos),
                            dot(edge[3], screen_pos)) *
                       gl_Position.w;
        edge_dist[1] = vec4(dot(edge[4], screen_pos),
                            dot(edge[5], screen_pos),
                            dot(edge[6], screen_pos),
                            dot(edge[7], screen_pos)) *
                       gl_Position.w;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA()
    : matrix_location_(-1),
      viewport_location_(-1),
      quad_location_(-1),
      edge_location_(-1),
      tex_transform_location_(-1) {
}

void VertexShaderQuadTexTransformAA::Init(GLES2Interface* context,
                                          unsigned program,
                                          int* base_uniform_index) {
  static const char* uniforms[] = {
      "matrix", "viewport", "quad", "edge", "texTrans",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  matrix_location_ = locations[0];
  viewport_location_ = locations[1];
  quad_location_ = locations[2];
  edge_location_ = locations[3];
  tex_transform_location_ = locations[4];
}

std::string VertexShaderQuadTexTransformAA::GetShaderString() const {
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      attribute TexCoordPrecision vec4 a_position;
      attribute float a_index;
      uniform mat4 matrix;
      uniform vec4 viewport;
      uniform TexCoordPrecision vec2 quad[4];
      uniform TexCoordPrecision vec3 edge[8];
      uniform TexCoordPrecision vec4 texTrans;
      varying TexCoordPrecision vec2 v_texCoord;
      varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.

      void main() {
        vec2 pos = quad[int(a_index)];  // NOLINT
        gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
        vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
        vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
        edge_dist[0] = vec4(dot(edge[0], screen_pos),
                            dot(edge[1], screen_pos),
                            dot(edge[2], screen_pos),
                            dot(edge[3], screen_pos)) *
                       gl_Position.w;
        edge_dist[1] = vec4(dot(edge[4], screen_pos),
                            dot(edge[5], screen_pos),
                            dot(edge[6], screen_pos),
                            dot(edge[7], screen_pos)) *
                       gl_Position.w;
        v_texCoord = (pos.xy + vec2(0.5)) * texTrans.zw + texTrans.xy;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

VertexShaderTile::VertexShaderTile()
    : matrix_location_(-1),
      quad_location_(-1),
      vertex_tex_transform_location_(-1) {
}

void VertexShaderTile::Init(GLES2Interface* context,
                            unsigned program,
                            int* base_uniform_index) {
  static const char* uniforms[] = {
      "matrix", "quad", "vertexTexTransform",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  matrix_location_ = locations[0];
  quad_location_ = locations[1];
  vertex_tex_transform_location_ = locations[2];
}

std::string VertexShaderTile::GetShaderString() const {
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      attribute TexCoordPrecision vec4 a_position;
      attribute TexCoordPrecision vec2 a_texCoord;
      attribute float a_index;
      uniform mat4 matrix;
      uniform TexCoordPrecision vec2 quad[4];
      uniform TexCoordPrecision vec4 vertexTexTransform;
      varying TexCoordPrecision vec2 v_texCoord;
      void main() {
        vec2 pos = quad[int(a_index)];  // NOLINT
        gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
        v_texCoord = a_texCoord * vertexTexTransform.zw + vertexTexTransform.xy;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

VertexShaderTileAA::VertexShaderTileAA()
    : matrix_location_(-1),
      viewport_location_(-1),
      quad_location_(-1),
      edge_location_(-1),
      vertex_tex_transform_location_(-1) {
}

void VertexShaderTileAA::Init(GLES2Interface* context,
                              unsigned program,
                              int* base_uniform_index) {
  static const char* uniforms[] = {
      "matrix", "viewport", "quad", "edge", "vertexTexTransform",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  matrix_location_ = locations[0];
  viewport_location_ = locations[1];
  quad_location_ = locations[2];
  edge_location_ = locations[3];
  vertex_tex_transform_location_ = locations[4];
}

std::string VertexShaderTileAA::GetShaderString() const {
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      attribute TexCoordPrecision vec4 a_position;
      attribute float a_index;
      uniform mat4 matrix;
      uniform vec4 viewport;
      uniform TexCoordPrecision vec2 quad[4];
      uniform TexCoordPrecision vec3 edge[8];
      uniform TexCoordPrecision vec4 vertexTexTransform;
      varying TexCoordPrecision vec2 v_texCoord;
      varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.

      void main() {
        vec2 pos = quad[int(a_index)];  // NOLINT
        gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
        vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
        vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
        edge_dist[0] = vec4(dot(edge[0], screen_pos),
                            dot(edge[1], screen_pos),
                            dot(edge[2], screen_pos),
                            dot(edge[3], screen_pos)) *
                       gl_Position.w;
        edge_dist[1] = vec4(dot(edge[4], screen_pos),
                            dot(edge[5], screen_pos),
                            dot(edge[6], screen_pos),
                            dot(edge[7], screen_pos)) *
                       gl_Position.w;
        v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

VertexShaderVideoTransform::VertexShaderVideoTransform()
    : matrix_location_(-1), tex_matrix_location_(-1) {
}

void VertexShaderVideoTransform::Init(GLES2Interface* context,
                                      unsigned program,
                                      int* base_uniform_index) {
  static const char* uniforms[] = {
      "matrix", "texMatrix",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  matrix_location_ = locations[0];
  tex_matrix_location_ = locations[1];
}

std::string VertexShaderVideoTransform::GetShaderString() const {
  // clang-format off
  return VERTEX_SHADER(
      // clang-format on
      attribute vec4 a_position;
      attribute TexCoordPrecision vec2 a_texCoord;
      uniform mat4 matrix;
      uniform TexCoordPrecision mat4 texMatrix;
      varying TexCoordPrecision vec2 v_texCoord;
      void main() {
        gl_Position = matrix * a_position;
        v_texCoord =
            vec2(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0));
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

#define BLEND_MODE_UNIFORMS "s_backdropTexture", "backdropRect"
#define UNUSED_BLEND_MODE_UNIFORMS (!has_blend_mode() ? 2 : 0)
#define BLEND_MODE_SET_LOCATIONS(X, POS)                   \
  if (has_blend_mode()) {                                  \
    DCHECK_LT(static_cast<size_t>(POS) + 1, arraysize(X)); \
    backdrop_location_ = locations[POS];                   \
    backdrop_rect_location_ = locations[POS + 1];          \
  }

FragmentTexBlendMode::FragmentTexBlendMode()
    : backdrop_location_(-1),
      backdrop_rect_location_(-1),
      blend_mode_(BlendModeNone) {
}

std::string FragmentTexBlendMode::SetBlendModeFunctions(
    std::string shader_string) const {
  if (shader_string.find("ApplyBlendMode") == std::string::npos)
    return shader_string;

  if (!has_blend_mode()) {
    return "#define ApplyBlendMode(X) (X)\n" + shader_string;
  }

  // clang-format off
  static const std::string kFunctionApplyBlendMode = SHADER0(
      // clang-format on
      uniform sampler2D s_backdropTexture;
      uniform TexCoordPrecision vec4 backdropRect;

      vec4 GetBackdropColor() {
        TexCoordPrecision vec2 bgTexCoord = gl_FragCoord.xy - backdropRect.xy;
        bgTexCoord.x /= backdropRect.z;
        bgTexCoord.y /= backdropRect.w;
        return texture2D(s_backdropTexture, bgTexCoord);
      }

      vec4 ApplyBlendMode(vec4 src) {
        vec4 dst = GetBackdropColor();
        return Blend(src, dst);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on

  return "precision mediump float;" + GetHelperFunctions() +
         GetBlendFunction() + kFunctionApplyBlendMode + shader_string;
}

std::string FragmentTexBlendMode::GetHelperFunctions() const {
  // clang-format off
  static const std::string kFunctionHardLight = SHADER0(
      // clang-format on
      vec3 hardLight(vec4 src, vec4 dst) {
        vec3 result;
        result.r =
            (2.0 * src.r <= src.a)
                ? (2.0 * src.r * dst.r)
                : (src.a * dst.a - 2.0 * (dst.a - dst.r) * (src.a - src.r));
        result.g =
            (2.0 * src.g <= src.a)
                ? (2.0 * src.g * dst.g)
                : (src.a * dst.a - 2.0 * (dst.a - dst.g) * (src.a - src.g));
        result.b =
            (2.0 * src.b <= src.a)
                ? (2.0 * src.b * dst.b)
                : (src.a * dst.a - 2.0 * (dst.a - dst.b) * (src.a - src.b));
        result.rgb += src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
        return result;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)

  static const std::string kFunctionColorDodgeComponent = SHADER0(
      // clang-format on
      float getColorDodgeComponent(
          float srcc, float srca, float dstc, float dsta) {
        if (0.0 == dstc)
          return srcc * (1.0 - dsta);
        float d = srca - srcc;
        if (0.0 == d)
          return srca * dsta + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
        d = min(dsta, dstc * srca / d);
        return d * srca + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)

  static const std::string kFunctionColorBurnComponent = SHADER0(
      // clang-format on
      float getColorBurnComponent(
          float srcc, float srca, float dstc, float dsta) {
        if (dsta == dstc)
          return srca * dsta + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
        if (0.0 == srcc)
          return dstc * (1.0 - srca);
        float d = max(0.0, dsta - (dsta - dstc) * srca / srcc);
        return srca * d + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)

  static const std::string kFunctionSoftLightComponentPosDstAlpha = SHADER0(
      // clang-format on
      float getSoftLightComponent(
          float srcc, float srca, float dstc, float dsta) {
        if (2.0 * srcc <= srca) {
          return (dstc * dstc * (srca - 2.0 * srcc)) / dsta +
                 (1.0 - dsta) * srcc + dstc * (-srca + 2.0 * srcc + 1.0);
        } else if (4.0 * dstc <= dsta) {
          float DSqd = dstc * dstc;
          float DCub = DSqd * dstc;
          float DaSqd = dsta * dsta;
          float DaCub = DaSqd * dsta;
          return (-DaCub * srcc +
                  DaSqd * (srcc - dstc * (3.0 * srca - 6.0 * srcc - 1.0)) +
                  12.0 * dsta * DSqd * (srca - 2.0 * srcc) -
                  16.0 * DCub * (srca - 2.0 * srcc)) /
                 DaSqd;
        } else {
          return -sqrt(dsta * dstc) * (srca - 2.0 * srcc) - dsta * srcc +
                 dstc * (srca - 2.0 * srcc + 1.0) + srcc;
        }
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)

  static const std::string kFunctionLum = SHADER0(
      // clang-format on
      float luminance(vec3 color) { return dot(vec3(0.3, 0.59, 0.11), color); }

      vec3 set_luminance(vec3 hueSat, float alpha, vec3 lumColor) {
        float diff = luminance(lumColor - hueSat);
        vec3 outColor = hueSat + diff;
        float outLum = luminance(outColor);
        float minComp = min(min(outColor.r, outColor.g), outColor.b);
        float maxComp = max(max(outColor.r, outColor.g), outColor.b);
        if (minComp < 0.0 && outLum != minComp) {
          outColor = outLum +
                     ((outColor - vec3(outLum, outLum, outLum)) * outLum) /
                         (outLum - minComp);
        }
        if (maxComp > alpha && maxComp != outLum) {
          outColor =
              outLum +
              ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) /
                  (maxComp - outLum);
        }
        return outColor;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)

  static const std::string kFunctionSat = SHADER0(
      // clang-format on
      float saturation(vec3 color) {
        return max(max(color.r, color.g), color.b) -
               min(min(color.r, color.g), color.b);
      }

      vec3 set_saturation_helper(
          float minComp, float midComp, float maxComp, float sat) {
        if (minComp < maxComp) {
          vec3 result;
          result.r = 0.0;
          result.g = sat * (midComp - minComp) / (maxComp - minComp);
          result.b = sat;
          return result;
        } else {
          return vec3(0, 0, 0);
        }
      }

      vec3 set_saturation(vec3 hueLumColor, vec3 satColor) {
        float sat = saturation(satColor);
        if (hueLumColor.r <= hueLumColor.g) {
          if (hueLumColor.g <= hueLumColor.b) {
            hueLumColor.rgb = set_saturation_helper(
                hueLumColor.r, hueLumColor.g, hueLumColor.b, sat);
          } else if (hueLumColor.r <= hueLumColor.b) {
            hueLumColor.rbg = set_saturation_helper(
                hueLumColor.r, hueLumColor.b, hueLumColor.g, sat);
          } else {
            hueLumColor.brg = set_saturation_helper(
                hueLumColor.b, hueLumColor.r, hueLumColor.g, sat);
          }
        } else if (hueLumColor.r <= hueLumColor.b) {
          hueLumColor.grb = set_saturation_helper(
              hueLumColor.g, hueLumColor.r, hueLumColor.b, sat);
        } else if (hueLumColor.g <= hueLumColor.b) {
          hueLumColor.gbr = set_saturation_helper(
              hueLumColor.g, hueLumColor.b, hueLumColor.r, sat);
        } else {
          hueLumColor.bgr = set_saturation_helper(
              hueLumColor.b, hueLumColor.g, hueLumColor.r, sat);
        }
        return hueLumColor;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on

  switch (blend_mode_) {
    case BlendModeOverlay:
    case BlendModeHardLight:
      return kFunctionHardLight;
    case BlendModeColorDodge:
      return kFunctionColorDodgeComponent;
    case BlendModeColorBurn:
      return kFunctionColorBurnComponent;
    case BlendModeSoftLight:
      return kFunctionSoftLightComponentPosDstAlpha;
    case BlendModeHue:
    case BlendModeSaturation:
      return kFunctionLum + kFunctionSat;
    case BlendModeColor:
    case BlendModeLuminosity:
      return kFunctionLum;
    default:
      return std::string();
  }
}

std::string FragmentTexBlendMode::GetBlendFunction() const {
  return "vec4 Blend(vec4 src, vec4 dst) {"
         "    vec4 result;"
         "    result.a = src.a + (1.0 - src.a) * dst.a;" +
         GetBlendFunctionBodyForRGB() +
         "    return result;"
         "}";
}

std::string FragmentTexBlendMode::GetBlendFunctionBodyForRGB() const {
  switch (blend_mode_) {
    case BlendModeNormal:
      return "result.rgb = src.rgb + dst.rgb * (1.0 - src.a);";
    case BlendModeScreen:
      return "result.rgb = src.rgb + (1.0 - src.rgb) * dst.rgb;";
    case BlendModeLighten:
      return "result.rgb = max((1.0 - src.a) * dst.rgb + src.rgb,"
             "                 (1.0 - dst.a) * src.rgb + dst.rgb);";
    case BlendModeOverlay:
      return "result.rgb = hardLight(dst, src);";
    case BlendModeDarken:
      return "result.rgb = min((1.0 - src.a) * dst.rgb + src.rgb,"
             "                 (1.0 - dst.a) * src.rgb + dst.rgb);";
    case BlendModeColorDodge:
      return "result.r = getColorDodgeComponent(src.r, src.a, dst.r, dst.a);"
             "result.g = getColorDodgeComponent(src.g, src.a, dst.g, dst.a);"
             "result.b = getColorDodgeComponent(src.b, src.a, dst.b, dst.a);";
    case BlendModeColorBurn:
      return "result.r = getColorBurnComponent(src.r, src.a, dst.r, dst.a);"
             "result.g = getColorBurnComponent(src.g, src.a, dst.g, dst.a);"
             "result.b = getColorBurnComponent(src.b, src.a, dst.b, dst.a);";
    case BlendModeHardLight:
      return "result.rgb = hardLight(src, dst);";
    case BlendModeSoftLight:
      return "if (0.0 == dst.a) {"
             "  result.rgb = src.rgb;"
             "} else {"
             "  result.r = getSoftLightComponent(src.r, src.a, dst.r, dst.a);"
             "  result.g = getSoftLightComponent(src.g, src.a, dst.g, dst.a);"
             "  result.b = getSoftLightComponent(src.b, src.a, dst.b, dst.a);"
             "}";
    case BlendModeDifference:
      return "result.rgb = src.rgb + dst.rgb -"
             "    2.0 * min(src.rgb * dst.a, dst.rgb * src.a);";
    case BlendModeExclusion:
      return "result.rgb = dst.rgb + src.rgb - 2.0 * dst.rgb * src.rgb;";
    case BlendModeMultiply:
      return "result.rgb = (1.0 - src.a) * dst.rgb +"
             "    (1.0 - dst.a) * src.rgb + src.rgb * dst.rgb;";
    case BlendModeHue:
      return "vec4 dstSrcAlpha = dst * src.a;"
             "result.rgb ="
             "    set_luminance(set_saturation(src.rgb * dst.a,"
             "                                 dstSrcAlpha.rgb),"
             "                  dstSrcAlpha.a,"
             "                  dstSrcAlpha.rgb);"
             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
    case BlendModeSaturation:
      return "vec4 dstSrcAlpha = dst * src.a;"
             "result.rgb = set_luminance(set_saturation(dstSrcAlpha.rgb,"
             "                                          src.rgb * dst.a),"
             "                           dstSrcAlpha.a,"
             "                           dstSrcAlpha.rgb);"
             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
    case BlendModeColor:
      return "vec4 srcDstAlpha = src * dst.a;"
             "result.rgb = set_luminance(srcDstAlpha.rgb,"
             "                           srcDstAlpha.a,"
             "                           dst.rgb * src.a);"
             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
    case BlendModeLuminosity:
      return "vec4 srcDstAlpha = src * dst.a;"
             "result.rgb = set_luminance(dst.rgb * src.a,"
             "                           srcDstAlpha.a,"
             "                           srcDstAlpha.rgb);"
             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
    case BlendModeNone:
    case NumBlendModes:
      NOTREACHED();
  }
  return "result = vec4(1.0, 0.0, 0.0, 1.0);";
}

FragmentTexAlphaBinding::FragmentTexAlphaBinding()
    : sampler_location_(-1), alpha_location_(-1) {
}

void FragmentTexAlphaBinding::Init(GLES2Interface* context,
                                   unsigned program,
                                   int* base_uniform_index) {
  static const char* uniforms[] = {
      "s_texture", "alpha", BLEND_MODE_UNIFORMS,
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                             uniforms,
                             locations,
                             base_uniform_index);
  sampler_location_ = locations[0];
  alpha_location_ = locations[1];
  BLEND_MODE_SET_LOCATIONS(locations, 2);
}

FragmentTexColorMatrixAlphaBinding::FragmentTexColorMatrixAlphaBinding()
    : sampler_location_(-1),
      alpha_location_(-1),
      color_matrix_location_(-1),
      color_offset_location_(-1) {
}

void FragmentTexColorMatrixAlphaBinding::Init(GLES2Interface* context,
                                              unsigned program,
                                              int* base_uniform_index) {
  static const char* uniforms[] = {
      "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS,
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                             uniforms,
                             locations,
                             base_uniform_index);
  sampler_location_ = locations[0];
  alpha_location_ = locations[1];
  color_matrix_location_ = locations[2];
  color_offset_location_ = locations[3];
  BLEND_MODE_SET_LOCATIONS(locations, 4);
}

FragmentTexOpaqueBinding::FragmentTexOpaqueBinding() : sampler_location_(-1) {
}

void FragmentTexOpaqueBinding::Init(GLES2Interface* context,
                                    unsigned program,
                                    int* base_uniform_index) {
  static const char* uniforms[] = {
      "s_texture",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  sampler_location_ = locations[0];
}

std::string FragmentShaderRGBATexAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      uniform SamplerType s_texture;
      uniform float alpha;
      void main() {
        vec4 texColor = TextureLookup(s_texture, v_texCoord);
        gl_FragColor = ApplyBlendMode(texColor * alpha);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      uniform SamplerType s_texture;
      uniform float alpha;
      uniform mat4 colorMatrix;
      uniform vec4 colorOffset;
      void main() {
        vec4 texColor = TextureLookup(s_texture, v_texCoord);
        float nonZeroAlpha = max(texColor.a, 0.00001);
        texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
        texColor = colorMatrix * texColor + colorOffset;
        texColor.rgb *= texColor.a;
        texColor = clamp(texColor, 0.0, 1.0);
        gl_FragColor = ApplyBlendMode(texColor * alpha);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      varying float v_alpha;
      uniform SamplerType s_texture;
      void main() {
        vec4 texColor = TextureLookup(s_texture, v_texCoord);
        gl_FragColor = texColor * v_alpha;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      varying float v_alpha;
      uniform SamplerType s_texture;
      void main() {
        vec4 texColor = TextureLookup(s_texture, v_texCoord);
        texColor.rgb *= texColor.a;
        gl_FragColor = texColor * v_alpha;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentTexBackgroundBinding::FragmentTexBackgroundBinding()
    : background_color_location_(-1), sampler_location_(-1) {
}

void FragmentTexBackgroundBinding::Init(GLES2Interface* context,
                                        unsigned program,
                                        int* base_uniform_index) {
  static const char* uniforms[] = {
      "s_texture", "background_color",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);

  sampler_location_ = locations[0];
  DCHECK_NE(sampler_location_, -1);

  background_color_location_ = locations[1];
  DCHECK_NE(background_color_location_, -1);
}

std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      varying float v_alpha;
      uniform vec4 background_color;
      uniform SamplerType s_texture;
      void main() {
        vec4 texColor = TextureLookup(s_texture, v_texCoord);
        texColor += background_color * (1.0 - texColor.a);
        gl_FragColor = texColor * v_alpha;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      varying float v_alpha;
      uniform vec4 background_color;
      uniform SamplerType s_texture;
      void main() {
        vec4 texColor = TextureLookup(s_texture, v_texCoord);
        texColor.rgb *= texColor.a;
        texColor += background_color * (1.0 - texColor.a);
        gl_FragColor = texColor * v_alpha;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

std::string FragmentShaderRGBATexOpaque::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      uniform SamplerType s_texture;
      void main() {
        vec4 texColor = TextureLookup(s_texture, v_texCoord);
        gl_FragColor = vec4(texColor.rgb, 1.0);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

std::string FragmentShaderRGBATex::GetShaderString(TexCoordPrecision precision,
                                                   SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      uniform SamplerType s_texture;
      void main() { gl_FragColor = TextureLookup(s_texture, v_texCoord); }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      uniform SamplerType s_texture;
      uniform float alpha;
      void main() {
        vec4 texColor = TextureLookup(s_texture, v_texCoord);
        gl_FragColor =
            vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      uniform SamplerType s_texture;
      void main() {
        vec4 texColor = TextureLookup(s_texture, v_texCoord);
        gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, 1.0);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentShaderRGBATexAlphaAA::FragmentShaderRGBATexAlphaAA()
    : sampler_location_(-1), alpha_location_(-1) {
}

void FragmentShaderRGBATexAlphaAA::Init(GLES2Interface* context,
                                        unsigned program,
                                        int* base_uniform_index) {
  static const char* uniforms[] = {
      "s_texture", "alpha", BLEND_MODE_UNIFORMS,
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                             uniforms,
                             locations,
                             base_uniform_index);
  sampler_location_ = locations[0];
  alpha_location_ = locations[1];
  BLEND_MODE_SET_LOCATIONS(locations, 2);
}

std::string FragmentShaderRGBATexAlphaAA::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      uniform SamplerType s_texture;
      uniform float alpha;
      varying TexCoordPrecision vec2 v_texCoord;
      varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.

      void main() {
        vec4 texColor = TextureLookup(s_texture, v_texCoord);
        vec4 d4 = min(edge_dist[0], edge_dist[1]);
        vec2 d2 = min(d4.xz, d4.yw);
        float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
        gl_FragColor = ApplyBlendMode(texColor * alpha * aa);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentTexClampAlphaAABinding::FragmentTexClampAlphaAABinding()
    : sampler_location_(-1),
      alpha_location_(-1),
      fragment_tex_transform_location_(-1) {
}

void FragmentTexClampAlphaAABinding::Init(GLES2Interface* context,
                                          unsigned program,
                                          int* base_uniform_index) {
  static const char* uniforms[] = {
      "s_texture", "alpha", "fragmentTexTransform",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  sampler_location_ = locations[0];
  alpha_location_ = locations[1];
  fragment_tex_transform_location_ = locations[2];
}

std::string FragmentShaderRGBATexClampAlphaAA::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      uniform SamplerType s_texture;
      uniform float alpha;
      uniform TexCoordPrecision vec4 fragmentTexTransform;
      varying TexCoordPrecision vec2 v_texCoord;
      varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.

      void main() {
        TexCoordPrecision vec2 texCoord =
            clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
            fragmentTexTransform.xy;
        vec4 texColor = TextureLookup(s_texture, texCoord);
        vec4 d4 = min(edge_dist[0], edge_dist[1]);
        vec2 d2 = min(d4.xz, d4.yw);
        float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
        gl_FragColor = texColor * alpha * aa;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      uniform SamplerType s_texture;
      uniform float alpha;
      uniform TexCoordPrecision vec4 fragmentTexTransform;
      varying TexCoordPrecision vec2 v_texCoord;
      varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.

      void main() {
        TexCoordPrecision vec2 texCoord =
            clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
            fragmentTexTransform.xy;
        vec4 texColor = TextureLookup(s_texture, texCoord);
        vec4 d4 = min(edge_dist[0], edge_dist[1]);
        vec2 d2 = min(d4.xz, d4.yw);
        float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
        gl_FragColor =
            vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha * aa;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask()
    : sampler_location_(-1),
      mask_sampler_location_(-1),
      alpha_location_(-1),
      mask_tex_coord_scale_location_(-1) {
}

void FragmentShaderRGBATexAlphaMask::Init(GLES2Interface* context,
                                          unsigned program,
                                          int* base_uniform_index) {
  static const char* uniforms[] = {
      "s_texture",
      "s_mask",
      "alpha",
      "maskTexCoordScale",
      "maskTexCoordOffset",
      BLEND_MODE_UNIFORMS,
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                             uniforms,
                             locations,
                             base_uniform_index);
  sampler_location_ = locations[0];
  mask_sampler_location_ = locations[1];
  alpha_location_ = locations[2];
  mask_tex_coord_scale_location_ = locations[3];
  mask_tex_coord_offset_location_ = locations[4];
  BLEND_MODE_SET_LOCATIONS(locations, 5);
}

std::string FragmentShaderRGBATexAlphaMask::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      uniform sampler2D s_texture;
      uniform SamplerType s_mask;
      uniform TexCoordPrecision vec2 maskTexCoordScale;
      uniform TexCoordPrecision vec2 maskTexCoordOffset;
      uniform float alpha;
      void main() {
        vec4 texColor = texture2D(s_texture, v_texCoord);
        TexCoordPrecision vec2 maskTexCoord =
            vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
                 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
        vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
        gl_FragColor = ApplyBlendMode(texColor * alpha * maskColor.w);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentShaderRGBATexAlphaMaskAA::FragmentShaderRGBATexAlphaMaskAA()
    : sampler_location_(-1),
      mask_sampler_location_(-1),
      alpha_location_(-1),
      mask_tex_coord_scale_location_(-1),
      mask_tex_coord_offset_location_(-1) {
}

void FragmentShaderRGBATexAlphaMaskAA::Init(GLES2Interface* context,
                                            unsigned program,
                                            int* base_uniform_index) {
  static const char* uniforms[] = {
      "s_texture",
      "s_mask",
      "alpha",
      "maskTexCoordScale",
      "maskTexCoordOffset",
      BLEND_MODE_UNIFORMS,
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                             uniforms,
                             locations,
                             base_uniform_index);
  sampler_location_ = locations[0];
  mask_sampler_location_ = locations[1];
  alpha_location_ = locations[2];
  mask_tex_coord_scale_location_ = locations[3];
  mask_tex_coord_offset_location_ = locations[4];
  BLEND_MODE_SET_LOCATIONS(locations, 5);
}

std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      uniform sampler2D s_texture;
      uniform SamplerType s_mask;
      uniform TexCoordPrecision vec2 maskTexCoordScale;
      uniform TexCoordPrecision vec2 maskTexCoordOffset;
      uniform float alpha;
      varying TexCoordPrecision vec2 v_texCoord;
      varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.

      void main() {
        vec4 texColor = texture2D(s_texture, v_texCoord);
        TexCoordPrecision vec2 maskTexCoord =
            vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
                 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
        vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
        vec4 d4 = min(edge_dist[0], edge_dist[1]);
        vec2 d2 = min(d4.xz, d4.yw);
        float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
        gl_FragColor = ApplyBlendMode(texColor * alpha * maskColor.w * aa);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentShaderRGBATexAlphaMaskColorMatrixAA::
    FragmentShaderRGBATexAlphaMaskColorMatrixAA()
    : sampler_location_(-1),
      mask_sampler_location_(-1),
      alpha_location_(-1),
      mask_tex_coord_scale_location_(-1),
      color_matrix_location_(-1),
      color_offset_location_(-1) {
}

void FragmentShaderRGBATexAlphaMaskColorMatrixAA::Init(
    GLES2Interface* context,
    unsigned program,
    int* base_uniform_index) {
  static const char* uniforms[] = {
      "s_texture",
      "s_mask",
      "alpha",
      "maskTexCoordScale",
      "maskTexCoordOffset",
      "colorMatrix",
      "colorOffset",
      BLEND_MODE_UNIFORMS,
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                             uniforms,
                             locations,
                             base_uniform_index);
  sampler_location_ = locations[0];
  mask_sampler_location_ = locations[1];
  alpha_location_ = locations[2];
  mask_tex_coord_scale_location_ = locations[3];
  mask_tex_coord_offset_location_ = locations[4];
  color_matrix_location_ = locations[5];
  color_offset_location_ = locations[6];
  BLEND_MODE_SET_LOCATIONS(locations, 7);
}

std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      uniform sampler2D s_texture;
      uniform SamplerType s_mask;
      uniform vec2 maskTexCoordScale;
      uniform vec2 maskTexCoordOffset;
      uniform mat4 colorMatrix;
      uniform vec4 colorOffset;
      uniform float alpha;
      varying TexCoordPrecision vec2 v_texCoord;
      varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.

      void main() {
        vec4 texColor = texture2D(s_texture, v_texCoord);
        float nonZeroAlpha = max(texColor.a, 0.00001);
        texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
        texColor = colorMatrix * texColor + colorOffset;
        texColor.rgb *= texColor.a;
        texColor = clamp(texColor, 0.0, 1.0);
        TexCoordPrecision vec2 maskTexCoord =
            vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
                 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
        vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
        vec4 d4 = min(edge_dist[0], edge_dist[1]);
        vec2 d2 = min(d4.xz, d4.yw);
        float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
        gl_FragColor = ApplyBlendMode(texColor * alpha * maskColor.w * aa);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentShaderRGBATexAlphaColorMatrixAA::
    FragmentShaderRGBATexAlphaColorMatrixAA()
    : sampler_location_(-1),
      alpha_location_(-1),
      color_matrix_location_(-1),
      color_offset_location_(-1) {
}

void FragmentShaderRGBATexAlphaColorMatrixAA::Init(GLES2Interface* context,
                                                   unsigned program,
                                                   int* base_uniform_index) {
  static const char* uniforms[] = {
      "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS,
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                             uniforms,
                             locations,
                             base_uniform_index);
  sampler_location_ = locations[0];
  alpha_location_ = locations[1];
  color_matrix_location_ = locations[2];
  color_offset_location_ = locations[3];
  BLEND_MODE_SET_LOCATIONS(locations, 4);
}

std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      uniform SamplerType s_texture;
      uniform float alpha;
      uniform mat4 colorMatrix;
      uniform vec4 colorOffset;
      varying TexCoordPrecision vec2 v_texCoord;
      varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.

      void main() {
        vec4 texColor = TextureLookup(s_texture, v_texCoord);
        float nonZeroAlpha = max(texColor.a, 0.00001);
        texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
        texColor = colorMatrix * texColor + colorOffset;
        texColor.rgb *= texColor.a;
        texColor = clamp(texColor, 0.0, 1.0);
        vec4 d4 = min(edge_dist[0], edge_dist[1]);
        vec2 d2 = min(d4.xz, d4.yw);
        float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
        gl_FragColor = ApplyBlendMode(texColor * alpha * aa);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentShaderRGBATexAlphaMaskColorMatrix::
    FragmentShaderRGBATexAlphaMaskColorMatrix()
    : sampler_location_(-1),
      mask_sampler_location_(-1),
      alpha_location_(-1),
      mask_tex_coord_scale_location_(-1) {
}

void FragmentShaderRGBATexAlphaMaskColorMatrix::Init(GLES2Interface* context,
                                                     unsigned program,
                                                     int* base_uniform_index) {
  static const char* uniforms[] = {
      "s_texture",
      "s_mask",
      "alpha",
      "maskTexCoordScale",
      "maskTexCoordOffset",
      "colorMatrix",
      "colorOffset",
      BLEND_MODE_UNIFORMS,
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                             uniforms,
                             locations,
                             base_uniform_index);
  sampler_location_ = locations[0];
  mask_sampler_location_ = locations[1];
  alpha_location_ = locations[2];
  mask_tex_coord_scale_location_ = locations[3];
  mask_tex_coord_offset_location_ = locations[4];
  color_matrix_location_ = locations[5];
  color_offset_location_ = locations[6];
  BLEND_MODE_SET_LOCATIONS(locations, 7);
}

std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      varying TexCoordPrecision vec2 v_texCoord;
      uniform sampler2D s_texture;
      uniform SamplerType s_mask;
      uniform vec2 maskTexCoordScale;
      uniform vec2 maskTexCoordOffset;
      uniform mat4 colorMatrix;
      uniform vec4 colorOffset;
      uniform float alpha;
      void main() {
        vec4 texColor = texture2D(s_texture, v_texCoord);
        float nonZeroAlpha = max(texColor.a, 0.00001);
        texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
        texColor = colorMatrix * texColor + colorOffset;
        texColor.rgb *= texColor.a;
        texColor = clamp(texColor, 0.0, 1.0);
        TexCoordPrecision vec2 maskTexCoord =
            vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
                 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
        vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
        gl_FragColor = ApplyBlendMode(texColor * alpha * maskColor.w);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentShaderYUVVideo::FragmentShaderYUVVideo()
    : y_texture_location_(-1),
      u_texture_location_(-1),
      v_texture_location_(-1),
      alpha_location_(-1),
      yuv_matrix_location_(-1),
      yuv_adj_location_(-1),
      clamp_rect_location_(-1) {
}

void FragmentShaderYUVVideo::Init(GLES2Interface* context,
                                  unsigned program,
                                  int* base_uniform_index) {
  static const char* uniforms[] = {"y_texture",
                                   "u_texture",
                                   "v_texture",
                                   "alpha",
                                   "yuv_matrix",
                                   "yuv_adj",
                                   "clamp_rect"};
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  y_texture_location_ = locations[0];
  u_texture_location_ = locations[1];
  v_texture_location_ = locations[2];
  alpha_location_ = locations[3];
  yuv_matrix_location_ = locations[4];
  yuv_adj_location_ = locations[5];
  clamp_rect_location_ = locations[6];
}

std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision,
                                                    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      precision mediump int;
      varying TexCoordPrecision vec2 v_texCoord;
      uniform SamplerType y_texture;
      uniform SamplerType u_texture;
      uniform SamplerType v_texture;
      uniform float alpha;
      uniform vec3 yuv_adj;
      uniform mat3 yuv_matrix;
      uniform vec4 clamp_rect;
      void main() {
        vec2 clamped = max(clamp_rect.xy, min(clamp_rect.zw, v_texCoord));
        float y_raw = TextureLookup(y_texture, clamped).x;
        float u_unsigned = TextureLookup(u_texture, clamped).x;
        float v_unsigned = TextureLookup(v_texture, clamped).x;
        vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
        vec3 rgb = yuv_matrix * yuv;
        gl_FragColor = vec4(rgb, 1.0) * alpha;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentShaderYUVAVideo::FragmentShaderYUVAVideo()
    : y_texture_location_(-1),
      u_texture_location_(-1),
      v_texture_location_(-1),
      a_texture_location_(-1),
      alpha_location_(-1),
      yuv_matrix_location_(-1),
      yuv_adj_location_(-1) {
}

void FragmentShaderYUVAVideo::Init(GLES2Interface* context,
                                   unsigned program,
                                   int* base_uniform_index) {
  static const char* uniforms[] = {
      "y_texture",
      "u_texture",
      "v_texture",
      "a_texture",
      "alpha",
      "cc_matrix",
      "yuv_adj",
      "clamp_rect",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  y_texture_location_ = locations[0];
  u_texture_location_ = locations[1];
  v_texture_location_ = locations[2];
  a_texture_location_ = locations[3];
  alpha_location_ = locations[4];
  yuv_matrix_location_ = locations[5];
  yuv_adj_location_ = locations[6];
  clamp_rect_location_ = locations[7];
}

std::string FragmentShaderYUVAVideo::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      precision mediump int;
      varying TexCoordPrecision vec2 v_texCoord;
      uniform SamplerType y_texture;
      uniform SamplerType u_texture;
      uniform SamplerType v_texture;
      uniform SamplerType a_texture;
      uniform float alpha;
      uniform vec3 yuv_adj;
      uniform mat3 yuv_matrix;
      uniform vec4 clamp_rect;
      void main() {
        vec2 clamped = max(clamp_rect.xy, min(clamp_rect.zw, v_texCoord));
        float y_raw = TextureLookup(y_texture, clamped).x;
        float u_unsigned = TextureLookup(u_texture, clamped).x;
        float v_unsigned = TextureLookup(v_texture, clamped).x;
        float a_raw = TextureLookup(a_texture, clamped).x;
        vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
        vec3 rgb = yuv_matrix * yuv;
        gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentShaderColor::FragmentShaderColor() : color_location_(-1) {
}

void FragmentShaderColor::Init(GLES2Interface* context,
                               unsigned program,
                               int* base_uniform_index) {
  static const char* uniforms[] = {
      "color",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  color_location_ = locations[0];
}

std::string FragmentShaderColor::GetShaderString(TexCoordPrecision precision,
                                                 SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      uniform vec4 color;
      void main() { gl_FragColor = color; }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentShaderColorAA::FragmentShaderColorAA() : color_location_(-1) {
}

void FragmentShaderColorAA::Init(GLES2Interface* context,
                                 unsigned program,
                                 int* base_uniform_index) {
  static const char* uniforms[] = {
      "color",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  color_location_ = locations[0];
}

std::string FragmentShaderColorAA::GetShaderString(TexCoordPrecision precision,
                                                   SamplerType sampler) const {
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      uniform vec4 color;
      varying vec4 edge_dist[2];  // 8 edge distances.

      void main() {
        vec4 d4 = min(edge_dist[0], edge_dist[1]);
        vec2 d2 = min(d4.xz, d4.yw);
        float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
        gl_FragColor = color * aa;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

FragmentShaderCheckerboard::FragmentShaderCheckerboard()
    : alpha_location_(-1),
      tex_transform_location_(-1),
      frequency_location_(-1) {
}

void FragmentShaderCheckerboard::Init(GLES2Interface* context,
                                      unsigned program,
                                      int* base_uniform_index) {
  static const char* uniforms[] = {
      "alpha", "texTransform", "frequency", "color",
  };
  int locations[arraysize(uniforms)];

  GetProgramUniformLocations(context,
                             program,
                             arraysize(uniforms),
                             uniforms,
                             locations,
                             base_uniform_index);
  alpha_location_ = locations[0];
  tex_transform_location_ = locations[1];
  frequency_location_ = locations[2];
  color_location_ = locations[3];
}

std::string FragmentShaderCheckerboard::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  // Shader based on Example 13-17 of "OpenGL ES 2.0 Programming Guide"
  // by Munshi, Ginsburg, Shreiner.
  // clang-format off
  return FRAGMENT_SHADER(
      // clang-format on
      precision mediump float;
      precision mediump int;
      varying vec2 v_texCoord;
      uniform float alpha;
      uniform float frequency;
      uniform vec4 texTransform;
      uniform vec4 color;
      void main() {
        vec4 color1 = vec4(1.0, 1.0, 1.0, 1.0);
        vec4 color2 = color;
        vec2 texCoord =
            clamp(v_texCoord, 0.0, 1.0) * texTransform.zw + texTransform.xy;
        vec2 coord = mod(floor(texCoord * frequency * 2.0), 2.0);
        float picker = abs(coord.x - coord.y);  // NOLINT
        gl_FragColor = mix(color1, color2, picker) * alpha;
      }
      // clang-format off
  );  // NOLINT(whitespace/parens)
  // clang-format on
}

}  // namespace cc
