// 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"

template <size_t size>
std::string StripLambda(const char(&shader)[size]) {
  // Must contain at least "[]() {}" and trailing null (included in size).
  static_assert(size >= 8,
                "String passed to StripLambda must be at least 8 characters");
  DCHECK_EQ(strncmp("[]() {", shader, 6), 0);
  DCHECK_EQ(shader[size - 2], '}');
  return std::string(shader + 6, shader + size - 2);
}

// Shaders are passed in with lambda syntax, which tricks clang-format into
// handling them correctly. StipLambda removes this.
#define SHADER0(Src) StripLambda(#Src)
#define VERTEX_SHADER(Head, Body) SetVertexTexCoordPrecision(Head + Body)
#define FRAGMENT_SHADER(Head, Body) \
  SetFragmentTexCoordPrecision(     \
      precision,                    \
      SetFragmentSamplerType(sampler, SetBlendModeFunctions(Head + Body)))

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 TEX_COORD_PRECISION_HIGH:
      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 TEX_COORD_PRECISION_MEDIUM:
      DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
      return "#define TexCoordPrecision mediump\n" + shader_string;
    case TEX_COORD_PRECISION_NA:
      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 std::string& 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" + 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 TEX_COORD_PRECISION_HIGH;
  return TEX_COORD_PRECISION_MEDIUM;
}

static std::string SetFragmentSamplerType(SamplerType requested_type,
                                          std::string shader_string) {
  switch (requested_type) {
    case SAMPLER_TYPE_2D:
      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 SAMPLER_TYPE_2D_RECT:
      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 SAMPLER_TYPE_EXTERNAL_OES:
      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 SAMPLER_TYPE_NA:
      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 {
  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
}

std::string VertexShaderPosTex::GetShaderHead() {
  return SHADER0([]() {
    attribute vec4 a_position;
    attribute TexCoordPrecision vec2 a_texCoord;
    uniform mat4 matrix;
    varying TexCoordPrecision vec2 v_texCoord;
  });
}

std::string VertexShaderPosTex::GetShaderBody() {
  return SHADER0([]() {
    void main() {
      gl_Position = matrix * a_position;
      v_texCoord = a_texCoord;
    }
  });
}

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 {
  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
}

std::string VertexShaderPosTexYUVStretchOffset::GetShaderHead() {
  return SHADER0([]() {
    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;
  });
}

std::string VertexShaderPosTexYUVStretchOffset::GetShaderBody() {
  return SHADER0([]() {
    void main() {
      gl_Position = matrix * a_position;
      v_texCoord = a_texCoord * texScale + texOffset;
    }
  });
}

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 {
  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
}

std::string VertexShaderPos::GetShaderHead() {
  return SHADER0([]() {
    attribute vec4 a_position;
    uniform mat4 matrix;
  });
}

std::string VertexShaderPos::GetShaderBody() {
  return SHADER0([]() {
    void main() { gl_Position = matrix * a_position; }
  });
}

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 {
  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
}

std::string VertexShaderPosTexTransform::GetShaderHead() {
  return SHADER0([]() {
    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;
  });
}

std::string VertexShaderPosTexTransform::GetShaderBody() {
  return SHADER0([]() {
    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
    }
  });
}

std::string VertexShaderPosTexIdentity::GetShaderString() const {
  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
}

std::string VertexShaderPosTexIdentity::GetShaderHead() {
  return SHADER0([]() {
    attribute vec4 a_position;
    varying TexCoordPrecision vec2 v_texCoord;
  });
}

std::string VertexShaderPosTexIdentity::GetShaderBody() {
  return SHADER0([]() {
    void main() {
      gl_Position = a_position;
      v_texCoord = (a_position.xy + vec2(1.0)) * 0.5;
    }
  });
}

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 {
  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
}

std::string VertexShaderQuad::GetShaderHead() {
#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
  return SHADER0([]() {
    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;
  });
#else
  return SHADER0([]() {
    attribute TexCoordPrecision vec4 a_position;
    attribute float a_index;
    uniform mat4 matrix;
    uniform TexCoordPrecision vec2 quad[4];
  });
#endif
}

std::string VertexShaderQuad::GetShaderBody() {
#if defined(OS_ANDROID)
  return SHADER0([]() {
    void main() {
      vec2 pos = quad[int(a_index)];  // NOLINT
      gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
      dummy_varying = dummy_uniform;
    }
  });
#else
  return SHADER0([]() {
    void main() {
      vec2 pos = quad[int(a_index)];  // NOLINT
      gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
    }
  });
#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 {
  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
}

std::string VertexShaderQuadAA::GetShaderHead() {
  return SHADER0([]() {
    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.
  });
}

std::string VertexShaderQuadAA::GetShaderBody() {
  return SHADER0([]() {
    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;
    }
  });
}

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 {
  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
}

std::string VertexShaderQuadTexTransformAA::GetShaderHead() {
  return SHADER0([]() {
    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.
  });
}

std::string VertexShaderQuadTexTransformAA::GetShaderBody() {
  return SHADER0([]() {
    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;
    }
  });
}

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 {
  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
}

std::string VertexShaderTile::GetShaderHead() {
  return SHADER0([]() {
    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;
  });
}

std::string VertexShaderTile::GetShaderBody() {
  return SHADER0([]() {
    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;
    }
  });
}

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 {
  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
}

std::string VertexShaderTileAA::GetShaderHead() {
  return SHADER0([]() {
    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.
  });
}

std::string VertexShaderTileAA::GetShaderBody() {
  return SHADER0([]() {
    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;
    }
  });
}

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 {
  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
}

std::string VertexShaderVideoTransform::GetShaderHead() {
  return SHADER0([]() {
    attribute vec4 a_position;
    attribute TexCoordPrecision vec2 a_texCoord;
    uniform mat4 matrix;
    uniform TexCoordPrecision mat4 texMatrix;
    varying TexCoordPrecision vec2 v_texCoord;
  });
}

std::string VertexShaderVideoTransform::GetShaderBody() {
  return SHADER0([]() {
    void main() {
      gl_Position = matrix * a_position;
      v_texCoord =
          vec2(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0));
    }
  });
}

#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_(BLEND_MODE_NONE) {
}

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;
  }

  static const std::string kFunctionApplyBlendMode = SHADER0([]() {
    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);
    }
  });

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

std::string FragmentTexBlendMode::GetHelperFunctions() const {
  static const std::string kFunctionHardLight = SHADER0([]() {
    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;
    }
  });

  static const std::string kFunctionColorDodgeComponent = SHADER0([]() {
    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);
    }
  });

  static const std::string kFunctionColorBurnComponent = SHADER0([]() {
    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);
    }
  });

  static const std::string kFunctionSoftLightComponentPosDstAlpha =
      SHADER0([]() {
        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;
          }
        }
      });

  static const std::string kFunctionLum = SHADER0([]() {
    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;
    }
  });

  static const std::string kFunctionSat = SHADER0([]() {
    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;
    }
  });

  switch (blend_mode_) {
    case BLEND_MODE_OVERLAY:
    case BLEND_MODE_HARD_LIGHT:
      return kFunctionHardLight;
    case BLEND_MODE_COLOR_DODGE:
      return kFunctionColorDodgeComponent;
    case BLEND_MODE_COLOR_BURN:
      return kFunctionColorBurnComponent;
    case BLEND_MODE_SOFT_LIGHT:
      return kFunctionSoftLightComponentPosDstAlpha;
    case BLEND_MODE_HUE:
    case BLEND_MODE_SATURATION:
      return kFunctionLum + kFunctionSat;
    case BLEND_MODE_COLOR:
    case BLEND_MODE_LUMINOSITY:
      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 BLEND_MODE_NORMAL:
      return "result.rgb = src.rgb + dst.rgb * (1.0 - src.a);";
    case BLEND_MODE_SCREEN:
      return "result.rgb = src.rgb + (1.0 - src.rgb) * dst.rgb;";
    case BLEND_MODE_LIGHTEN:
      return "result.rgb = max((1.0 - src.a) * dst.rgb + src.rgb,"
             "                 (1.0 - dst.a) * src.rgb + dst.rgb);";
    case BLEND_MODE_OVERLAY:
      return "result.rgb = hardLight(dst, src);";
    case BLEND_MODE_DARKEN:
      return "result.rgb = min((1.0 - src.a) * dst.rgb + src.rgb,"
             "                 (1.0 - dst.a) * src.rgb + dst.rgb);";
    case BLEND_MODE_COLOR_DODGE:
      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 BLEND_MODE_COLOR_BURN:
      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 BLEND_MODE_HARD_LIGHT:
      return "result.rgb = hardLight(src, dst);";
    case BLEND_MODE_SOFT_LIGHT:
      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 BLEND_MODE_DIFFERENCE:
      return "result.rgb = src.rgb + dst.rgb -"
             "    2.0 * min(src.rgb * dst.a, dst.rgb * src.a);";
    case BLEND_MODE_EXCLUSION:
      return "result.rgb = dst.rgb + src.rgb - 2.0 * dst.rgb * src.rgb;";
    case BLEND_MODE_MULTIPLY:
      return "result.rgb = (1.0 - src.a) * dst.rgb +"
             "    (1.0 - dst.a) * src.rgb + src.rgb * dst.rgb;";
    case BLEND_MODE_HUE:
      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 BLEND_MODE_SATURATION:
      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 BLEND_MODE_COLOR:
      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 BLEND_MODE_LUMINOSITY:
      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 BLEND_MODE_NONE:
      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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexAlpha::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    varying TexCoordPrecision vec2 v_texCoord;
    uniform SamplerType s_texture;
    uniform float alpha;
  });
}

std::string FragmentShaderRGBATexAlpha::GetShaderBody() {
  return SHADER0([]() {
    void main() {
      vec4 texColor = TextureLookup(s_texture, v_texCoord);
      gl_FragColor = ApplyBlendMode(texColor * alpha);
    }
  });
}

std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    varying TexCoordPrecision vec2 v_texCoord;
    uniform SamplerType s_texture;
    uniform float alpha;
    uniform mat4 colorMatrix;
    uniform vec4 colorOffset;
  });
}

std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderBody() {
  return SHADER0([]() {
    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);
    }
  });
}

std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexVaryingAlpha::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    varying TexCoordPrecision vec2 v_texCoord;
    varying float v_alpha;
    uniform SamplerType s_texture;
  });
}

std::string FragmentShaderRGBATexVaryingAlpha::GetShaderBody() {
  return SHADER0([]() {
    void main() {
      vec4 texColor = TextureLookup(s_texture, v_texCoord);
      gl_FragColor = texColor * v_alpha;
    }
  });
}

std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    varying TexCoordPrecision vec2 v_texCoord;
    varying float v_alpha;
    uniform SamplerType s_texture;
  });
}

std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderBody() {
  return SHADER0([]() {
    void main() {
      vec4 texColor = TextureLookup(s_texture, v_texCoord);
      texColor.rgb *= texColor.a;
      gl_FragColor = texColor * v_alpha;
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    varying TexCoordPrecision vec2 v_texCoord;
    varying float v_alpha;
    uniform vec4 background_color;
    uniform SamplerType s_texture;
  });
}

std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderBody() {
  return SHADER0([]() {
    void main() {
      vec4 texColor = TextureLookup(s_texture, v_texCoord);
      texColor += background_color * (1.0 - texColor.a);
      gl_FragColor = texColor * v_alpha;
    }
  });
}

std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    varying TexCoordPrecision vec2 v_texCoord;
    varying float v_alpha;
    uniform vec4 background_color;
    uniform SamplerType s_texture;
  });
}

std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderBody() {
  return SHADER0([]() {
    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;
    }
  });
}

std::string FragmentShaderRGBATexOpaque::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexOpaque::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    varying TexCoordPrecision vec2 v_texCoord;
    uniform SamplerType s_texture;
  });
}

std::string FragmentShaderRGBATexOpaque::GetShaderBody() {
  return SHADER0([]() {
    void main() {
      vec4 texColor = TextureLookup(s_texture, v_texCoord);
      gl_FragColor = vec4(texColor.rgb, 1.0);
    }
  });
}

std::string FragmentShaderRGBATex::GetShaderString(TexCoordPrecision precision,
                                                   SamplerType sampler) const {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATex::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    varying TexCoordPrecision vec2 v_texCoord;
    uniform SamplerType s_texture;
  });
}

std::string FragmentShaderRGBATex::GetShaderBody() {
  return SHADER0([]() {
    void main() { gl_FragColor = TextureLookup(s_texture, v_texCoord); }
  });
}

std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    varying TexCoordPrecision vec2 v_texCoord;
    uniform SamplerType s_texture;
    uniform float alpha;
  });
}

std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderBody() {
  return SHADER0([]() {
    void main() {
      vec4 texColor = TextureLookup(s_texture, v_texCoord);
      gl_FragColor =
          vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha;
    }
  });
}

std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    varying TexCoordPrecision vec2 v_texCoord;
    uniform SamplerType s_texture;
  });
}

std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderBody() {
  return SHADER0([]() {
    void main() {
      vec4 texColor = TextureLookup(s_texture, v_texCoord);
      gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, 1.0);
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexAlphaAA::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    uniform SamplerType s_texture;
    uniform float alpha;
    varying TexCoordPrecision vec2 v_texCoord;
    varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
  });
}

std::string FragmentShaderRGBATexAlphaAA::GetShaderBody() {
  return SHADER0([]() {
    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);
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexClampAlphaAA::GetShaderHead() {
  return SHADER0([]() {
    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.
  });
}

std::string FragmentShaderRGBATexClampAlphaAA::GetShaderBody() {
  return SHADER0([]() {
    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;
    }
  });
}

std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderString(
    TexCoordPrecision precision,
    SamplerType sampler) const {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderHead() {
  return SHADER0([]() {
    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.
  });
}

std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderBody() {
  return SHADER0([]() {
    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;
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexAlphaMask::GetShaderHead() {
  return SHADER0([]() {
    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;
  });
}

std::string FragmentShaderRGBATexAlphaMask::GetShaderBody() {
  return SHADER0([]() {
    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);
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderHead() {
  return SHADER0([]() {
    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.
  });
}

std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderBody() {
  return SHADER0([]() {
    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);
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderHead() {
  return SHADER0([]() {
    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.
  });
}

std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderBody() {
  return SHADER0([]() {
    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);
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderHead() {
  return SHADER0([]() {
    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.
  });
}

std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderBody() {
  return SHADER0([]() {
    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);
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderHead() {
  return SHADER0([]() {
    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;
  });
}

std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderBody() {
  return SHADER0([]() {
    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);
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderYUVVideo::GetShaderHead() {
  return SHADER0([]() {
    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;
  });
}

std::string FragmentShaderYUVVideo::GetShaderBody() {
  return SHADER0([]() {
    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;
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderYUVAVideo::GetShaderHead() {
  return SHADER0([]() {
    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;
  });
}

std::string FragmentShaderYUVAVideo::GetShaderBody() {
  return SHADER0([]() {
    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);
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderColor::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    uniform vec4 color;
  });
}

std::string FragmentShaderColor::GetShaderBody() {
  return SHADER0([]() {
    void main() { gl_FragColor = color; }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderColorAA::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    uniform vec4 color;
    varying vec4 edge_dist[2];  // 8 edge distances.
  });
}

std::string FragmentShaderColorAA::GetShaderBody() {
  return SHADER0([]() {
    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;
    }
  });
}

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 {
  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
}

std::string FragmentShaderCheckerboard::GetShaderHead() {
  return SHADER0([]() {
    precision mediump float;
    precision mediump int;
    varying vec2 v_texCoord;
    uniform float alpha;
    uniform float frequency;
    uniform vec4 texTransform;
    uniform vec4 color;
  });
}

std::string FragmentShaderCheckerboard::GetShaderBody() {
  // Shader based on Example 13-17 of "OpenGL ES 2.0 Programming Guide"
  // by Munshi, Ginsburg, Shreiner.
  return SHADER0([]() {
    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;
    }
  });
}

}  // namespace cc
