| // Copyright (c) 2012 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. | 
 |  | 
 | // This file is here so other GLES2 related files can have a common set of | 
 | // includes where appropriate. | 
 |  | 
 | #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 
 |  | 
 | #include <GLES2/gl2.h> | 
 | #include <GLES2/gl2ext.h> | 
 | #include <GLES2/gl2extchromium.h> | 
 | #include <GLES3/gl3.h> | 
 |  | 
 | #include <sstream> | 
 |  | 
 | #include "base/numerics/safe_math.h" | 
 |  | 
 | namespace gpu { | 
 | namespace gles2 { | 
 |  | 
 | namespace gl_error_bit { | 
 | enum GLErrorBit { | 
 |   kNoError = 0, | 
 |   kInvalidEnum = (1 << 0), | 
 |   kInvalidValue = (1 << 1), | 
 |   kInvalidOperation = (1 << 2), | 
 |   kOutOfMemory = (1 << 3), | 
 |   kInvalidFramebufferOperation = (1 << 4), | 
 |   kContextLost = (1 << 5) | 
 | }; | 
 | }  // namespace gl_error_bit | 
 |  | 
 | int GLES2Util::GLGetNumValuesReturned(int id) const { | 
 |   switch (id) { | 
 |     // -- glGetBooleanv, glGetFloatv, glGetIntergerv | 
 |     case GL_ACTIVE_TEXTURE: | 
 |       return 1; | 
 |     case GL_ALIASED_LINE_WIDTH_RANGE: | 
 |       return 2; | 
 |     case GL_ALIASED_POINT_SIZE_RANGE: | 
 |       return 2; | 
 |     case GL_ALPHA_BITS: | 
 |       return 1; | 
 |     case GL_ARRAY_BUFFER_BINDING: | 
 |       return 1; | 
 |     case GL_BLEND: | 
 |       return 1; | 
 |     case GL_BLEND_COLOR: | 
 |       return 4; | 
 |     case GL_BLEND_DST_ALPHA: | 
 |       return 1; | 
 |     case GL_BLEND_DST_RGB: | 
 |       return 1; | 
 |     case GL_BLEND_EQUATION_ALPHA: | 
 |       return 1; | 
 |     case GL_BLEND_EQUATION_RGB: | 
 |       return 1; | 
 |     case GL_BLEND_SRC_ALPHA: | 
 |       return 1; | 
 |     case GL_BLEND_SRC_RGB: | 
 |       return 1; | 
 |     case GL_BLUE_BITS: | 
 |       return 1; | 
 |     case GL_COLOR_CLEAR_VALUE: | 
 |       return 4; | 
 |     case GL_COLOR_WRITEMASK: | 
 |       return 4; | 
 |     case GL_COMPRESSED_TEXTURE_FORMATS: | 
 |       return num_compressed_texture_formats_; | 
 |     case GL_CULL_FACE: | 
 |       return 1; | 
 |     case GL_CULL_FACE_MODE: | 
 |       return 1; | 
 |     case GL_CURRENT_PROGRAM: | 
 |       return 1; | 
 |     case GL_DEPTH_BITS: | 
 |       return 1; | 
 |     case GL_DEPTH_CLEAR_VALUE: | 
 |       return 1; | 
 |     case GL_DEPTH_FUNC: | 
 |       return 1; | 
 |     case GL_DEPTH_RANGE: | 
 |       return 2; | 
 |     case GL_DEPTH_TEST: | 
 |       return 1; | 
 |     case GL_DEPTH_WRITEMASK: | 
 |       return 1; | 
 |     case GL_DITHER: | 
 |       return 1; | 
 |     case GL_ELEMENT_ARRAY_BUFFER_BINDING: | 
 |       return 1; | 
 |     case GL_FRAMEBUFFER_BINDING: | 
 |       return 1; | 
 |     case GL_FRONT_FACE: | 
 |       return 1; | 
 |     case GL_GENERATE_MIPMAP_HINT: | 
 |       return 1; | 
 |     case GL_GREEN_BITS: | 
 |       return 1; | 
 |     case GL_IMPLEMENTATION_COLOR_READ_FORMAT: | 
 |       return 1; | 
 |     case GL_IMPLEMENTATION_COLOR_READ_TYPE: | 
 |       return 1; | 
 |     case GL_LINE_WIDTH: | 
 |       return 1; | 
 |     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: | 
 |       return 1; | 
 |     case GL_MAX_CUBE_MAP_TEXTURE_SIZE: | 
 |       return 1; | 
 |     case GL_MAX_FRAGMENT_UNIFORM_VECTORS: | 
 |       return 1; | 
 |     case GL_MAX_RENDERBUFFER_SIZE: | 
 |       return 1; | 
 |     case GL_MAX_TEXTURE_IMAGE_UNITS: | 
 |       return 1; | 
 |     case GL_MAX_TEXTURE_SIZE: | 
 |       return 1; | 
 |     case GL_MAX_VARYING_VECTORS: | 
 |       return 1; | 
 |     case GL_MAX_VERTEX_ATTRIBS: | 
 |       return 1; | 
 |     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: | 
 |       return 1; | 
 |     case GL_MAX_VERTEX_UNIFORM_VECTORS: | 
 |       return 1; | 
 |     case GL_MAX_VIEWPORT_DIMS: | 
 |       return 2; | 
 |     case GL_NUM_COMPRESSED_TEXTURE_FORMATS: | 
 |       return 1; | 
 |     case GL_NUM_SHADER_BINARY_FORMATS: | 
 |       return 1; | 
 |     case GL_PACK_ALIGNMENT: | 
 |       return 1; | 
 |     case GL_POLYGON_OFFSET_FACTOR: | 
 |       return 1; | 
 |     case GL_POLYGON_OFFSET_FILL: | 
 |       return 1; | 
 |     case GL_POLYGON_OFFSET_UNITS: | 
 |       return 1; | 
 |     case GL_RED_BITS: | 
 |       return 1; | 
 |     case GL_RENDERBUFFER_BINDING: | 
 |       return 1; | 
 |     case GL_SAMPLE_BUFFERS: | 
 |       return 1; | 
 |     case GL_SAMPLE_COVERAGE_INVERT: | 
 |       return 1; | 
 |     case GL_SAMPLE_COVERAGE_VALUE: | 
 |       return 1; | 
 |     case GL_SAMPLES: | 
 |       return 1; | 
 |     case GL_SCISSOR_BOX: | 
 |       return 4; | 
 |     case GL_SCISSOR_TEST: | 
 |       return 1; | 
 |     case GL_SHADER_BINARY_FORMATS: | 
 |       return num_shader_binary_formats_; | 
 |     case GL_SHADER_COMPILER: | 
 |       return 1; | 
 |     case GL_STENCIL_BACK_FAIL: | 
 |       return 1; | 
 |     case GL_STENCIL_BACK_FUNC: | 
 |       return 1; | 
 |     case GL_STENCIL_BACK_PASS_DEPTH_FAIL: | 
 |       return 1; | 
 |     case GL_STENCIL_BACK_PASS_DEPTH_PASS: | 
 |       return 1; | 
 |     case GL_STENCIL_BACK_REF: | 
 |       return 1; | 
 |     case GL_STENCIL_BACK_VALUE_MASK: | 
 |       return 1; | 
 |     case GL_STENCIL_BACK_WRITEMASK: | 
 |       return 1; | 
 |     case GL_STENCIL_BITS: | 
 |       return 1; | 
 |     case GL_STENCIL_CLEAR_VALUE: | 
 |       return 1; | 
 |     case GL_STENCIL_FAIL: | 
 |       return 1; | 
 |     case GL_STENCIL_FUNC: | 
 |       return 1; | 
 |     case GL_STENCIL_PASS_DEPTH_FAIL: | 
 |       return 1; | 
 |     case GL_STENCIL_PASS_DEPTH_PASS: | 
 |       return 1; | 
 |     case GL_STENCIL_REF: | 
 |       return 1; | 
 |     case GL_STENCIL_TEST: | 
 |       return 1; | 
 |     case GL_STENCIL_VALUE_MASK: | 
 |       return 1; | 
 |     case GL_STENCIL_WRITEMASK: | 
 |       return 1; | 
 |     case GL_SUBPIXEL_BITS: | 
 |       return 1; | 
 |     case GL_TEXTURE_BINDING_2D: | 
 |       return 1; | 
 |     case GL_TEXTURE_BINDING_CUBE_MAP: | 
 |       return 1; | 
 |     case GL_TEXTURE_BINDING_EXTERNAL_OES: | 
 |       return 1; | 
 |     case GL_TEXTURE_BINDING_RECTANGLE_ARB: | 
 |       return 1; | 
 |     case GL_UNPACK_ALIGNMENT: | 
 |       return 1; | 
 |     case GL_VIEWPORT: | 
 |       return 4; | 
 |  | 
 |     // ES3 | 
 |     case GL_COPY_READ_BUFFER_BINDING: | 
 |       return 1; | 
 |     case GL_COPY_WRITE_BUFFER_BINDING: | 
 |       return 1; | 
 |     case GL_MAX_3D_TEXTURE_SIZE: | 
 |       return 1; | 
 |     case GL_MAX_ARRAY_TEXTURE_LAYERS: | 
 |       return 1; | 
 |     case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: | 
 |       return 1; | 
 |     case GL_MAX_COMBINED_UNIFORM_BLOCKS: | 
 |       return 1; | 
 |     case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: | 
 |       return 1; | 
 |     case GL_MAX_ELEMENT_INDEX: | 
 |       return 1; | 
 |     case GL_MAX_ELEMENTS_INDICES: | 
 |       return 1; | 
 |     case GL_MAX_ELEMENTS_VERTICES: | 
 |       return 1; | 
 |     case GL_MAX_FRAGMENT_INPUT_COMPONENTS: | 
 |       return 1; | 
 |     case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: | 
 |       return 1; | 
 |     case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: | 
 |       return 1; | 
 |     case GL_MAX_PROGRAM_TEXEL_OFFSET: | 
 |       return 1; | 
 |     case GL_MAX_SERVER_WAIT_TIMEOUT: | 
 |       return 1; | 
 |     case GL_MAX_TEXTURE_LOD_BIAS: | 
 |       return 1; | 
 |     case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: | 
 |       return 1; | 
 |     case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: | 
 |       return 1; | 
 |     case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: | 
 |       return 1; | 
 |     case GL_MAX_UNIFORM_BLOCK_SIZE: | 
 |       return 1; | 
 |     case GL_MAX_UNIFORM_BUFFER_BINDINGS: | 
 |       return 1; | 
 |     case GL_MAX_VARYING_COMPONENTS: | 
 |       return 1; | 
 |     case GL_MAX_VERTEX_OUTPUT_COMPONENTS: | 
 |       return 1; | 
 |     case GL_MAX_VERTEX_UNIFORM_BLOCKS: | 
 |       return 1; | 
 |     case GL_MAX_VERTEX_UNIFORM_COMPONENTS: | 
 |       return 1; | 
 |     case GL_MIN_PROGRAM_TEXEL_OFFSET: | 
 |       return 1; | 
 |     case GL_PIXEL_PACK_BUFFER_BINDING: | 
 |       return 1; | 
 |     case GL_PIXEL_UNPACK_BUFFER_BINDING: | 
 |       return 1; | 
 |     case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: | 
 |       return 1; | 
 |     case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: | 
 |       return 1; | 
 |     case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: | 
 |       return 1; | 
 |     case GL_TRANSFORM_FEEDBACK_BUFFER_START: | 
 |       return 1; | 
 |     case GL_UNIFORM_BUFFER_BINDING: | 
 |       return 1; | 
 |     case GL_UNIFORM_BUFFER_SIZE: | 
 |       return 1; | 
 |     case GL_UNIFORM_BUFFER_START: | 
 |       return 1; | 
 |     case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: | 
 |       return 1; | 
 |  | 
 |     // -- glGetBooleanv, glGetFloatv, glGetIntergerv with | 
 |     //    GL_CHROMIUM_framebuffer_multisample | 
 |     case GL_MAX_SAMPLES_EXT: | 
 |       return 1; | 
 |     case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: | 
 |       return 1; | 
 |  | 
 |     // -- glGetBufferParameteriv | 
 |     case GL_BUFFER_SIZE: | 
 |       return 1; | 
 |     case GL_BUFFER_USAGE: | 
 |       return 1; | 
 |  | 
 |     // ES3 | 
 |     case GL_BUFFER_MAPPED: | 
 |       return 1; | 
 |     case GL_BUFFER_ACCESS_FLAGS: | 
 |       return 1; | 
 |     case GL_BUFFER_MAP_LENGTH: | 
 |       return 1; | 
 |     case GL_BUFFER_MAP_OFFSET: | 
 |       return 1; | 
 |  | 
 |     // -- glGetFramebufferAttachmentParameteriv | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: | 
 |       return 1; | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: | 
 |       return 1; | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: | 
 |       return 1; | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: | 
 |       return 1; | 
 |     // -- glGetFramebufferAttachmentParameteriv with | 
 |     //    GL_EXT_multisampled_render_to_texture | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT: | 
 |       return 1; | 
 |     // -- glGetFramebufferAttachmentParameteriv with | 
 |     //    GL_EXT_sRGB | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: | 
 |       return 1; | 
 |     // ES3 | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: | 
 |       return 1; | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: | 
 |       return 1; | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: | 
 |       return 1; | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: | 
 |       return 1; | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: | 
 |       return 1; | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: | 
 |       return 1; | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: | 
 |       return 1; | 
 |     case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: | 
 |       return 1; | 
 |  | 
 |     // -- glGetProgramiv | 
 |     case GL_DELETE_STATUS: | 
 |       return 1; | 
 |     case GL_LINK_STATUS: | 
 |       return 1; | 
 |     case GL_VALIDATE_STATUS: | 
 |       return 1; | 
 |     case GL_INFO_LOG_LENGTH: | 
 |       return 1; | 
 |     case GL_ATTACHED_SHADERS: | 
 |       return 1; | 
 |     case GL_ACTIVE_ATTRIBUTES: | 
 |       return 1; | 
 |     case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: | 
 |       return 1; | 
 |     case GL_ACTIVE_UNIFORMS: | 
 |       return 1; | 
 |     case GL_ACTIVE_UNIFORM_MAX_LENGTH: | 
 |       return 1; | 
 |  | 
 |     // -- glGetRenderbufferAttachmentParameteriv | 
 |     case GL_RENDERBUFFER_WIDTH: | 
 |       return 1; | 
 |     case GL_RENDERBUFFER_HEIGHT: | 
 |       return 1; | 
 |     case GL_RENDERBUFFER_INTERNAL_FORMAT: | 
 |       return 1; | 
 |     case GL_RENDERBUFFER_RED_SIZE: | 
 |       return 1; | 
 |     case GL_RENDERBUFFER_GREEN_SIZE: | 
 |       return 1; | 
 |     case GL_RENDERBUFFER_BLUE_SIZE: | 
 |       return 1; | 
 |     case GL_RENDERBUFFER_ALPHA_SIZE: | 
 |       return 1; | 
 |     case GL_RENDERBUFFER_DEPTH_SIZE: | 
 |       return 1; | 
 |     case GL_RENDERBUFFER_STENCIL_SIZE: | 
 |       return 1; | 
 |     // -- glGetRenderbufferAttachmentParameteriv with | 
 |     //    GL_EXT_multisampled_render_to_texture | 
 |     case GL_RENDERBUFFER_SAMPLES_EXT: | 
 |       return 1; | 
 |  | 
 |     // -- glGetShaderiv | 
 |     case GL_SHADER_TYPE: | 
 |       return 1; | 
 |     // Already defined under glGetFramebufferAttachemntParameteriv. | 
 |     // case GL_DELETE_STATUS: | 
 |     //   return 1; | 
 |     case GL_COMPILE_STATUS: | 
 |       return 1; | 
 |     // Already defined under glGetFramebufferAttachemntParameteriv. | 
 |     // case GL_INFO_LOG_LENGTH: | 
 |     //   return 1; | 
 |     case GL_SHADER_SOURCE_LENGTH: | 
 |       return 1; | 
 |     case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: | 
 |       return 1; | 
 |  | 
 |     // -- glGetTexParameterfv, glGetTexParameteriv | 
 |     case GL_TEXTURE_MAG_FILTER: | 
 |       return 1; | 
 |     case GL_TEXTURE_MIN_FILTER: | 
 |       return 1; | 
 |     case GL_TEXTURE_WRAP_R: | 
 |       return 1; | 
 |     case GL_TEXTURE_WRAP_S: | 
 |       return 1; | 
 |     case GL_TEXTURE_WRAP_T: | 
 |       return 1; | 
 |     case GL_TEXTURE_COMPARE_FUNC: | 
 |       return 1; | 
 |     case GL_TEXTURE_COMPARE_MODE: | 
 |       return 1; | 
 |     case GL_TEXTURE_MAX_LOD: | 
 |       return 1; | 
 |     case GL_TEXTURE_MIN_LOD: | 
 |       return 1; | 
 |     case GL_TEXTURE_BASE_LEVEL: | 
 |       return 1; | 
 |     case GL_TEXTURE_MAX_LEVEL: | 
 |       return 1; | 
 |     case GL_TEXTURE_IMMUTABLE_FORMAT: | 
 |       return 1; | 
 |     case GL_TEXTURE_IMMUTABLE_LEVELS: | 
 |       return 1; | 
 |     case GL_TEXTURE_MAX_ANISOTROPY_EXT: | 
 |       return 1; | 
 |     case GL_TEXTURE_SWIZZLE_R: | 
 |       return 1; | 
 |     case GL_TEXTURE_SWIZZLE_G: | 
 |       return 1; | 
 |     case GL_TEXTURE_SWIZZLE_B: | 
 |       return 1; | 
 |     case GL_TEXTURE_SWIZZLE_A: | 
 |       return 1; | 
 |  | 
 |     // -- glGetVertexAttrib | 
 |     case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: | 
 |       return 1; | 
 |     case GL_VERTEX_ATTRIB_ARRAY_ENABLED: | 
 |       return 1; | 
 |     case GL_VERTEX_ATTRIB_ARRAY_SIZE: | 
 |       return 1; | 
 |     case GL_VERTEX_ATTRIB_ARRAY_STRIDE: | 
 |       return 1; | 
 |     case GL_VERTEX_ATTRIB_ARRAY_TYPE: | 
 |       return 1; | 
 |     case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: | 
 |       return 1; | 
 |     case GL_CURRENT_VERTEX_ATTRIB: | 
 |       return 4; | 
 |     case GL_VERTEX_ATTRIB_ARRAY_INTEGER: | 
 |       return 1; | 
 |     case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: | 
 |       return 1; | 
 |  | 
 |     // -- glGetSynciv | 
 |     case GL_OBJECT_TYPE: | 
 |       return 1; | 
 |     case GL_SYNC_STATUS: | 
 |       return 1; | 
 |     case GL_SYNC_CONDITION: | 
 |       return 1; | 
 |     case GL_SYNC_FLAGS: | 
 |       return 1; | 
 |  | 
 |     // -- glHint with GL_OES_standard_derivatives | 
 |     case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: | 
 |       return 1; | 
 |  | 
 |     // Chromium internal bind_generates_resource query | 
 |     case GL_BIND_GENERATES_RESOURCE_CHROMIUM: | 
 |       return 1; | 
 |  | 
 |     // bad enum | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | namespace { | 
 |  | 
 | // Return the number of bytes per element, based on the element type. | 
 | int BytesPerElement(int type) { | 
 |   switch (type) { | 
 |     case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: | 
 |       return 8; | 
 |     case GL_FLOAT: | 
 |     case GL_UNSIGNED_INT_24_8_OES: | 
 |     case GL_UNSIGNED_INT: | 
 |     case GL_INT: | 
 |     case GL_UNSIGNED_INT_2_10_10_10_REV: | 
 |     case GL_UNSIGNED_INT_10F_11F_11F_REV: | 
 |     case GL_UNSIGNED_INT_5_9_9_9_REV: | 
 |       return 4; | 
 |     case GL_HALF_FLOAT: | 
 |     case GL_HALF_FLOAT_OES: | 
 |     case GL_UNSIGNED_SHORT: | 
 |     case GL_SHORT: | 
 |     case GL_UNSIGNED_SHORT_5_6_5: | 
 |     case GL_UNSIGNED_SHORT_4_4_4_4: | 
 |     case GL_UNSIGNED_SHORT_5_5_5_1: | 
 |       return 2; | 
 |     case GL_UNSIGNED_BYTE: | 
 |     case GL_BYTE: | 
 |       return 1; | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | }  // anonymous namespace | 
 |  | 
 | // Return the number of elements per group of a specified format. | 
 | int GLES2Util::ElementsPerGroup(int format, int type) { | 
 |   switch (type) { | 
 |     case GL_UNSIGNED_SHORT_5_6_5: | 
 |     case GL_UNSIGNED_SHORT_4_4_4_4: | 
 |     case GL_UNSIGNED_SHORT_5_5_5_1: | 
 |     case GL_UNSIGNED_INT_24_8_OES: | 
 |     case GL_UNSIGNED_INT_2_10_10_10_REV: | 
 |     case GL_UNSIGNED_INT_10F_11F_11F_REV: | 
 |     case GL_UNSIGNED_INT_5_9_9_9_REV: | 
 |     case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: | 
 |        return 1; | 
 |     default: | 
 |        break; | 
 |     } | 
 |  | 
 |     switch (format) { | 
 |     case GL_RGB: | 
 |     case GL_RGB_INTEGER: | 
 |     case GL_SRGB_EXT: | 
 |        return 3; | 
 |     case GL_LUMINANCE_ALPHA: | 
 |     case GL_RG_EXT: | 
 |     case GL_RG_INTEGER: | 
 |        return 2; | 
 |     case GL_RGBA: | 
 |     case GL_RGBA_INTEGER: | 
 |     case GL_BGRA_EXT: | 
 |     case GL_SRGB_ALPHA_EXT: | 
 |        return 4; | 
 |     case GL_ALPHA: | 
 |     case GL_LUMINANCE: | 
 |     case GL_DEPTH_COMPONENT: | 
 |     case GL_DEPTH_COMPONENT24_OES: | 
 |     case GL_DEPTH_COMPONENT32_OES: | 
 |     case GL_DEPTH_COMPONENT16: | 
 |     case GL_DEPTH24_STENCIL8_OES: | 
 |     case GL_DEPTH_STENCIL_OES: | 
 |     case GL_RED_EXT: | 
 |     case GL_RED_INTEGER: | 
 |        return 1; | 
 |     default: | 
 |        return 0; | 
 |   } | 
 | } | 
 |  | 
 | uint32_t GLES2Util::ComputeImageGroupSize(int format, int type) { | 
 |   int bytes_per_element = BytesPerElement(type); | 
 |   DCHECK_GE(8, bytes_per_element); | 
 |   int elements_per_group = ElementsPerGroup(format, type); | 
 |   DCHECK_GE(4, elements_per_group); | 
 |   return  bytes_per_element * elements_per_group; | 
 | } | 
 |  | 
 | bool GLES2Util::ComputeImageRowSizeHelper(int width, | 
 |                                           uint32_t bytes_per_group, | 
 |                                           int alignment, | 
 |                                           uint32_t* rt_unpadded_row_size, | 
 |                                           uint32_t* rt_padded_row_size, | 
 |                                           uint32_t* rt_padding) { | 
 |   DCHECK(alignment == 1 || alignment == 2 || | 
 |          alignment == 4 || alignment == 8); | 
 |   uint32_t unpadded_row_size; | 
 |   if (!SafeMultiplyUint32(width, bytes_per_group, &unpadded_row_size)) { | 
 |     return false; | 
 |   } | 
 |   uint32_t residual = unpadded_row_size % alignment; | 
 |   uint32_t padding = 0; | 
 |   uint32_t padded_row_size = unpadded_row_size; | 
 |   if (residual > 0) { | 
 |     padding = alignment - residual; | 
 |     if (!SafeAddUint32(unpadded_row_size, padding, &padded_row_size)) { | 
 |       return false; | 
 |     } | 
 |   } | 
 |  | 
 |   if (rt_unpadded_row_size) | 
 |     *rt_unpadded_row_size = unpadded_row_size; | 
 |   if (rt_padded_row_size) | 
 |     *rt_padded_row_size = padded_row_size; | 
 |   if (rt_padding) | 
 |     *rt_padding = padding; | 
 |   return true; | 
 | } | 
 |  | 
 | bool GLES2Util::ComputeImagePaddedRowSize(int width, | 
 |                                           int format, | 
 |                                           int type, | 
 |                                           int alignment, | 
 |                                           uint32_t* padded_row_size) { | 
 |   uint32_t bytes_per_group = ComputeImageGroupSize(format, type); | 
 |   return ComputeImageRowSizeHelper( | 
 |       width, bytes_per_group, alignment, nullptr, padded_row_size, nullptr); | 
 | } | 
 |  | 
 | // Returns the amount of data glTexImage*D or glTexSubImage*D will access. | 
 | bool GLES2Util::ComputeImageDataSizes(int width, | 
 |                                       int height, | 
 |                                       int depth, | 
 |                                       int format, | 
 |                                       int type, | 
 |                                       int alignment, | 
 |                                       uint32_t* size, | 
 |                                       uint32_t* opt_unpadded_row_size, | 
 |                                       uint32_t* opt_padded_row_size) { | 
 |   PixelStoreParams params; | 
 |   params.alignment = alignment; | 
 |   return ComputeImageDataSizesES3( | 
 |       width, height, depth, format, type, params, | 
 |       size, opt_unpadded_row_size, opt_padded_row_size, nullptr, nullptr); | 
 | } | 
 |  | 
 | bool GLES2Util::ComputeImageDataSizesES3( | 
 |     int width, int height, int depth, int format, int type, | 
 |     const PixelStoreParams& params, | 
 |     uint32_t* size, uint32_t* opt_unpadded_row_size, | 
 |     uint32_t* opt_padded_row_size, uint32_t* opt_skip_size, | 
 |     uint32_t* opt_padding) { | 
 |   DCHECK(width >= 0 && height >= 0 && depth >= 0); | 
 |  | 
 |   uint32_t bytes_per_group = ComputeImageGroupSize(format, type); | 
 |  | 
 |   uint32_t unpadded_row_size; | 
 |   uint32_t padded_row_size; | 
 |   if (!ComputeImageRowSizeHelper(width, bytes_per_group, params.alignment, | 
 |                                  &unpadded_row_size, &padded_row_size, | 
 |                                  opt_padding)) { | 
 |     return false; | 
 |   } | 
 |   if (params.row_length > 0 && | 
 |       !ComputeImageRowSizeHelper(params.row_length, bytes_per_group, | 
 |                                  params.alignment, nullptr, &padded_row_size, | 
 |                                  opt_padding)) { | 
 |     // Here we re-compute the padded_row_size, but the unpadded_row_size | 
 |     // isn't affected. That is, the last row isn't affected by ROW_LENGTH. | 
 |     return false; | 
 |   } | 
 |  | 
 |   int image_height = params.image_height > 0 ? params.image_height : height; | 
 |   uint32_t num_of_rows; | 
 |   if (depth > 0) { | 
 |     if (!SafeMultiplyUint32(image_height, depth - 1, &num_of_rows) || | 
 |         !SafeAddUint32(num_of_rows, height, &num_of_rows)) { | 
 |       return false; | 
 |     } | 
 |   } else { | 
 |     num_of_rows = 0; | 
 |   } | 
 |  | 
 |   if (num_of_rows > 0) { | 
 |     uint32_t size_of_all_but_last_row; | 
 |     if (!SafeMultiplyUint32((num_of_rows - 1), padded_row_size, | 
 |                             &size_of_all_but_last_row)) { | 
 |       return false; | 
 |     } | 
 |     if (!SafeAddUint32(size_of_all_but_last_row, unpadded_row_size, size)) { | 
 |       return false; | 
 |     } | 
 |   } else { | 
 |     *size = 0; | 
 |   } | 
 |  | 
 |   uint32_t skip_size = 0; | 
 |   if (params.skip_images > 0) { | 
 |     uint32_t image_size; | 
 |     if (!SafeMultiplyUint32(image_height, padded_row_size, &image_size)) | 
 |       return false; | 
 |     if (!SafeMultiplyUint32(image_size, params.skip_images, &skip_size)) | 
 |       return false; | 
 |   } | 
 |   if (params.skip_rows > 0) { | 
 |     uint32_t temp; | 
 |     if (!SafeMultiplyUint32(padded_row_size, params.skip_rows, &temp)) | 
 |       return false; | 
 |     if (!SafeAddUint32(skip_size, temp, &skip_size)) | 
 |       return false; | 
 |   } | 
 |   if (params.skip_pixels > 0) { | 
 |     uint32_t temp; | 
 |     if (!SafeMultiplyUint32(bytes_per_group, params.skip_pixels, &temp)) | 
 |       return false; | 
 |     if (!SafeAddUint32(skip_size, temp, &skip_size)) | 
 |       return false; | 
 |   } | 
 |   uint32_t total_size; | 
 |   if (!SafeAddUint32(*size, skip_size, &total_size)) | 
 |     return false; | 
 |  | 
 |   if (opt_padded_row_size) { | 
 |     *opt_padded_row_size = padded_row_size; | 
 |   } | 
 |   if (opt_unpadded_row_size) { | 
 |     *opt_unpadded_row_size = unpadded_row_size; | 
 |   } | 
 |   if (opt_skip_size) | 
 |     *opt_skip_size = skip_size; | 
 |   return true; | 
 | } | 
 |  | 
 | size_t GLES2Util::RenderbufferBytesPerPixel(int format) { | 
 |   switch (format) { | 
 |     case GL_STENCIL_INDEX8: | 
 |       return 1; | 
 |     case GL_RGBA4: | 
 |     case GL_RGB565: | 
 |     case GL_RGB5_A1: | 
 |     case GL_DEPTH_COMPONENT16: | 
 |       return 2; | 
 |     case GL_RGB: | 
 |     case GL_RGBA: | 
 |     case GL_DEPTH24_STENCIL8_OES: | 
 |     case GL_RGB8_OES: | 
 |     case GL_RGBA8_OES: | 
 |     case GL_DEPTH_COMPONENT24_OES: | 
 |       return 4; | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | uint32_t GLES2Util::GetElementSizeForUniformType(int type) { | 
 |   switch (type) { | 
 |     case GL_FLOAT: | 
 |     case GL_FLOAT_VEC2: | 
 |     case GL_FLOAT_VEC3: | 
 |     case GL_FLOAT_VEC4: | 
 |     case GL_FLOAT_MAT2: | 
 |     case GL_FLOAT_MAT3: | 
 |     case GL_FLOAT_MAT4: | 
 |       return sizeof(GLfloat); | 
 |     case GL_INT: | 
 |     case GL_INT_VEC2: | 
 |     case GL_INT_VEC3: | 
 |     case GL_INT_VEC4: | 
 |     case GL_BOOL: | 
 |     case GL_BOOL_VEC2: | 
 |     case GL_BOOL_VEC3: | 
 |     case GL_BOOL_VEC4: | 
 |     case GL_SAMPLER_2D: | 
 |     case GL_SAMPLER_CUBE: | 
 |     case GL_SAMPLER_2D_RECT_ARB:  // extension. | 
 |     case GL_SAMPLER_EXTERNAL_OES:  // extension. | 
 |       return sizeof(GLint); | 
 |  | 
 |     // ES3 types. | 
 |     case GL_UNSIGNED_INT: | 
 |     case GL_UNSIGNED_INT_VEC2: | 
 |     case GL_UNSIGNED_INT_VEC3: | 
 |     case GL_UNSIGNED_INT_VEC4: | 
 |       return sizeof(GLuint); | 
 |     case GL_SAMPLER_3D: | 
 |     case GL_SAMPLER_2D_SHADOW: | 
 |     case GL_SAMPLER_2D_ARRAY: | 
 |     case GL_SAMPLER_2D_ARRAY_SHADOW: | 
 |     case GL_SAMPLER_CUBE_SHADOW: | 
 |     case GL_INT_SAMPLER_2D: | 
 |     case GL_INT_SAMPLER_3D: | 
 |     case GL_INT_SAMPLER_CUBE: | 
 |     case GL_INT_SAMPLER_2D_ARRAY: | 
 |     case GL_UNSIGNED_INT_SAMPLER_2D: | 
 |     case GL_UNSIGNED_INT_SAMPLER_3D: | 
 |     case GL_UNSIGNED_INT_SAMPLER_CUBE: | 
 |     case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: | 
 |       return sizeof(GLint); | 
 |     case GL_FLOAT_MAT2x3: | 
 |     case GL_FLOAT_MAT3x2: | 
 |     case GL_FLOAT_MAT2x4: | 
 |     case GL_FLOAT_MAT4x2: | 
 |     case GL_FLOAT_MAT3x4: | 
 |     case GL_FLOAT_MAT4x3: | 
 |       return sizeof(GLfloat); | 
 |  | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | uint32_t GLES2Util::GetElementCountForUniformType(int type) { | 
 |   switch (type) { | 
 |     case GL_FLOAT: | 
 |     case GL_INT: | 
 |     case GL_BOOL: | 
 |     case GL_SAMPLER_2D: | 
 |     case GL_SAMPLER_CUBE: | 
 |     case GL_SAMPLER_2D_RECT_ARB:  // extension. | 
 |     case GL_SAMPLER_EXTERNAL_OES:  // extension. | 
 |       return 1; | 
 |     case GL_FLOAT_VEC2: | 
 |     case GL_INT_VEC2: | 
 |     case GL_BOOL_VEC2: | 
 |       return 2; | 
 |     case GL_FLOAT_VEC3: | 
 |     case GL_INT_VEC3: | 
 |     case GL_BOOL_VEC3: | 
 |       return 3; | 
 |     case GL_FLOAT_VEC4: | 
 |     case GL_INT_VEC4: | 
 |     case GL_BOOL_VEC4: | 
 |     case GL_FLOAT_MAT2: | 
 |       return 4; | 
 |     case GL_FLOAT_MAT3: | 
 |       return 9; | 
 |     case GL_FLOAT_MAT4: | 
 |       return 16; | 
 |  | 
 |     // ES3 types. | 
 |     case GL_UNSIGNED_INT: | 
 |     case GL_SAMPLER_3D: | 
 |     case GL_SAMPLER_2D_SHADOW: | 
 |     case GL_SAMPLER_2D_ARRAY: | 
 |     case GL_SAMPLER_2D_ARRAY_SHADOW: | 
 |     case GL_SAMPLER_CUBE_SHADOW: | 
 |     case GL_INT_SAMPLER_2D: | 
 |     case GL_INT_SAMPLER_3D: | 
 |     case GL_INT_SAMPLER_CUBE: | 
 |     case GL_INT_SAMPLER_2D_ARRAY: | 
 |     case GL_UNSIGNED_INT_SAMPLER_2D: | 
 |     case GL_UNSIGNED_INT_SAMPLER_3D: | 
 |     case GL_UNSIGNED_INT_SAMPLER_CUBE: | 
 |     case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: | 
 |       return 1; | 
 |     case GL_UNSIGNED_INT_VEC2: | 
 |       return 2; | 
 |     case GL_UNSIGNED_INT_VEC3: | 
 |       return 3; | 
 |     case GL_UNSIGNED_INT_VEC4: | 
 |       return 4; | 
 |     case GL_FLOAT_MAT2x3: | 
 |     case GL_FLOAT_MAT3x2: | 
 |       return 6; | 
 |     case GL_FLOAT_MAT2x4: | 
 |     case GL_FLOAT_MAT4x2: | 
 |       return 8; | 
 |     case GL_FLOAT_MAT3x4: | 
 |     case GL_FLOAT_MAT4x3: | 
 |       return 12; | 
 |  | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | size_t GLES2Util::GetGLTypeSizeForTextures(uint32_t type) { | 
 |   return static_cast<size_t>(BytesPerElement(type)); | 
 | } | 
 |  | 
 | size_t GLES2Util::GetGLTypeSizeForBuffers(uint32_t type) { | 
 |   switch (type) { | 
 |     case GL_BYTE: | 
 |       return sizeof(GLbyte);  // NOLINT | 
 |     case GL_UNSIGNED_BYTE: | 
 |       return sizeof(GLubyte);  // NOLINT | 
 |     case GL_SHORT: | 
 |       return sizeof(GLshort);  // NOLINT | 
 |     case GL_UNSIGNED_SHORT: | 
 |       return sizeof(GLushort);  // NOLINT | 
 |     case GL_INT: | 
 |       return sizeof(GLint);  // NOLINT | 
 |     case GL_UNSIGNED_INT: | 
 |       return sizeof(GLuint);  // NOLINT | 
 |     case GL_FLOAT: | 
 |       return sizeof(GLfloat);  // NOLINT | 
 |     case GL_FIXED: | 
 |       return sizeof(GLfixed);  // NOLINT | 
 |     case GL_HALF_FLOAT: | 
 |       return sizeof(GLushort);  // NOLINT | 
 |     case GL_INT_2_10_10_10_REV: | 
 |       return sizeof(GLint);  // NOLINT | 
 |     case GL_UNSIGNED_INT_2_10_10_10_REV: | 
 |       return sizeof(GLuint);  // NOLINT | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | size_t GLES2Util::GetGroupSizeForBufferType(uint32_t count, uint32_t type) { | 
 |   size_t type_size = GetGLTypeSizeForBuffers(type); | 
 |   // For packed types, group size equals to the type size. | 
 |   if (type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) { | 
 |     DCHECK_EQ(4u, count); | 
 |     return type_size; | 
 |   } | 
 |   return type_size * count; | 
 | } | 
 | size_t GLES2Util::GetComponentCountForGLTransformType(uint32_t type) { | 
 |   switch (type) { | 
 |     case GL_TRANSLATE_X_CHROMIUM: | 
 |     case GL_TRANSLATE_Y_CHROMIUM: | 
 |       return 1; | 
 |     case GL_TRANSLATE_2D_CHROMIUM: | 
 |       return 2; | 
 |     case GL_TRANSLATE_3D_CHROMIUM: | 
 |       return 3; | 
 |     case GL_AFFINE_2D_CHROMIUM: | 
 |     case GL_TRANSPOSE_AFFINE_2D_CHROMIUM: | 
 |       return 6; | 
 |     case GL_AFFINE_3D_CHROMIUM: | 
 |     case GL_TRANSPOSE_AFFINE_3D_CHROMIUM: | 
 |       return 12; | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 | size_t GLES2Util::GetCoefficientCountForGLPathFragmentInputGenMode( | 
 |     uint32_t gen_mode) { | 
 |   switch (gen_mode) { | 
 |     case GL_EYE_LINEAR_CHROMIUM: | 
 |       return 4; | 
 |     case GL_OBJECT_LINEAR_CHROMIUM: | 
 |       return 3; | 
 |     case GL_CONSTANT_CHROMIUM: | 
 |       return 1; | 
 |     case GL_NONE: | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | size_t GLES2Util::GetGLTypeSizeForPathCoordType(uint32_t type) { | 
 |   switch (type) { | 
 |     case GL_BYTE: | 
 |       return sizeof(GLbyte);  // NOLINT | 
 |     case GL_UNSIGNED_BYTE: | 
 |       return sizeof(GLubyte);  // NOLINT | 
 |     case GL_SHORT: | 
 |       return sizeof(GLshort);  // NOLINT | 
 |     case GL_UNSIGNED_SHORT: | 
 |       return sizeof(GLushort);  // NOLINT | 
 |     case GL_FLOAT: | 
 |       return sizeof(GLfloat);  // NOLINT | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | size_t GLES2Util::GetGLTypeSizeForGLPathNameType(uint32_t type) { | 
 |   switch (type) { | 
 |     case GL_BYTE: | 
 |       return sizeof(GLbyte);  // NOLINT | 
 |     case GL_UNSIGNED_BYTE: | 
 |       return sizeof(GLubyte);  // NOLINT | 
 |     case GL_SHORT: | 
 |       return sizeof(GLshort);  // NOLINT | 
 |     case GL_UNSIGNED_SHORT: | 
 |       return sizeof(GLushort);  // NOLINT | 
 |     case GL_INT: | 
 |       return sizeof(GLint);  // NOLINT | 
 |     case GL_UNSIGNED_INT: | 
 |       return sizeof(GLuint);  // NOLINT | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | uint32_t GLES2Util::GLErrorToErrorBit(uint32_t error) { | 
 |   switch (error) { | 
 |     case GL_INVALID_ENUM: | 
 |       return gl_error_bit::kInvalidEnum; | 
 |     case GL_INVALID_VALUE: | 
 |       return gl_error_bit::kInvalidValue; | 
 |     case GL_INVALID_OPERATION: | 
 |       return gl_error_bit::kInvalidOperation; | 
 |     case GL_OUT_OF_MEMORY: | 
 |       return gl_error_bit::kOutOfMemory; | 
 |     case GL_INVALID_FRAMEBUFFER_OPERATION: | 
 |       return gl_error_bit::kInvalidFramebufferOperation; | 
 |     case GL_CONTEXT_LOST_KHR: | 
 |       return gl_error_bit::kContextLost; | 
 |     default: | 
 |       NOTREACHED(); | 
 |       return gl_error_bit::kNoError; | 
 |   } | 
 | } | 
 |  | 
 | uint32_t GLES2Util::GLErrorBitToGLError(uint32_t error_bit) { | 
 |   switch (error_bit) { | 
 |     case gl_error_bit::kInvalidEnum: | 
 |       return GL_INVALID_ENUM; | 
 |     case gl_error_bit::kInvalidValue: | 
 |       return GL_INVALID_VALUE; | 
 |     case gl_error_bit::kInvalidOperation: | 
 |       return GL_INVALID_OPERATION; | 
 |     case gl_error_bit::kOutOfMemory: | 
 |       return GL_OUT_OF_MEMORY; | 
 |     case gl_error_bit::kInvalidFramebufferOperation: | 
 |       return GL_INVALID_FRAMEBUFFER_OPERATION; | 
 |     case gl_error_bit::kContextLost: | 
 |       return GL_CONTEXT_LOST_KHR; | 
 |     default: | 
 |       NOTREACHED(); | 
 |       return GL_NO_ERROR; | 
 |   } | 
 | } | 
 |  | 
 | uint32_t GLES2Util::IndexToGLFaceTarget(int index) { | 
 |   static uint32_t faces[] = { | 
 |       GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, | 
 |       GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, | 
 |       GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, | 
 |   }; | 
 |   return faces[index]; | 
 | } | 
 |  | 
 | size_t GLES2Util::GLTargetToFaceIndex(uint32_t target) { | 
 |   switch (target) { | 
 |     case GL_TEXTURE_2D: | 
 |     case GL_TEXTURE_EXTERNAL_OES: | 
 |     case GL_TEXTURE_RECTANGLE_ARB: | 
 |     case GL_TEXTURE_3D: | 
 |     case GL_TEXTURE_2D_ARRAY: | 
 |       return 0; | 
 |     case GL_TEXTURE_CUBE_MAP_POSITIVE_X: | 
 |       return 0; | 
 |     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: | 
 |       return 1; | 
 |     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: | 
 |       return 2; | 
 |     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: | 
 |       return 3; | 
 |     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: | 
 |       return 4; | 
 |     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: | 
 |       return 5; | 
 |     default: | 
 |       NOTREACHED(); | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | uint32_t GLES2Util::GLFaceTargetToTextureTarget(uint32_t target) { | 
 |   switch (target) { | 
 |     case GL_TEXTURE_2D: | 
 |     case GL_TEXTURE_EXTERNAL_OES: | 
 |     case GL_TEXTURE_RECTANGLE_ARB: | 
 |     case GL_TEXTURE_3D: | 
 |     case GL_TEXTURE_2D_ARRAY: | 
 |       return target; | 
 |     case GL_TEXTURE_CUBE_MAP_POSITIVE_X: | 
 |     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: | 
 |     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: | 
 |     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: | 
 |     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: | 
 |     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: | 
 |       return GL_TEXTURE_CUBE_MAP; | 
 |     default: | 
 |       NOTREACHED(); | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | uint32_t GLES2Util::GetGLReadPixelsImplementationFormat( | 
 |     uint32_t internal_format, | 
 |     uint32_t texture_type, | 
 |     bool supports_bgra) { | 
 |   switch (internal_format) { | 
 |     case GL_R8: | 
 |     case GL_R16F: | 
 |     case GL_R32F: | 
 |       return GL_RED; | 
 |     case GL_R8UI: | 
 |     case GL_R8I: | 
 |     case GL_R16UI: | 
 |     case GL_R16I: | 
 |     case GL_R32UI: | 
 |     case GL_R32I: | 
 |       return GL_RED_INTEGER; | 
 |     case GL_RG8: | 
 |     case GL_RG16F: | 
 |     case GL_RG32F: | 
 |       return GL_RG; | 
 |     case GL_RG8UI: | 
 |     case GL_RG8I: | 
 |     case GL_RG16UI: | 
 |     case GL_RG16I: | 
 |     case GL_RG32UI: | 
 |     case GL_RG32I: | 
 |       return GL_RG_INTEGER; | 
 |     case GL_RGB: | 
 |     case GL_RGB8: | 
 |     case GL_RGB565: | 
 |     case GL_R11F_G11F_B10F: | 
 |     case GL_RGB16F: | 
 |     case GL_RGB32F: | 
 |       return GL_RGB; | 
 |     case GL_RGBA8UI: | 
 |     case GL_RGBA8I: | 
 |     case GL_RGB10_A2UI: | 
 |     case GL_RGBA16UI: | 
 |     case GL_RGBA16I: | 
 |     case GL_RGBA32UI: | 
 |     case GL_RGBA32I: | 
 |       return GL_RGBA_INTEGER; | 
 |     case GL_BGRA_EXT: | 
 |     case GL_BGRA8_EXT: | 
 |       // If the internal format is BGRA, we prefer reading back BGRA if | 
 |       // possible. | 
 |       if (texture_type == GL_UNSIGNED_BYTE && supports_bgra) | 
 |         return GL_BGRA_EXT; | 
 |       else | 
 |         return GL_RGBA; | 
 |     default: | 
 |       return GL_RGBA; | 
 |   } | 
 | } | 
 |  | 
 | uint32_t GLES2Util::GetGLReadPixelsImplementationType(uint32_t internal_format, | 
 |                                                       uint32_t texture_type) { | 
 |   switch (internal_format) { | 
 |     case GL_R16UI: | 
 |     case GL_RG16UI: | 
 |     case GL_RGBA16UI: | 
 |     case GL_RGB10_A2: | 
 |     case GL_RGB10_A2UI: | 
 |       return GL_UNSIGNED_SHORT; | 
 |     case GL_R32UI: | 
 |     case GL_RG32UI: | 
 |     case GL_RGBA32UI: | 
 |       return GL_UNSIGNED_INT; | 
 |     case GL_R8I: | 
 |     case GL_RG8I: | 
 |     case GL_RGBA8I: | 
 |       return GL_BYTE; | 
 |     case GL_R16I: | 
 |     case GL_RG16I: | 
 |     case GL_RGBA16I: | 
 |       return GL_SHORT; | 
 |     case GL_R32I: | 
 |     case GL_RG32I: | 
 |     case GL_RGBA32I: | 
 |       return GL_INT; | 
 |     case GL_R32F: | 
 |     case GL_RG32F: | 
 |     case GL_RGB32F: | 
 |     case GL_RGBA32F: | 
 |     case GL_R11F_G11F_B10F: | 
 |       return GL_UNSIGNED_BYTE; | 
 |     case GL_R16F: | 
 |     case GL_RG16F: | 
 |     case GL_RGB16F: | 
 |     case GL_RGBA16F: | 
 |       return GL_HALF_FLOAT; | 
 |     default: | 
 |       // Unsized internal format. | 
 |       return texture_type; | 
 |   } | 
 | } | 
 |  | 
 | uint32_t GLES2Util::GetChannelsForFormat(int format) { | 
 |   switch (format) { | 
 |     case GL_ALPHA: | 
 |     case GL_ALPHA16F_EXT: | 
 |     case GL_ALPHA32F_EXT: | 
 |       return kAlpha; | 
 |     case GL_LUMINANCE: | 
 |       return kRGB; | 
 |     case GL_LUMINANCE_ALPHA: | 
 |       return kRGBA; | 
 |     case GL_RGB: | 
 |     case GL_RGB8_OES: | 
 |     case GL_RGB565: | 
 |     case GL_RGB16F_EXT: | 
 |     case GL_RGB32F_EXT: | 
 |     case GL_SRGB_EXT: | 
 |     case GL_SRGB8: | 
 |     case GL_RGB8_SNORM: | 
 |     case GL_R11F_G11F_B10F: | 
 |     case GL_RGB9_E5: | 
 |     case GL_RGB8UI: | 
 |     case GL_RGB8I: | 
 |     case GL_RGB16UI: | 
 |     case GL_RGB16I: | 
 |     case GL_RGB32UI: | 
 |     case GL_RGB32I: | 
 |       return kRGB; | 
 |     case GL_BGRA_EXT: | 
 |     case GL_BGRA8_EXT: | 
 |     case GL_RGBA16F_EXT: | 
 |     case GL_RGBA32F_EXT: | 
 |     case GL_RGBA: | 
 |     case GL_RGBA8_OES: | 
 |     case GL_RGBA4: | 
 |     case GL_RGB5_A1: | 
 |     case GL_SRGB_ALPHA_EXT: | 
 |     case GL_SRGB8_ALPHA8_EXT: | 
 |     case GL_RGBA8_SNORM: | 
 |     case GL_RGB10_A2: | 
 |     case GL_RGBA8UI: | 
 |     case GL_RGBA8I: | 
 |     case GL_RGB10_A2UI: | 
 |     case GL_RGBA16UI: | 
 |     case GL_RGBA16I: | 
 |     case GL_RGBA32UI: | 
 |     case GL_RGBA32I: | 
 |       return kRGBA; | 
 |     case GL_DEPTH_COMPONENT32_OES: | 
 |     case GL_DEPTH_COMPONENT24_OES: | 
 |     case GL_DEPTH_COMPONENT16: | 
 |     case GL_DEPTH_COMPONENT: | 
 |     case GL_DEPTH_COMPONENT32F: | 
 |       return kDepth; | 
 |     case GL_STENCIL_INDEX8: | 
 |       return kStencil; | 
 |     case GL_DEPTH_STENCIL_OES: | 
 |     case GL_DEPTH24_STENCIL8_OES: | 
 |     case GL_DEPTH32F_STENCIL8: | 
 |       return kDepth | kStencil; | 
 |     case GL_RED_EXT: | 
 |     case GL_R8: | 
 |     case GL_R8_SNORM: | 
 |     case GL_R16F: | 
 |     case GL_R32F: | 
 |     case GL_R8UI: | 
 |     case GL_R8I: | 
 |     case GL_R16UI: | 
 |     case GL_R16I: | 
 |     case GL_R32UI: | 
 |     case GL_R32I: | 
 |       return kRed; | 
 |     case GL_RG_EXT: | 
 |     case GL_RG8: | 
 |     case GL_RG8_SNORM: | 
 |     case GL_RG16F: | 
 |     case GL_RG32F: | 
 |     case GL_RG8UI: | 
 |     case GL_RG8I: | 
 |     case GL_RG16UI: | 
 |     case GL_RG16I: | 
 |     case GL_RG32UI: | 
 |     case GL_RG32I: | 
 |       return kRed | kGreen; | 
 |     default: | 
 |       return 0x0000; | 
 |   } | 
 | } | 
 |  | 
 | bool GLES2Util::IsSizedColorFormat(uint32_t internal_format) { | 
 |   switch (internal_format) { | 
 |     case GL_ALPHA16F_EXT: | 
 |     case GL_ALPHA32F_EXT: | 
 |     case GL_RGB8: | 
 |     case GL_RGB565: | 
 |     case GL_RGB16F: | 
 |     case GL_RGB32F: | 
 |     case GL_SRGB8: | 
 |     case GL_RGB8_SNORM: | 
 |     case GL_R11F_G11F_B10F: | 
 |     case GL_RGB9_E5: | 
 |     case GL_RGB8UI: | 
 |     case GL_RGB8I: | 
 |     case GL_RGB16UI: | 
 |     case GL_RGB16I: | 
 |     case GL_RGB32UI: | 
 |     case GL_RGB32I: | 
 |     case GL_BGRA8_EXT: | 
 |     case GL_RGBA16F: | 
 |     case GL_RGBA32F: | 
 |     case GL_RGBA8_OES: | 
 |     case GL_RGBA4: | 
 |     case GL_RGB5_A1: | 
 |     case GL_SRGB8_ALPHA8: | 
 |     case GL_RGBA8_SNORM: | 
 |     case GL_RGB10_A2: | 
 |     case GL_RGBA8UI: | 
 |     case GL_RGBA8I: | 
 |     case GL_RGB10_A2UI: | 
 |     case GL_RGBA16UI: | 
 |     case GL_RGBA16I: | 
 |     case GL_RGBA32UI: | 
 |     case GL_RGBA32I: | 
 |     case GL_R8: | 
 |     case GL_R8_SNORM: | 
 |     case GL_R16F: | 
 |     case GL_R32F: | 
 |     case GL_R8UI: | 
 |     case GL_R8I: | 
 |     case GL_R16UI: | 
 |     case GL_R16I: | 
 |     case GL_R32UI: | 
 |     case GL_R32I: | 
 |     case GL_RG8: | 
 |     case GL_RG8_SNORM: | 
 |     case GL_RG16F: | 
 |     case GL_RG32F: | 
 |     case GL_RG8UI: | 
 |     case GL_RG8I: | 
 |     case GL_RG16UI: | 
 |     case GL_RG16I: | 
 |     case GL_RG32UI: | 
 |     case GL_RG32I: | 
 |       return true; | 
 |     default: | 
 |       return false; | 
 |   } | 
 | } | 
 |  | 
 | void GLES2Util::GetColorFormatComponentSizes( | 
 |     uint32_t internal_format, uint32_t type, int* r, int* g, int* b, int* a) { | 
 |   DCHECK(r && g && b && a); | 
 |   *r = 0; | 
 |   *g = 0; | 
 |   *b = 0; | 
 |   *a = 0; | 
 |  | 
 |   switch (internal_format) { | 
 |     case GL_LUMINANCE: | 
 |       switch (type) { | 
 |         case GL_UNSIGNED_BYTE: | 
 |           // It can be RGBA8, RGB8, RG8, or R8. | 
 |           // Here we only require R8, which is good enough for validation. | 
 |           // Same for other types. | 
 |           internal_format = GL_R8; | 
 |           break; | 
 |         case GL_HALF_FLOAT_OES: | 
 |           internal_format = GL_R16F; | 
 |           break; | 
 |         case GL_FLOAT: | 
 |           internal_format = GL_R32F; | 
 |           return; | 
 |         default: | 
 |           NOTREACHED(); | 
 |           break; | 
 |       } | 
 |       break; | 
 |     case GL_LUMINANCE_ALPHA: | 
 |       switch (type) { | 
 |         case GL_UNSIGNED_BYTE: | 
 |           internal_format = GL_RGBA8; | 
 |           break; | 
 |         case GL_HALF_FLOAT_OES: | 
 |           internal_format = GL_RGBA16F; | 
 |           break; | 
 |         case GL_FLOAT: | 
 |           internal_format = GL_RGBA32F; | 
 |           return; | 
 |         default: | 
 |           NOTREACHED(); | 
 |           break; | 
 |       } | 
 |       break; | 
 |     default: | 
 |       internal_format = ConvertToSizedFormat(internal_format, type); | 
 |       break; | 
 |   } | 
 |  | 
 |   // Sized formats. | 
 |   switch (internal_format) { | 
 |     case GL_ALPHA8_EXT: | 
 |       *a = 8; | 
 |     case GL_ALPHA16F_EXT: | 
 |       *a = 16; | 
 |     case GL_ALPHA32F_EXT: | 
 |       *a = 32; | 
 |     case GL_RGB8_OES: | 
 |     case GL_SRGB8: | 
 |     case GL_RGB8_SNORM: | 
 |     case GL_RGB8UI: | 
 |     case GL_RGB8I: | 
 |       *r = 8; | 
 |       *g = 8; | 
 |       *b = 8; | 
 |       break; | 
 |     case GL_RGB565: | 
 |       *r = 5; | 
 |       *g = 6; | 
 |       *b = 5; | 
 |       break; | 
 |     case GL_RGB16F: | 
 |     case GL_RGB16UI: | 
 |     case GL_RGB16I: | 
 |       *r = 16; | 
 |       *g = 16; | 
 |       *b = 16; | 
 |       break; | 
 |     case GL_RGB32F: | 
 |     case GL_RGB32UI: | 
 |     case GL_RGB32I: | 
 |       *r = 32; | 
 |       *g = 32; | 
 |       *b = 32; | 
 |       break; | 
 |     case GL_R11F_G11F_B10F: | 
 |       *r = 11; | 
 |       *g = 11; | 
 |       *b = 10; | 
 |       break; | 
 |     case GL_RGB9_E5: | 
 |       *r = 9; | 
 |       *g = 9; | 
 |       *b = 9; | 
 |       break; | 
 |     case GL_BGRA8_EXT: | 
 |     case GL_RGBA8: | 
 |     case GL_SRGB8_ALPHA8: | 
 |     case GL_RGBA8_SNORM: | 
 |     case GL_RGBA8UI: | 
 |     case GL_RGBA8I: | 
 |       *r = 8; | 
 |       *g = 8; | 
 |       *b = 8; | 
 |       *a = 8; | 
 |       break; | 
 |     case GL_RGBA16F_EXT: | 
 |     case GL_RGBA16UI: | 
 |     case GL_RGBA16I: | 
 |       *r = 16; | 
 |       *g = 16; | 
 |       *b = 16; | 
 |       *a = 16; | 
 |       break; | 
 |     case GL_RGBA32F_EXT: | 
 |     case GL_RGBA32UI: | 
 |     case GL_RGBA32I: | 
 |       *r = 32; | 
 |       *g = 32; | 
 |       *b = 32; | 
 |       *a = 32; | 
 |       break; | 
 |     case GL_RGBA4: | 
 |       *r = 4; | 
 |       *g = 4; | 
 |       *b = 4; | 
 |       *a = 4; | 
 |       break; | 
 |     case GL_RGB5_A1: | 
 |       *r = 5; | 
 |       *g = 5; | 
 |       *b = 5; | 
 |       *a = 1; | 
 |       break; | 
 |     case GL_RGB10_A2: | 
 |     case GL_RGB10_A2UI: | 
 |       *r = 10; | 
 |       *g = 10; | 
 |       *b = 10; | 
 |       *a = 2; | 
 |       break; | 
 |     case GL_R8: | 
 |     case GL_R8_SNORM: | 
 |     case GL_R8UI: | 
 |     case GL_R8I: | 
 |       *r = 8; | 
 |       break; | 
 |     case GL_R16F: | 
 |     case GL_R16UI: | 
 |     case GL_R16I: | 
 |       *r = 16; | 
 |       break; | 
 |     case GL_R32F: | 
 |     case GL_R32UI: | 
 |     case GL_R32I: | 
 |       *r = 32; | 
 |       break; | 
 |     case GL_RG8: | 
 |     case GL_RG8_SNORM: | 
 |     case GL_RG8UI: | 
 |     case GL_RG8I: | 
 |       *r = 8; | 
 |       *g = 8; | 
 |       break; | 
 |     case GL_RG16F: | 
 |     case GL_RG16UI: | 
 |     case GL_RG16I: | 
 |       *r = 16; | 
 |       *g = 16; | 
 |       break; | 
 |     case GL_RG32F: | 
 |     case GL_RG32UI: | 
 |     case GL_RG32I: | 
 |       *r = 32; | 
 |       *g = 32; | 
 |       break; | 
 |     default: | 
 |       NOTREACHED(); | 
 |       break; | 
 |   } | 
 | } | 
 |  | 
 | uint32_t GLES2Util::GetChannelsNeededForAttachmentType( | 
 |     int type, | 
 |     uint32_t max_color_attachments) { | 
 |   switch (type) { | 
 |     case GL_DEPTH_ATTACHMENT: | 
 |       return kDepth; | 
 |     case GL_STENCIL_ATTACHMENT: | 
 |       return kStencil; | 
 |     default: | 
 |       if (type >= GL_COLOR_ATTACHMENT0 && | 
 |           type < static_cast<int>( | 
 |               GL_COLOR_ATTACHMENT0 + max_color_attachments)) { | 
 |         return kRGBA; | 
 |       } | 
 |       return 0x0000; | 
 |   } | 
 | } | 
 |  | 
 | std::string GLES2Util::GetStringEnum(uint32_t value) { | 
 |   const EnumToString* entry = enum_to_string_table_; | 
 |   const EnumToString* end = entry + enum_to_string_table_len_; | 
 |   for (; entry < end; ++entry) { | 
 |     if (value == entry->value) | 
 |       return entry->name; | 
 |   } | 
 |   std::stringstream ss; | 
 |   ss.fill('0'); | 
 |   ss.width(value < 0x10000 ? 4 : 8); | 
 |   ss << std::hex << value; | 
 |   return "0x" + ss.str(); | 
 | } | 
 |  | 
 | std::string GLES2Util::GetStringError(uint32_t value) { | 
 |   static EnumToString string_table[] = { | 
 |     { GL_NONE, "GL_NONE" }, | 
 |   }; | 
 |   return GLES2Util::GetQualifiedEnumString( | 
 |       string_table, arraysize(string_table), value); | 
 | } | 
 |  | 
 | std::string GLES2Util::GetStringBool(uint32_t value) { | 
 |   return value ? "GL_TRUE" : "GL_FALSE"; | 
 | } | 
 |  | 
 | std::string GLES2Util::GetQualifiedEnumString(const EnumToString* table, | 
 |                                               size_t count, | 
 |                                               uint32_t value) { | 
 |   for (const EnumToString* end = table + count; table < end; ++table) { | 
 |     if (table->value == value) { | 
 |       return table->name; | 
 |     } | 
 |   } | 
 |   return GetStringEnum(value); | 
 | } | 
 |  | 
 | GLSLArrayName::GLSLArrayName(const std::string& name) : element_index_(-1) { | 
 |   if (name.size() < 4) | 
 |     return; | 
 |   if (name.back() != ']') | 
 |     return; | 
 |  | 
 |   size_t open_pos = name.find_last_of('['); | 
 |   if (open_pos >= name.size() - 2) | 
 |     return; | 
 |  | 
 |   base::CheckedNumeric<int> index = 0; | 
 |   size_t last = name.size() - 1; | 
 |   for (size_t pos = open_pos + 1; pos < last; ++pos) { | 
 |     int8_t digit = name[pos] - '0'; | 
 |     if (digit < 0 || digit > 9) | 
 |       return; | 
 |     index = index * 10 + digit; | 
 |   } | 
 |   if (!index.IsValid()) | 
 |     return; | 
 |   element_index_ = index.ValueOrDie(); | 
 |   base_name_ = name.substr(0, open_pos); | 
 | } | 
 |  | 
 | size_t GLES2Util::CalcClearBufferivDataCount(int buffer) { | 
 |   switch (buffer) { | 
 |     case GL_COLOR: | 
 |       return 4; | 
 |     case GL_STENCIL: | 
 |       return 1; | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | size_t GLES2Util::CalcClearBufferfvDataCount(int buffer) { | 
 |   switch (buffer) { | 
 |     case GL_COLOR: | 
 |       return 4; | 
 |     case GL_DEPTH: | 
 |       return 1; | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | // static | 
 | void GLES2Util::MapUint64ToTwoUint32( | 
 |     uint64_t v64, uint32_t* v32_0, uint32_t* v32_1) { | 
 |   DCHECK(v32_0 && v32_1); | 
 |   *v32_0 = static_cast<uint32_t>(v64 & 0xFFFFFFFF); | 
 |   *v32_1 = static_cast<uint32_t>((v64 & 0xFFFFFFFF00000000) >> 32); | 
 | } | 
 |  | 
 | // static | 
 | uint64_t GLES2Util::MapTwoUint32ToUint64(uint32_t v32_0, uint32_t v32_1) { | 
 |   uint64_t v64 = v32_1; | 
 |   return (v64 << 32) | v32_0; | 
 | } | 
 |  | 
 | // static | 
 | uint32_t GLES2Util::MapBufferTargetToBindingEnum(uint32_t target) { | 
 |   switch (target) { | 
 |     case GL_ARRAY_BUFFER: | 
 |       return GL_ARRAY_BUFFER_BINDING; | 
 |     case GL_COPY_READ_BUFFER: | 
 |       return GL_COPY_READ_BUFFER_BINDING; | 
 |     case GL_COPY_WRITE_BUFFER: | 
 |       return GL_COPY_WRITE_BUFFER_BINDING; | 
 |     case GL_ELEMENT_ARRAY_BUFFER: | 
 |       return GL_ELEMENT_ARRAY_BUFFER_BINDING; | 
 |     case GL_PIXEL_PACK_BUFFER: | 
 |       return GL_PIXEL_PACK_BUFFER_BINDING; | 
 |     case GL_PIXEL_UNPACK_BUFFER: | 
 |       return GL_PIXEL_UNPACK_BUFFER_BINDING; | 
 |     case GL_TRANSFORM_FEEDBACK_BUFFER: | 
 |       return GL_TRANSFORM_FEEDBACK_BUFFER_BINDING; | 
 |     case GL_UNIFORM_BUFFER: | 
 |       return GL_UNIFORM_BUFFER_BINDING; | 
 |     default: | 
 |       return 0; | 
 |   } | 
 | } | 
 |  | 
 | // static | 
 | bool GLES2Util::IsUnsignedIntegerFormat(uint32_t internal_format) { | 
 |   switch (internal_format) { | 
 |     case GL_R8UI: | 
 |     case GL_R16UI: | 
 |     case GL_R32UI: | 
 |     case GL_RG8UI: | 
 |     case GL_RG16UI: | 
 |     case GL_RG32UI: | 
 |     case GL_RGB8UI: | 
 |     case GL_RGB16UI: | 
 |     case GL_RGB32UI: | 
 |     case GL_RGBA8UI: | 
 |     case GL_RGB10_A2UI: | 
 |     case GL_RGBA16UI: | 
 |     case GL_RGBA32UI: | 
 |       return true; | 
 |     default: | 
 |       return false; | 
 |   } | 
 | } | 
 |  | 
 | // static | 
 | bool GLES2Util::IsSignedIntegerFormat(uint32_t internal_format) { | 
 |   switch (internal_format) { | 
 |     case GL_R8I: | 
 |     case GL_R16I: | 
 |     case GL_R32I: | 
 |     case GL_RG8I: | 
 |     case GL_RG16I: | 
 |     case GL_RG32I: | 
 |     case GL_RGB8I: | 
 |     case GL_RGB16I: | 
 |     case GL_RGB32I: | 
 |     case GL_RGBA8I: | 
 |     case GL_RGBA16I: | 
 |     case GL_RGBA32I: | 
 |       return true; | 
 |     default: | 
 |       return false; | 
 |   } | 
 | } | 
 |  | 
 | // static | 
 | bool GLES2Util::IsIntegerFormat(uint32_t internal_format) { | 
 |   return (IsUnsignedIntegerFormat(internal_format) || | 
 |           IsSignedIntegerFormat(internal_format)); | 
 | } | 
 |  | 
 | // static | 
 | bool GLES2Util::IsFloatFormat(uint32_t internal_format) { | 
 |   switch (internal_format) { | 
 |     case GL_R16F: | 
 |     case GL_R32F: | 
 |     case GL_RG16F: | 
 |     case GL_RG32F: | 
 |     case GL_R11F_G11F_B10F: | 
 |     case GL_RGB16F: | 
 |     case GL_RGB32F: | 
 |     case GL_RGBA16F: | 
 |     case GL_RGBA32F: | 
 |       return true; | 
 |     default: | 
 |       return false; | 
 |   } | 
 | } | 
 |  | 
 | // static | 
 | uint32_t GLES2Util::ConvertToSizedFormat(uint32_t format, uint32_t type) { | 
 |   switch (format) { | 
 |     case GL_RGB: | 
 |       switch (type) { | 
 |         case GL_UNSIGNED_BYTE: | 
 |           return GL_RGB8; | 
 |         case GL_UNSIGNED_SHORT_5_6_5: | 
 |           return GL_RGB565; | 
 |         case GL_HALF_FLOAT_OES: | 
 |           return GL_RGB16F; | 
 |         case GL_FLOAT: | 
 |           return GL_RGB32F; | 
 |         default: | 
 |           NOTREACHED(); | 
 |           break; | 
 |       } | 
 |       break; | 
 |     case GL_RGBA: | 
 |       switch (type) { | 
 |         case GL_UNSIGNED_BYTE: | 
 |           return GL_RGBA8; | 
 |         case GL_UNSIGNED_SHORT_4_4_4_4: | 
 |           return GL_RGBA4; | 
 |         case GL_UNSIGNED_SHORT_5_5_5_1: | 
 |           return GL_RGB5_A1; | 
 |         case GL_HALF_FLOAT_OES: | 
 |           return GL_RGBA16F; | 
 |         case GL_FLOAT: | 
 |           return GL_RGBA32F; | 
 |         default: | 
 |           NOTREACHED(); | 
 |           break; | 
 |       } | 
 |       break; | 
 |     case GL_ALPHA: | 
 |       switch (type) { | 
 |         case GL_UNSIGNED_BYTE: | 
 |           return GL_ALPHA8_EXT; | 
 |         case GL_HALF_FLOAT_OES: | 
 |           return GL_ALPHA16F_EXT; | 
 |         case GL_FLOAT: | 
 |           return GL_ALPHA32F_EXT; | 
 |         default: | 
 |           NOTREACHED(); | 
 |           break; | 
 |       } | 
 |       break; | 
 |     case GL_RED: | 
 |       switch (type) { | 
 |         case GL_UNSIGNED_BYTE: | 
 |           return GL_R8; | 
 |         case GL_HALF_FLOAT_OES: | 
 |           return GL_R16F; | 
 |         case GL_FLOAT: | 
 |           return GL_R32F; | 
 |         default: | 
 |           NOTREACHED(); | 
 |           break; | 
 |       } | 
 |       break; | 
 |     case GL_RG: | 
 |       switch (type) { | 
 |         case GL_UNSIGNED_BYTE: | 
 |           return GL_RG8; | 
 |         case GL_HALF_FLOAT_OES: | 
 |           return GL_RG16F; | 
 |         case GL_FLOAT: | 
 |           return GL_RG32F; | 
 |         default: | 
 |           NOTREACHED(); | 
 |           break; | 
 |       } | 
 |       break; | 
 |     case GL_SRGB_EXT: | 
 |       switch (type) { | 
 |         case GL_UNSIGNED_BYTE: | 
 |           return GL_SRGB8; | 
 |         default: | 
 |           NOTREACHED(); | 
 |           break; | 
 |       } | 
 |       break; | 
 |     case GL_SRGB_ALPHA_EXT: | 
 |       switch (type) { | 
 |         case GL_UNSIGNED_BYTE: | 
 |           return GL_SRGB8_ALPHA8; | 
 |         default: | 
 |           NOTREACHED(); | 
 |           break; | 
 |       } | 
 |       break; | 
 |     case GL_BGRA_EXT: | 
 |       switch (type) { | 
 |         case GL_UNSIGNED_BYTE: | 
 |           return GL_BGRA8_EXT; | 
 |         default: | 
 |           NOTREACHED(); | 
 |           break; | 
 |       } | 
 |       break; | 
 |     default: | 
 |       break; | 
 |   } | 
 |  | 
 |   return format; | 
 | } | 
 |  | 
 | // static | 
 | bool GLES2Util::ComputeDataSize(uint32_t count, | 
 |                                 size_t size, | 
 |                                 unsigned int elements_per_unit, | 
 |                                 uint32_t* dst) { | 
 |   uint32_t value; | 
 |   if (!SafeMultiplyUint32(count, static_cast<uint32_t>(size), &value)) { | 
 |     return false; | 
 |   } | 
 |   if (!SafeMultiplyUint32(value, elements_per_unit, &value)) { | 
 |     return false; | 
 |   } | 
 |   *dst = value; | 
 |   return true; | 
 | } | 
 |  | 
 | namespace { | 
 |  | 
 | // GL context configuration attributes. Those in the 16-bit range are the same | 
 | // as used by EGL. Those outside the 16-bit range are unique to Chromium. | 
 | // Attributes are matched using a closest fit algorithm. | 
 |  | 
 | // From <EGL/egl.h>. | 
 | #include <stddef.h> | 
 | #include <stdint.h> | 
 | const int32_t kAlphaSize = 0x3021;        // EGL_ALPHA_SIZE | 
 | const int32_t kBlueSize = 0x3022;         // EGL_BLUE_SIZE | 
 | const int32_t kGreenSize = 0x3023;        // EGL_GREEN_SIZE | 
 | const int32_t kRedSize = 0x3024;          // EGL_RED_SIZE | 
 | const int32_t kDepthSize = 0x3025;        // EGL_DEPTH_SIZE | 
 | const int32_t kStencilSize = 0x3026;      // EGL_STENCIL_SIZE | 
 | const int32_t kSamples = 0x3031;          // EGL_SAMPLES | 
 | const int32_t kSampleBuffers = 0x3032;    // EGL_SAMPLE_BUFFERS | 
 | const int32_t kNone = 0x3038;             // EGL_NONE | 
 | const int32_t kSwapBehavior = 0x3093;     // EGL_SWAP_BEHAVIOR | 
 | const int32_t kBufferPreserved = 0x3094;  // EGL_BUFFER_PRESERVED | 
 |  | 
 | // Chromium only. | 
 | const int32_t kBindGeneratesResource = 0x10000; | 
 | const int32_t kFailIfMajorPerfCaveat = 0x10001; | 
 | const int32_t kLoseContextWhenOutOfMemory = 0x10002; | 
 | const int32_t kShouldUseNativeGMBForBackbuffer = 0x10003; | 
 | const int32_t kContextType = 0x10004; | 
 |  | 
 | }  // namespace | 
 |  | 
 | bool IsWebGLContextType(ContextType context_type) { | 
 |   // Switch statement to cause a compile-time error if we miss a case. | 
 |   switch (context_type) { | 
 |     case CONTEXT_TYPE_WEBGL1: | 
 |     case CONTEXT_TYPE_WEBGL2: | 
 |       return true; | 
 |     case CONTEXT_TYPE_OPENGLES2: | 
 |     case CONTEXT_TYPE_OPENGLES3: | 
 |       return false; | 
 |   } | 
 |  | 
 |   NOTREACHED(); | 
 |   return false; | 
 | } | 
 |  | 
 | ContextCreationAttribHelper::ContextCreationAttribHelper() | 
 |     : gpu_preference(gl::PreferIntegratedGpu), | 
 |       alpha_size(-1), | 
 |       blue_size(-1), | 
 |       green_size(-1), | 
 |       red_size(-1), | 
 |       depth_size(-1), | 
 |       stencil_size(-1), | 
 |       samples(-1), | 
 |       sample_buffers(-1), | 
 |       buffer_preserved(true), | 
 |       bind_generates_resource(true), | 
 |       fail_if_major_perf_caveat(false), | 
 |       lose_context_when_out_of_memory(false), | 
 |       should_use_native_gmb_for_backbuffer(false), | 
 |       context_type(CONTEXT_TYPE_OPENGLES2) {} | 
 |  | 
 | ContextCreationAttribHelper::ContextCreationAttribHelper( | 
 |     const ContextCreationAttribHelper& other) = default; | 
 |  | 
 | bool ContextCreationAttribHelper::Parse(const std::vector<int32_t>& attribs) { | 
 |   for (size_t i = 0; i < attribs.size(); i += 2) { | 
 |     const int32_t attrib = attribs[i]; | 
 |     if (i + 1 >= attribs.size()) { | 
 |       if (attrib == kNone) { | 
 |         return true; | 
 |       } | 
 |  | 
 |       DLOG(ERROR) << "Missing value after context creation attribute: " | 
 |                   << attrib; | 
 |       return false; | 
 |     } | 
 |  | 
 |     const int32_t value = attribs[i + 1]; | 
 |     switch (attrib) { | 
 |       case kAlphaSize: | 
 |         alpha_size = value; | 
 |         break; | 
 |       case kBlueSize: | 
 |         blue_size = value; | 
 |         break; | 
 |       case kGreenSize: | 
 |         green_size = value; | 
 |         break; | 
 |       case kRedSize: | 
 |         red_size = value; | 
 |         break; | 
 |       case kDepthSize: | 
 |         depth_size = value; | 
 |         break; | 
 |       case kStencilSize: | 
 |         stencil_size = value; | 
 |         break; | 
 |       case kSamples: | 
 |         samples = value; | 
 |         break; | 
 |       case kSampleBuffers: | 
 |         sample_buffers = value; | 
 |         break; | 
 |       case kSwapBehavior: | 
 |         buffer_preserved = value == kBufferPreserved; | 
 |         break; | 
 |       case kBindGeneratesResource: | 
 |         bind_generates_resource = value != 0; | 
 |         break; | 
 |       case kFailIfMajorPerfCaveat: | 
 |         fail_if_major_perf_caveat = value != 0; | 
 |         break; | 
 |       case kLoseContextWhenOutOfMemory: | 
 |         lose_context_when_out_of_memory = value != 0; | 
 |         break; | 
 |       case kShouldUseNativeGMBForBackbuffer: | 
 |         should_use_native_gmb_for_backbuffer = value != 0; | 
 |         break; | 
 |       case kContextType: | 
 |         context_type = static_cast<ContextType>(value); | 
 |         break; | 
 |       case kNone: | 
 |         // Terminate list, even if more attributes. | 
 |         return true; | 
 |       default: | 
 |         DLOG(ERROR) << "Invalid context creation attribute: " << attrib; | 
 |         return false; | 
 |     } | 
 |   } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | #include "gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h" | 
 |  | 
 | }  // namespace gles2 | 
 | }  // namespace gpu |