diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-06-18 14:10:49 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2015-06-18 13:53:24 +0000 |
commit | 813fbf95af77a531c57a8c497345ad2c61d475b3 (patch) | |
tree | 821b2c8de8365f21b6c9ba17a236fb3006a1d506 /chromium/gpu/command_buffer | |
parent | af6588f8d723931a298c995fa97259bb7f7deb55 (diff) | |
download | qtwebengine-chromium-813fbf95af77a531c57a8c497345ad2c61d475b3.tar.gz |
BASELINE: Update chromium to 44.0.2403.47
Change-Id: Ie056fedba95cf5e5c76b30c4b2c80fca4764aa2f
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/gpu/command_buffer')
208 files changed, 40297 insertions, 8364 deletions
diff --git a/chromium/gpu/command_buffer/OWNERS b/chromium/gpu/command_buffer/OWNERS index cd07f4dafa3..16b05676ea4 100644 --- a/chromium/gpu/command_buffer/OWNERS +++ b/chromium/gpu/command_buffer/OWNERS @@ -3,3 +3,7 @@ jbauman@chromium.org bajones@chromium.org zmo@chromium.org vmiura@chromium.org + +# GPU memory buffer tests. +per-file *gpu_memory_buffer*=reveman@chromium.org + diff --git a/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py b/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py index 8d7332ffa6b..8ababfe5cb0 100755 --- a/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -10,6 +10,7 @@ import os import os.path import sys import re +import platform from optparse import OptionParser from subprocess import call @@ -81,6 +82,8 @@ _CAPABILITY_FLAGS = [ {'name': 'scissor_test'}, {'name': 'stencil_test', 'state_flag': 'framebuffer_state_.clear_state_dirty'}, + {'name': 'rasterizer_discard', 'es3': True}, + {'name': 'primitive_restart_fixed_index', 'es3': True}, ] _STATES = { @@ -384,7 +387,8 @@ _STATES = { 'name': 'hint_generate_mipmap', 'type': 'GLenum', 'enum': 'GL_GENERATE_MIPMAP_HINT', - 'default': 'GL_DONT_CARE' + 'default': 'GL_DONT_CARE', + 'gl_version_flag': '!is_desktop_core_profile' }, { 'name': 'hint_fragment_shader_derivative', @@ -543,8 +547,11 @@ _STATES = { # named types are used in 'cmd_buffer_functions.txt'. # type: The actual GL type of the named type. # valid: The list of values that are valid for both the client and the service. +# valid_es3: The list of values that are valid in OpenGL ES 3, but not ES 2. # invalid: Examples of invalid values for the type. At least these values # should be tested to be invalid. +# deprecated_es3: The list of values that are valid in OpenGL ES 2, but +# deprecated in ES 3. # is_complete: The list of valid values of type are final and will not be # modified during runtime. _NAMED_TYPE_INFO = { @@ -563,6 +570,19 @@ _NAMED_TYPE_INFO = { 'valid': [ 'GL_FRAMEBUFFER', ], + 'valid_es3': [ + 'GL_DRAW_FRAMEBUFFER' , + 'GL_READ_FRAMEBUFFER' , + ], + 'invalid': [ + 'GL_RENDERBUFFER', + ], + }, + 'InvalidateFrameBufferTarget': { + 'type': 'GLenum', + 'valid': [ + 'GL_FRAMEBUFFER', + ], 'invalid': [ 'GL_DRAW_FRAMEBUFFER' , 'GL_READ_FRAMEBUFFER' , @@ -583,6 +603,76 @@ _NAMED_TYPE_INFO = { 'GL_ARRAY_BUFFER', 'GL_ELEMENT_ARRAY_BUFFER', ], + 'valid_es3': [ + 'GL_COPY_READ_BUFFER', + 'GL_COPY_WRITE_BUFFER', + 'GL_PIXEL_PACK_BUFFER', + 'GL_PIXEL_UNPACK_BUFFER', + 'GL_TRANSFORM_FEEDBACK_BUFFER', + 'GL_UNIFORM_BUFFER', + ], + 'invalid': [ + 'GL_RENDERBUFFER', + ], + }, + 'IndexedBufferTarget': { + 'type': 'GLenum', + 'valid': [ + 'GL_TRANSFORM_FEEDBACK_BUFFER', + 'GL_UNIFORM_BUFFER', + ], + 'invalid': [ + 'GL_RENDERBUFFER', + ], + }, + 'MapBufferAccess': { + 'type': 'GLenum', + 'valid': [ + 'GL_MAP_READ_BIT', + 'GL_MAP_WRITE_BIT', + 'GL_MAP_INVALIDATE_RANGE_BIT', + 'GL_MAP_INVALIDATE_BUFFER_BIT', + 'GL_MAP_FLUSH_EXPLICIT_BIT', + 'GL_MAP_UNSYNCHRONIZED_BIT', + ], + 'invalid': [ + 'GL_SYNC_FLUSH_COMMANDS_BIT', + ], + }, + 'Bufferiv': { + 'type': 'GLenum', + 'valid': [ + 'GL_COLOR', + 'GL_STENCIL', + ], + 'invalid': [ + 'GL_RENDERBUFFER', + ], + }, + 'Bufferuiv': { + 'type': 'GLenum', + 'valid': [ + 'GL_COLOR', + ], + 'invalid': [ + 'GL_RENDERBUFFER', + ], + }, + 'Bufferfv': { + 'type': 'GLenum', + 'valid': [ + 'GL_COLOR', + 'GL_DEPTH', + ], + 'invalid': [ + 'GL_RENDERBUFFER', + ], + }, + 'Bufferfi': { + 'type': 'GLenum', + 'valid': [ + 'GL_DEPTH_STENCIL', + ], 'invalid': [ 'GL_RENDERBUFFER', ], @@ -594,14 +684,34 @@ _NAMED_TYPE_INFO = { 'GL_STATIC_DRAW', 'GL_DYNAMIC_DRAW', ], - 'invalid': [ + 'valid_es3': [ + 'GL_STREAM_READ', + 'GL_STREAM_COPY', 'GL_STATIC_READ', + 'GL_STATIC_COPY', + 'GL_DYNAMIC_READ', + 'GL_DYNAMIC_COPY', + ], + 'invalid': [ + 'GL_NONE', ], }, 'CompressedTextureFormat': { 'type': 'GLenum', 'valid': [ ], + 'valid_es3': [ + 'GL_COMPRESSED_R11_EAC', + 'GL_COMPRESSED_SIGNED_R11_EAC', + 'GL_COMPRESSED_RG11_EAC', + 'GL_COMPRESSED_SIGNED_RG11_EAC', + 'GL_COMPRESSED_RGB8_ETC2', + 'GL_COMPRESSED_SRGB8_ETC2', + 'GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2', + 'GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2', + 'GL_COMPRESSED_RGBA8_ETC2_EAC', + 'GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC', + ], }, 'GLState': { 'type': 'GLenum', @@ -659,6 +769,101 @@ _NAMED_TYPE_INFO = { 'GL_VERTEX_ARRAY_BINDING_OES', 'GL_VIEWPORT', ], + 'valid_es3': [ + 'GL_COPY_READ_BUFFER_BINDING', + 'GL_COPY_WRITE_BUFFER_BINDING', + 'GL_DRAW_BUFFER0', + 'GL_DRAW_BUFFER1', + 'GL_DRAW_BUFFER2', + 'GL_DRAW_BUFFER3', + 'GL_DRAW_BUFFER4', + 'GL_DRAW_BUFFER5', + 'GL_DRAW_BUFFER6', + 'GL_DRAW_BUFFER7', + 'GL_DRAW_BUFFER8', + 'GL_DRAW_BUFFER9', + 'GL_DRAW_BUFFER10', + 'GL_DRAW_BUFFER11', + 'GL_DRAW_BUFFER12', + 'GL_DRAW_BUFFER13', + 'GL_DRAW_BUFFER14', + 'GL_DRAW_BUFFER15', + 'GL_DRAW_FRAMEBUFFER_BINDING', + 'GL_FRAGMENT_SHADER_DERIVATIVE_HINT', + 'GL_MAJOR_VERSION', + 'GL_MAX_3D_TEXTURE_SIZE', + 'GL_MAX_ARRAY_TEXTURE_LAYERS', + 'GL_MAX_COLOR_ATTACHMENTS', + 'GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS', + 'GL_MAX_COMBINED_UNIFORM_BLOCKS', + 'GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS', + 'GL_MAX_DRAW_BUFFERS', + 'GL_MAX_ELEMENT_INDEX', + 'GL_MAX_ELEMENTS_INDICES', + 'GL_MAX_ELEMENTS_VERTICES', + 'GL_MAX_FRAGMENT_INPUT_COMPONENTS', + 'GL_MAX_FRAGMENT_UNIFORM_BLOCKS', + 'GL_MAX_FRAGMENT_UNIFORM_COMPONENTS', + 'GL_MAX_PROGRAM_TEXEL_OFFSET', + 'GL_MAX_SAMPLES', + 'GL_MAX_SERVER_WAIT_TIMEOUT', + 'GL_MAX_TEXTURE_LOD_BIAS', + 'GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS', + 'GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS', + 'GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS', + 'GL_MAX_UNIFORM_BLOCK_SIZE', + 'GL_MAX_UNIFORM_BUFFER_BINDINGS', + 'GL_MAX_VARYING_COMPONENTS', + 'GL_MAX_VERTEX_OUTPUT_COMPONENTS', + 'GL_MAX_VERTEX_UNIFORM_BLOCKS', + 'GL_MAX_VERTEX_UNIFORM_COMPONENTS', + 'GL_MIN_PROGRAM_TEXEL_OFFSET', + 'GL_MINOR_VERSION', + 'GL_NUM_EXTENSIONS', + 'GL_NUM_PROGRAM_BINARY_FORMATS', + 'GL_PACK_ROW_LENGTH', + 'GL_PACK_SKIP_PIXELS', + 'GL_PACK_SKIP_ROWS', + 'GL_PIXEL_PACK_BUFFER_BINDING', + 'GL_PIXEL_UNPACK_BUFFER_BINDING', + 'GL_PROGRAM_BINARY_FORMATS', + 'GL_READ_BUFFER', + 'GL_READ_FRAMEBUFFER_BINDING', + 'GL_SAMPLER_BINDING', + 'GL_TEXTURE_BINDING_2D_ARRAY', + 'GL_TEXTURE_BINDING_3D', + 'GL_TRANSFORM_FEEDBACK_BINDING', + 'GL_TRANSFORM_FEEDBACK_ACTIVE', + 'GL_TRANSFORM_FEEDBACK_BUFFER_BINDING', + 'GL_TRANSFORM_FEEDBACK_PAUSED', + 'GL_TRANSFORM_FEEDBACK_BUFFER_SIZE', + 'GL_TRANSFORM_FEEDBACK_BUFFER_START', + 'GL_UNIFORM_BUFFER_BINDING', + 'GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT', + 'GL_UNIFORM_BUFFER_SIZE', + 'GL_UNIFORM_BUFFER_START', + 'GL_UNPACK_IMAGE_HEIGHT', + 'GL_UNPACK_ROW_LENGTH', + 'GL_UNPACK_SKIP_IMAGES', + 'GL_UNPACK_SKIP_PIXELS', + 'GL_UNPACK_SKIP_ROWS', + # GL_VERTEX_ARRAY_BINDING is the same as GL_VERTEX_ARRAY_BINDING_OES + # 'GL_VERTEX_ARRAY_BINDING', + ], + 'invalid': [ + 'GL_FOG_HINT', + ], + }, + 'IndexedGLState': { + 'type': 'GLenum', + 'valid': [ + 'GL_TRANSFORM_FEEDBACK_BUFFER_BINDING', + 'GL_TRANSFORM_FEEDBACK_BUFFER_SIZE', + 'GL_TRANSFORM_FEEDBACK_BUFFER_START', + 'GL_UNIFORM_BUFFER_BINDING', + 'GL_UNIFORM_BUFFER_SIZE', + 'GL_UNIFORM_BUFFER_START', + ], 'invalid': [ 'GL_FOG_HINT', ], @@ -669,6 +874,10 @@ _NAMED_TYPE_INFO = { 'GL_TEXTURE_2D', 'GL_TEXTURE_CUBE_MAP', ], + 'valid_es3': [ + 'GL_TEXTURE_2D_ARRAY', + 'GL_TEXTURE_3D', + ], 'invalid': [ 'GL_PROXY_TEXTURE_CUBE_MAP', ] @@ -688,17 +897,51 @@ _NAMED_TYPE_INFO = { 'GL_PROXY_TEXTURE_CUBE_MAP', ] }, + 'Texture3DTarget': { + 'type': 'GLenum', + 'valid': [ + 'GL_TEXTURE_3D', + 'GL_TEXTURE_2D_ARRAY', + ], + 'invalid': [ + 'GL_TEXTURE_2D', + ] + }, 'TextureBindTarget': { 'type': 'GLenum', 'valid': [ 'GL_TEXTURE_2D', 'GL_TEXTURE_CUBE_MAP', ], + 'valid_es3': [ + 'GL_TEXTURE_3D', + 'GL_TEXTURE_2D_ARRAY', + ], 'invalid': [ 'GL_TEXTURE_1D', 'GL_TEXTURE_3D', ], }, + 'TransformFeedbackBindTarget': { + 'type': 'GLenum', + 'valid': [ + 'GL_TRANSFORM_FEEDBACK', + ], + 'invalid': [ + 'GL_TEXTURE_2D', + ], + }, + 'TransformFeedbackPrimitiveMode': { + 'type': 'GLenum', + 'valid': [ + 'GL_POINTS', + 'GL_LINES', + 'GL_TRIANGLES', + ], + 'invalid': [ + 'GL_LINE_LOOP', + ], + }, 'ShaderType': { 'type': 'GLenum', 'valid': [ @@ -744,10 +987,13 @@ _NAMED_TYPE_INFO = { 'GL_FUNC_SUBTRACT', 'GL_FUNC_REVERSE_SUBTRACT', ], - 'invalid': [ + 'valid_es3': [ 'GL_MIN', 'GL_MAX', ], + 'invalid': [ + 'GL_NONE', + ], }, 'SrcBlendFactor': { 'type': 'GLenum', @@ -790,7 +1036,10 @@ _NAMED_TYPE_INFO = { }, 'Capability': { 'type': 'GLenum', - 'valid': ["GL_%s" % cap['name'].upper() for cap in _CAPABILITY_FLAGS], + 'valid': ["GL_%s" % cap['name'].upper() for cap in _CAPABILITY_FLAGS + if 'es3' not in cap or cap['es3'] != True], + 'valid_es3': ["GL_%s" % cap['name'].upper() for cap in _CAPABILITY_FLAGS + if 'es3' in cap and cap['es3'] == True], 'invalid': [ 'GL_CLIP_PLANE0', 'GL_POINT_SPRITE', @@ -818,8 +1067,10 @@ _NAMED_TYPE_INFO = { 'GL_UNSIGNED_BYTE', 'GL_UNSIGNED_SHORT', ], - 'invalid': [ + 'valid_es3': [ 'GL_UNSIGNED_INT', + ], + 'invalid': [ 'GL_INT', ], }, @@ -841,6 +1092,9 @@ _NAMED_TYPE_INFO = { 'GL_DEPTH_ATTACHMENT', 'GL_STENCIL_ATTACHMENT', ], + 'valid_es3': [ + 'GL_DEPTH_STENCIL_ATTACHMENT', + ], }, 'BackbufferAttachment': { 'type': 'GLenum', @@ -856,6 +1110,22 @@ _NAMED_TYPE_INFO = { 'GL_BUFFER_SIZE', 'GL_BUFFER_USAGE', ], + 'valid_es3': [ + 'GL_BUFFER_ACCESS_FLAGS', + 'GL_BUFFER_MAPPED', + 'GL_BUFFER_MAP_LENGTH', + 'GL_BUFFER_MAP_OFFSET', + ], + 'invalid': [ + 'GL_PIXEL_PACK_BUFFER', + ], + }, + 'BufferMode': { + 'type': 'GLenum', + 'valid': [ + 'GL_INTERLEAVED_ATTRIBS', + 'GL_SEPARATE_ATTRIBS', + ], 'invalid': [ 'GL_PIXEL_PACK_BUFFER', ], @@ -868,6 +1138,17 @@ _NAMED_TYPE_INFO = { 'GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL', 'GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE', ], + 'valid_es3': [ + 'GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE', + 'GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE', + 'GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE', + 'GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE', + 'GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE', + 'GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE', + 'GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE', + 'GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING', + 'GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER', + ], }, 'MatrixMode': { 'type': 'GLenum', @@ -889,6 +1170,16 @@ _NAMED_TYPE_INFO = { 'GL_ACTIVE_UNIFORMS', 'GL_ACTIVE_UNIFORM_MAX_LENGTH', ], + 'valid_es3': [ + 'GL_ACTIVE_UNIFORM_BLOCKS', + 'GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH', + 'GL_TRANSFORM_FEEDBACK_BUFFER_MODE', + 'GL_TRANSFORM_FEEDBACK_VARYINGS', + 'GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH', + ], + 'invalid': [ + 'GL_PROGRAM_BINARY_RETRIEVABLE_HINT', # not supported in Chromium. + ], }, 'QueryObjectParameter': { 'type': 'GLenum', @@ -928,6 +1219,33 @@ _NAMED_TYPE_INFO = { 'GL_RENDERBUFFER_HEIGHT', 'GL_RENDERBUFFER_INTERNAL_FORMAT', ], + 'valid_es3': [ + 'GL_RENDERBUFFER_SAMPLES', + ], + }, + 'InternalFormatParameter': { + 'type': 'GLenum', + 'valid': [ + 'GL_NUM_SAMPLE_COUNTS', + 'GL_SAMPLES', + ], + }, + 'SamplerParameter': { + 'type': 'GLenum', + 'valid': [ + 'GL_TEXTURE_MAG_FILTER', + 'GL_TEXTURE_MIN_FILTER', + 'GL_TEXTURE_MIN_LOD', + 'GL_TEXTURE_MAX_LOD', + 'GL_TEXTURE_WRAP_S', + 'GL_TEXTURE_WRAP_T', + 'GL_TEXTURE_WRAP_R', + 'GL_TEXTURE_COMPARE_MODE', + 'GL_TEXTURE_COMPARE_FUNC', + ], + 'invalid': [ + 'GL_GENERATE_MIPMAP', + ], }, 'ShaderParameter': { 'type': 'GLenum', @@ -970,6 +1288,17 @@ _NAMED_TYPE_INFO = { 'GL_TEXTURE_WRAP_S', 'GL_TEXTURE_WRAP_T', ], + 'valid_es3': [ + 'GL_TEXTURE_BASE_LEVEL', + 'GL_TEXTURE_COMPARE_FUNC', + 'GL_TEXTURE_COMPARE_MODE', + 'GL_TEXTURE_IMMUTABLE_FORMAT', + 'GL_TEXTURE_IMMUTABLE_LEVELS', + 'GL_TEXTURE_MAX_LEVEL', + 'GL_TEXTURE_MAX_LOD', + 'GL_TEXTURE_MIN_LOD', + 'GL_TEXTURE_WRAP_R', + ], 'invalid': [ 'GL_GENERATE_MIPMAP', ], @@ -1007,6 +1336,26 @@ _NAMED_TYPE_INFO = { 'GL_LINEAR', ], }, + 'TextureCompareFunc': { + 'type': 'GLenum', + 'valid': [ + 'GL_LEQUAL', + 'GL_GEQUAL', + 'GL_LESS', + 'GL_GREATER', + 'GL_EQUAL', + 'GL_NOTEQUAL', + 'GL_ALWAYS', + 'GL_NEVER', + ], + }, + 'TextureCompareMode': { + 'type': 'GLenum', + 'valid': [ + 'GL_NONE', + 'GL_COMPARE_REF_TO_TEXTURE', + ], + }, 'TextureUsage': { 'type': 'GLenum', 'valid': [ @@ -1027,6 +1376,10 @@ _NAMED_TYPE_INFO = { 'GL_VERTEX_ATTRIB_ARRAY_TYPE', 'GL_CURRENT_VERTEX_ATTRIB', ], + 'valid_es3': [ + 'GL_VERTEX_ATTRIB_ARRAY_INTEGER', + 'GL_VERTEX_ATTRIB_ARRAY_DIVISOR', + ], }, 'VertexPointer': { 'type': 'GLenum', @@ -1039,6 +1392,9 @@ _NAMED_TYPE_INFO = { 'valid': [ 'GL_GENERATE_MIPMAP_HINT', ], + 'valid_es3': [ + 'GL_FRAGMENT_SHADER_DERIVATIVE_HINT', + ], 'invalid': [ 'GL_PERSPECTIVE_CORRECTION_HINT', ], @@ -1060,6 +1416,16 @@ _NAMED_TYPE_INFO = { 'GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM', 'GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM', ], + 'valid_es3': [ + 'GL_PACK_ROW_LENGTH', + 'GL_PACK_SKIP_PIXELS', + 'GL_PACK_SKIP_ROWS', + 'GL_UNPACK_ROW_LENGTH', + 'GL_UNPACK_IMAGE_HEIGHT', + 'GL_UNPACK_SKIP_PIXELS', + 'GL_UNPACK_SKIP_ROWS', + 'GL_UNPACK_SKIP_IMAGES', + ], 'invalid': [ 'GL_PACK_SWAP_BYTES', 'GL_UNPACK_SWAP_BYTES', @@ -1085,6 +1451,13 @@ _NAMED_TYPE_INFO = { 'GL_RGB', 'GL_RGBA', ], + 'valid_es3': [ + 'GL_RGBA_INTEGER', + ], + 'deprecated_es3': [ + 'GL_ALPHA', + 'GL_RGB', + ], }, 'PixelType': { 'type': 'GLenum', @@ -1094,9 +1467,22 @@ _NAMED_TYPE_INFO = { 'GL_UNSIGNED_SHORT_4_4_4_4', 'GL_UNSIGNED_SHORT_5_5_5_1', ], - 'invalid': [ + 'valid_es3': [ + 'GL_BYTE', + 'GL_UNSIGNED_SHORT', 'GL_SHORT', + 'GL_UNSIGNED_INT', 'GL_INT', + 'GL_HALF_FLOAT', + 'GL_FLOAT', + 'GL_UNSIGNED_INT_2_10_10_10_REV', + 'GL_UNSIGNED_INT_10F_11F_11F_REV', + 'GL_UNSIGNED_INT_5_9_9_9_REV', + 'GL_UNSIGNED_INT_24_8', + 'GL_FLOAT_32_UNSIGNED_INT_24_8_REV', + ], + 'invalid': [ + 'GL_UNSIGNED_BYTE_3_3_2', ], }, 'ReadPixelType': { @@ -1109,7 +1495,16 @@ _NAMED_TYPE_INFO = { ], 'invalid': [ 'GL_SHORT', + ], + 'valid_es3': [ + 'GL_UNSIGNED_INT', 'GL_INT', + 'GL_FLOAT', + ], + 'deprecated_es3': [ + 'GL_UNSIGNED_SHORT_5_6_5', + 'GL_UNSIGNED_SHORT_4_4_4_4', + 'GL_UNSIGNED_SHORT_5_5_5_1', ], }, 'RenderBufferFormat': { @@ -1121,6 +1516,37 @@ _NAMED_TYPE_INFO = { 'GL_DEPTH_COMPONENT16', 'GL_STENCIL_INDEX8', ], + 'valid_es3': [ + 'GL_R8', + 'GL_R8UI', + 'GL_R8I', + 'GL_R16UI', + 'GL_R16I', + 'GL_R32UI', + 'GL_R32I', + 'GL_RG8', + 'GL_RG8UI', + 'GL_RG8I', + 'GL_RG16UI', + 'GL_RG16I', + 'GL_RG32UI', + 'GL_RG32I', + 'GL_RGB8', + 'GL_RGBA8', + 'GL_SRGB8_ALPHA8', + 'GL_RGB10_A2', + 'GL_RGBA8UI', + 'GL_RGBA8I', + 'GL_RGB10_A2UI', + 'GL_RGBA16UI', + 'GL_RGBA16I', + 'GL_RGBA32UI', + 'GL_RGBA32I', + 'GL_DEPTH_COMPONENT24', + 'GL_DEPTH_COMPONENT32F', + 'GL_DEPTH24_STENCIL8', + 'GL_DEPTH32F_STENCIL8', + ], }, 'ShaderBinaryFormat': { 'type': 'GLenum', @@ -1149,6 +1575,16 @@ _NAMED_TYPE_INFO = { 'GL_RGB', 'GL_RGBA', ], + 'valid_es3': [ + 'GL_RED', + 'GL_RED_INTEGER', + 'GL_RG', + 'GL_RG_INTEGER', + 'GL_RGB_INTEGER', + 'GL_RGBA_INTEGER', + 'GL_DEPTH_COMPONENT', + 'GL_DEPTH_STENCIL', + ], 'invalid': [ 'GL_BGRA', 'GL_BGR', @@ -1163,6 +1599,64 @@ _NAMED_TYPE_INFO = { 'GL_RGB', 'GL_RGBA', ], + 'valid_es3': [ + 'GL_R8', + 'GL_R8_SNORM', + 'GL_R16F', + 'GL_R32F', + 'GL_R8UI', + 'GL_R8I', + 'GL_R16UI', + 'GL_R16I', + 'GL_R32UI', + 'GL_R32I', + 'GL_RG8', + 'GL_RG8_SNORM', + 'GL_RG16F', + 'GL_RG32F', + 'GL_RG8UI', + 'GL_RG8I', + 'GL_RG16UI', + 'GL_RG16I', + 'GL_RG32UI', + 'GL_RG32I', + 'GL_RGB8', + 'GL_SRGB8', + 'GL_RGB565', + 'GL_RGB8_SNORM', + 'GL_R11F_G11F_B10F', + 'GL_RGB9_E5', + 'GL_RGB16F', + 'GL_RGB32F', + 'GL_RGB8UI', + 'GL_RGB8I', + 'GL_RGB16UI', + 'GL_RGB16I', + 'GL_RGB32UI', + 'GL_RGB32I', + 'GL_RGBA8', + 'GL_SRGB8_ALPHA8', + 'GL_RGBA8_SNORM', + 'GL_RGB5_A1', + 'GL_RGBA4', + 'GL_RGB10_A2', + 'GL_RGBA16F', + 'GL_RGBA32F', + 'GL_RGBA8UI', + 'GL_RGBA8I', + 'GL_RGB10_A2UI', + 'GL_RGBA16UI', + 'GL_RGBA16I', + 'GL_RGBA32UI', + 'GL_RGBA32I', + # The DEPTH/STENCIL formats are not supported in CopyTexImage2D. + # We will reject them dynamically in GPU command buffer. + 'GL_DEPTH_COMPONENT16', + 'GL_DEPTH_COMPONENT24', + 'GL_DEPTH_COMPONENT32F', + 'GL_DEPTH24_STENCIL8', + 'GL_DEPTH32F_STENCIL8', + ], 'invalid': [ 'GL_BGRA', 'GL_BGR', @@ -1180,11 +1674,84 @@ _NAMED_TYPE_INFO = { 'GL_RGB8_OES', 'GL_RGBA8_OES', ], + 'valid_es3': [ + 'GL_R8', + 'GL_R8_SNORM', + 'GL_R16F', + 'GL_R32F', + 'GL_R8UI', + 'GL_R8I', + 'GL_R16UI', + 'GL_R16I', + 'GL_R32UI', + 'GL_R32I', + 'GL_RG8', + 'GL_RG8_SNORM', + 'GL_RG16F', + 'GL_RG32F', + 'GL_RG8UI', + 'GL_RG8I', + 'GL_RG16UI', + 'GL_RG16I', + 'GL_RG32UI', + 'GL_RG32I', + 'GL_SRGB8', + 'GL_RGB8_SNORM', + 'GL_R11F_G11F_B10F', + 'GL_RGB9_E5', + 'GL_RGB16F', + 'GL_RGB32F', + 'GL_RGB8UI', + 'GL_RGB8I', + 'GL_RGB16UI', + 'GL_RGB16I', + 'GL_RGB32UI', + 'GL_RGB32I', + 'GL_SRGB8_ALPHA8', + 'GL_RGBA8_SNORM', + 'GL_RGB10_A2', + 'GL_RGBA16F', + 'GL_RGBA32F', + 'GL_RGBA8UI', + 'GL_RGBA8I', + 'GL_RGB10_A2UI', + 'GL_RGBA16UI', + 'GL_RGBA16I', + 'GL_RGBA32UI', + 'GL_RGBA32I', + 'GL_DEPTH_COMPONENT16', + 'GL_DEPTH_COMPONENT24', + 'GL_DEPTH_COMPONENT32F', + 'GL_DEPTH24_STENCIL8', + 'GL_DEPTH32F_STENCIL8', + 'GL_COMPRESSED_R11_EAC', + 'GL_COMPRESSED_SIGNED_R11_EAC', + 'GL_COMPRESSED_RG11_EAC', + 'GL_COMPRESSED_SIGNED_RG11_EAC', + 'GL_COMPRESSED_RGB8_ETC2', + 'GL_COMPRESSED_SRGB8_ETC2', + 'GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2', + 'GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2', + 'GL_COMPRESSED_RGBA8_ETC2_EAC', + 'GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC', + ], + 'deprecated_es3': [ + 'GL_ALPHA8_EXT', + 'GL_LUMINANCE8_EXT', + 'GL_LUMINANCE8_ALPHA8_EXT', + 'GL_ALPHA16F_EXT', + 'GL_LUMINANCE16F_EXT', + 'GL_LUMINANCE_ALPHA16F_EXT', + 'GL_ALPHA32F_EXT', + 'GL_LUMINANCE32F_EXT', + 'GL_LUMINANCE_ALPHA32F_EXT', + ], }, 'ImageInternalFormat': { 'type': 'GLenum', 'valid': [ 'GL_RGB', + 'GL_RGB_YUV_420_CHROMIUM', 'GL_RGBA', ], }, @@ -1207,6 +1774,37 @@ _NAMED_TYPE_INFO = { 'GL_MOUSE_POSITION_CHROMIUM', ], }, + 'UniformParameter': { + 'type': 'GLenum', + 'valid': [ + 'GL_UNIFORM_SIZE', + 'GL_UNIFORM_TYPE', + 'GL_UNIFORM_NAME_LENGTH', + 'GL_UNIFORM_BLOCK_INDEX', + 'GL_UNIFORM_OFFSET', + 'GL_UNIFORM_ARRAY_STRIDE', + 'GL_UNIFORM_MATRIX_STRIDE', + 'GL_UNIFORM_IS_ROW_MAJOR', + ], + 'invalid': [ + 'GL_UNIFORM_BLOCK_NAME_LENGTH', + ], + }, + 'UniformBlockParameter': { + 'type': 'GLenum', + 'valid': [ + 'GL_UNIFORM_BLOCK_BINDING', + 'GL_UNIFORM_BLOCK_DATA_SIZE', + 'GL_UNIFORM_BLOCK_NAME_LENGTH', + 'GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS', + 'GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES', + 'GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER', + 'GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER', + ], + 'invalid': [ + 'GL_NEAREST', + ], + }, 'VertexAttribType': { 'type': 'GLenum', 'valid': [ @@ -1214,10 +1812,32 @@ _NAMED_TYPE_INFO = { 'GL_UNSIGNED_BYTE', 'GL_SHORT', 'GL_UNSIGNED_SHORT', - # 'GL_FIXED', // This is not available on Desktop GL. + # 'GL_FIXED', // This is not available on Desktop GL. 'GL_FLOAT', ], + 'valid_es3': [ + 'GL_INT', + 'GL_UNSIGNED_INT', + 'GL_HALF_FLOAT', + 'GL_INT_2_10_10_10_REV', + 'GL_UNSIGNED_INT_2_10_10_10_REV', + ], + 'invalid': [ + 'GL_DOUBLE', + ], + }, + 'VertexAttribIType': { + 'type': 'GLenum', + 'valid': [ + 'GL_BYTE', + 'GL_UNSIGNED_BYTE', + 'GL_SHORT', + 'GL_UNSIGNED_SHORT', + 'GL_INT', + 'GL_UNSIGNED_INT', + ], 'invalid': [ + 'GL_FLOAT', 'GL_DOUBLE', ], }, @@ -1272,6 +1892,48 @@ _NAMED_TYPE_INFO = { 'GL_UNKNOWN_CONTEXT_RESET_ARB', ], }, + 'SyncCondition': { + 'type': 'GLenum', + 'is_complete': True, + 'valid': [ + 'GL_SYNC_GPU_COMMANDS_COMPLETE', + ], + 'invalid': [ + '0', + ], + }, + 'SyncFlags': { + 'type': 'GLbitfield', + 'is_complete': True, + 'valid': [ + '0', + ], + 'invalid': [ + '1', + ], + }, + 'SyncFlushFlags': { + 'type': 'GLbitfield', + 'valid': [ + 'GL_SYNC_FLUSH_COMMANDS_BIT', + '0', + ], + 'invalid': [ + '0xFFFFFFFF', + ], + }, + 'SyncParameter': { + 'type': 'GLenum', + 'valid': [ + 'GL_SYNC_STATUS', # This needs to be the 1st; all others are cached. + 'GL_OBJECT_TYPE', + 'GL_SYNC_CONDITION', + 'GL_SYNC_FLAGS', + ], + 'invalid': [ + 'GL_SYNC_FENCE', + ], + }, } # This table specifies the different pepper interfaces that are supported for @@ -1317,8 +1979,10 @@ _PEPPER_INTERFACES = [ # command. # impl_decl: Whether or not to generate the GLES2Implementation declaration # for this command. -# needs_size: If true a data_size field is added to the command. +# needs_size: If True a data_size field is added to the command. # count: The number of units per element. For PUTn or PUT types. +# use_count_func: If True the actual data count needs to be computed; the count +# argument specifies the maximum count. # unit_test: If False no service side unit test will be generated. # client_test: If False no client side unit test will be generated. # expectation: If False the unit test will have no expected calls. @@ -1347,6 +2011,10 @@ _PEPPER_INTERFACES = [ # the corresponding feature info flag is enabled. Implies # 'extension': True. # not_shared: For GENn types, True if objects can't be shared between contexts +# unsafe: True = no validation is implemented on the service side and the +# command is only available with --enable-unsafe-es3-apis. +# id_mapping: A list of resource type names whose client side IDs need to be +# mapped to service side IDs. This is only used for unsafe APIs. _FUNCTION_INFO = { 'ActiveTexture': { @@ -1366,6 +2034,22 @@ _FUNCTION_INFO = { 'decoder_func': 'DoBindBuffer', 'gen_func': 'GenBuffersARB', }, + 'BindBufferBase': { + 'type': 'Bind', + 'id_mapping': [ 'Buffer' ], + 'gen_func': 'GenBuffersARB', + 'unsafe': True, + }, + 'BindBufferRange': { + 'type': 'Bind', + 'id_mapping': [ 'Buffer' ], + 'gen_func': 'GenBuffersARB', + 'valid_args': { + '3': '4', + '4': '4' + }, + 'unsafe': True, + }, 'BindFramebuffer': { 'type': 'Bind', 'decoder_func': 'DoBindFramebuffer', @@ -1379,6 +2063,11 @@ _FUNCTION_INFO = { 'gl_test_func': 'glBindRenderbufferEXT', 'gen_func': 'GenRenderbuffersEXT', }, + 'BindSampler': { + 'type': 'Bind', + 'id_mapping': [ 'Sampler' ], + 'unsafe': True, + }, 'BindTexture': { 'type': 'Bind', 'decoder_func': 'DoBindTexture', @@ -1387,6 +2076,11 @@ _FUNCTION_INFO = { 'client_test': False, 'trace_level': 1, }, + 'BindTransformFeedback': { + 'type': 'Bind', + 'id_mapping': [ 'TransformFeedback' ], + 'unsafe': True, + }, 'BlitFramebufferCHROMIUM': { 'decoder_func': 'DoBlitFramebufferCHROMIUM', 'unit_test': False, @@ -1420,6 +2114,26 @@ _FUNCTION_INFO = { 'defer_draws': True, 'trace_level': 1, }, + 'ClearBufferiv': { + 'type': 'PUT', + 'use_count_func': True, + 'count': 4, + 'unsafe': True, + }, + 'ClearBufferuiv': { + 'type': 'PUT', + 'count': 4, + 'unsafe': True, + }, + 'ClearBufferfv': { + 'type': 'PUT', + 'use_count_func': True, + 'count': 4, + 'unsafe': True, + }, + 'ClearBufferfi': { + 'unsafe': True, + }, 'ClearColor': { 'type': 'StateSet', 'state': 'ClearColor', @@ -1433,6 +2147,14 @@ _FUNCTION_INFO = { '0': '0.5f' }, }, + 'ClientWaitSync': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'cmd_args': 'GLuint sync, GLbitfieldSyncFlushFlags flags, ' + 'GLuint timeout_0, GLuint timeout_1, GLenum* result', + 'unsafe': True, + 'result': ['GLenum'], + }, 'ColorMask': { 'type': 'StateSet', 'state': 'ColorMask', @@ -1450,6 +2172,9 @@ _FUNCTION_INFO = { 'chromium': True, 'trace_level': 1, }, + 'CopyBufferSubData': { + 'unsafe': True, + }, 'CreateAndConsumeTextureCHROMIUM': { 'decoder_func': 'DoCreateAndConsumeTextureCHROMIUM', 'impl_func': False, @@ -1545,6 +2270,21 @@ _FUNCTION_INFO = { 'decoder_func': 'DoCopyTexSubImage2D', 'defer_reads': True, }, + 'CompressedTexImage3D': { + 'type': 'Manual', + 'data_transfer_methods': ['bucket', 'shm'], + 'unsafe': True, + }, + 'CompressedTexSubImage3D': { + 'type': 'Data', + 'data_transfer_methods': ['bucket', 'shm'], + 'decoder_func': 'DoCompressedTexSubImage3D', + 'unsafe': True, + }, + 'CopyTexSubImage3D': { + 'defer_reads': True, + 'unsafe': True, + }, 'CreateImageCHROMIUM': { 'type': 'Manual', 'cmd_args': @@ -1668,19 +2408,37 @@ _FUNCTION_INFO = { 'resource_type': 'Framebuffer', 'resource_types': 'Framebuffers', }, - 'DeleteProgram': {'type': 'Delete', 'decoder_func': 'DoDeleteProgram'}, + 'DeleteProgram': { 'type': 'Delete' }, 'DeleteRenderbuffers': { 'type': 'DELn', 'gl_test_func': 'glDeleteRenderbuffersEXT', 'resource_type': 'Renderbuffer', 'resource_types': 'Renderbuffers', }, - 'DeleteShader': {'type': 'Delete', 'decoder_func': 'DoDeleteShader'}, + 'DeleteSamplers': { + 'type': 'DELn', + 'resource_type': 'Sampler', + 'resource_types': 'Samplers', + 'unsafe': True, + }, + 'DeleteShader': { 'type': 'Delete' }, + 'DeleteSync': { + 'type': 'Delete', + 'cmd_args': 'GLuint sync', + 'resource_type': 'Sync', + 'unsafe': True, + }, 'DeleteTextures': { 'type': 'DELn', 'resource_type': 'Texture', 'resource_types': 'Textures', }, + 'DeleteTransformFeedbacks': { + 'type': 'DELn', + 'resource_type': 'TransformFeedback', + 'resource_types': 'TransformFeedbacks', + 'unsafe': True, + }, 'DepthRangef': { 'decoder_func': 'DoDepthRangef', 'gl_test_func': 'glDepthRange', @@ -1715,6 +2473,11 @@ _FUNCTION_INFO = { 'defer_draws': True, 'trace_level': 2, }, + 'DrawRangeElements': { + 'type': 'Manual', + 'gen_cmd': 'False', + 'unsafe': True, + }, 'Enable': { 'decoder_func': 'DoEnable', 'impl_func': False, @@ -1724,6 +2487,11 @@ _FUNCTION_INFO = { 'decoder_func': 'DoEnableVertexAttribArray', 'impl_decl': False, }, + 'FenceSync': { + 'type': 'Create', + 'client_test': False, + 'unsafe': True, + }, 'Finish': { 'impl_func': False, 'client_test': False, @@ -1751,6 +2519,10 @@ _FUNCTION_INFO = { 'extension_flag': 'multisampled_render_to_texture', 'trace_level': 1, }, + 'FramebufferTextureLayer': { + 'decoder_func': 'DoFramebufferTextureLayer', + 'unsafe': True, + }, 'GenerateMipmap': { 'decoder_func': 'DoGenerateMipmap', 'gl_test_func': 'glGenerateMipmapEXT', @@ -1778,12 +2550,26 @@ _FUNCTION_INFO = { 'resource_type': 'Renderbuffer', 'resource_types': 'Renderbuffers', }, + 'GenSamplers': { + 'type': 'GENn', + 'gl_test_func': 'glGenSamplers', + 'resource_type': 'Sampler', + 'resource_types': 'Samplers', + 'unsafe': True, + }, 'GenTextures': { 'type': 'GENn', 'gl_test_func': 'glGenTextures', 'resource_type': 'Texture', 'resource_types': 'Textures', }, + 'GenTransformFeedbacks': { + 'type': 'GENn', + 'gl_test_func': 'glGenTransformFeedbacks', + 'resource_type': 'TransformFeedback', + 'resource_types': 'TransformFeedbacks', + 'unsafe': True, + }, 'GetActiveAttrib': { 'type': 'Custom', 'data_transfer_methods': ['shm'], @@ -1808,6 +2594,30 @@ _FUNCTION_INFO = { 'uint32_t type', ], }, + 'GetActiveUniformBlockiv': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'result': ['SizedResult<GLint>'], + 'unsafe': True, + }, + 'GetActiveUniformBlockName': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'cmd_args': + 'GLidProgram program, GLuint index, uint32_t name_bucket_id, ' + 'void* result', + 'result': ['int32_t'], + 'unsafe': True, + }, + 'GetActiveUniformsiv': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'cmd_args': + 'GLidProgram program, uint32_t indices_bucket_id, GLenum pname, ' + 'GLint* params', + 'result': ['SizedResult<GLint>'], + 'unsafe': True, + }, 'GetAttachedShaders': { 'type': 'Custom', 'data_transfer_methods': ['shm'], @@ -1820,7 +2630,16 @@ _FUNCTION_INFO = { 'cmd_args': 'GLidProgram program, uint32_t name_bucket_id, GLint* location', 'result': ['GLint'], - 'error_return': -1, # http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml + 'error_return': -1, + }, + 'GetFragDataLocation': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'cmd_args': + 'GLidProgram program, uint32_t name_bucket_id, GLint* location', + 'result': ['GLint'], + 'error_return': -1, + 'unsafe': True, }, 'GetBooleanv': { 'type': 'GETn', @@ -1854,12 +2673,36 @@ _FUNCTION_INFO = { 'gl_test_func': 'glGetFramebufferAttachmentParameterivEXT', 'result': ['SizedResult<GLint>'], }, + 'GetInteger64v': { + 'type': 'GETn', + 'result': ['SizedResult<GLint64>'], + 'client_test': False, + 'decoder_func': 'DoGetInteger64v', + 'unsafe': True + }, 'GetIntegerv': { 'type': 'GETn', 'result': ['SizedResult<GLint>'], 'decoder_func': 'DoGetIntegerv', 'client_test': False, }, + 'GetInteger64i_v': { + 'type': 'GETn', + 'result': ['SizedResult<GLint64>'], + 'client_test': False, + 'unsafe': True + }, + 'GetIntegeri_v': { + 'type': 'GETn', + 'result': ['SizedResult<GLint>'], + 'client_test': False, + 'unsafe': True + }, + 'GetInternalformativ': { + 'type': 'GETn', + 'result': ['SizedResult<GLint>'], + 'unsafe': True, + }, 'GetMaxValueInBufferCHROMIUM': { 'type': 'Is', 'decoder_func': 'DoGetMaxValueInBufferCHROMIUM', @@ -1870,14 +2713,6 @@ _FUNCTION_INFO = { 'chromium': True, 'impl_func': False, }, - 'GetMultipleIntegervCHROMIUM': { - 'type': 'Custom', - 'data_transfer_methods': ['shm'], - 'expectation': False, - 'extension': True, - 'chromium': True, - 'client_test': False, - }, 'GetProgramiv': { 'type': 'GETn', 'decoder_func': 'DoGetProgramiv', @@ -1908,6 +2743,18 @@ _FUNCTION_INFO = { 'gl_test_func': 'glGetRenderbufferParameterivEXT', 'result': ['SizedResult<GLint>'], }, + 'GetSamplerParameterfv': { + 'type': 'GETn', + 'result': ['SizedResult<GLfloat>'], + 'id_mapping': [ 'Sampler' ], + 'unsafe': True, + }, + 'GetSamplerParameteriv': { + 'type': 'GETn', + 'result': ['SizedResult<GLint>'], + 'id_mapping': [ 'Sampler' ], + 'unsafe': True, + }, 'GetShaderiv': { 'type': 'GETn', 'decoder_func': 'DoGetShaderiv', @@ -1938,12 +2785,19 @@ _FUNCTION_INFO = { 'get_len_enum': 'GL_SHADER_SOURCE_LENGTH', 'unit_test': False, 'client_test': False, - }, + }, 'GetString': { 'type': 'Custom', 'client_test': False, 'cmd_args': 'GLenumStringType name, uint32_t bucket_id', }, + 'GetSynciv': { + 'type': 'GETn', + 'cmd_args': 'GLuint sync, GLenumSyncParameter pname, void* values', + 'result': ['SizedResult<GLint>'], + 'id_mapping': ['Sync'], + 'unsafe': True, + }, 'GetTexParameterfv': { 'type': 'GETn', 'decoder_func': 'DoGetTexParameterfv', @@ -1960,7 +2814,62 @@ _FUNCTION_INFO = { 'get_len_enum': 'GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE', 'unit_test': False, 'extension': True, - }, + }, + 'GetUniformBlockIndex': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'cmd_args': + 'GLidProgram program, uint32_t name_bucket_id, GLuint* index', + 'result': ['GLuint'], + 'error_return': 'GL_INVALID_INDEX', + 'unsafe': True, + }, + 'GetUniformBlocksCHROMIUM': { + 'type': 'Custom', + 'expectation': False, + 'impl_func': False, + 'extension': True, + 'chromium': True, + 'client_test': False, + 'cmd_args': 'GLidProgram program, uint32_t bucket_id', + 'result': ['uint32_t'], + 'unsafe': True, + }, + 'GetUniformsES3CHROMIUM': { + 'type': 'Custom', + 'expectation': False, + 'impl_func': False, + 'extension': True, + 'chromium': True, + 'client_test': False, + 'cmd_args': 'GLidProgram program, uint32_t bucket_id', + 'result': ['uint32_t'], + 'unsafe': True, + }, + 'GetTransformFeedbackVarying': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'cmd_args': + 'GLidProgram program, GLuint index, uint32_t name_bucket_id, ' + 'void* result', + 'result': [ + 'int32_t success', + 'int32_t size', + 'uint32_t type', + ], + 'unsafe': True, + }, + 'GetTransformFeedbackVaryingsCHROMIUM': { + 'type': 'Custom', + 'expectation': False, + 'impl_func': False, + 'extension': True, + 'chromium': True, + 'client_test': False, + 'cmd_args': 'GLidProgram program, uint32_t bucket_id', + 'result': ['uint32_t'], + 'unsafe': True, + }, 'GetUniformfv': { 'type': 'Custom', 'data_transfer_methods': ['shm'], @@ -1971,6 +2880,20 @@ _FUNCTION_INFO = { 'data_transfer_methods': ['shm'], 'result': ['SizedResult<GLint>'], }, + 'GetUniformuiv': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'result': ['SizedResult<GLuint>'], + 'unsafe': True, + }, + 'GetUniformIndices': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'result': ['SizedResult<GLuint>'], + 'cmd_args': 'GLidProgram program, uint32_t names_bucket_id, ' + 'GLuint* indices', + 'unsafe': True, + }, 'GetUniformLocation': { 'type': 'Custom', 'data_transfer_methods': ['shm'], @@ -1995,12 +2918,44 @@ _FUNCTION_INFO = { 'expectation': False, 'client_test': False, }, + 'GetVertexAttribIiv': { + 'type': 'GETn', + 'result': ['SizedResult<GLint>'], + 'impl_decl': False, + 'decoder_func': 'DoGetVertexAttribIiv', + 'expectation': False, + 'client_test': False, + 'unsafe': True, + }, + 'GetVertexAttribIuiv': { + 'type': 'GETn', + 'result': ['SizedResult<GLuint>'], + 'impl_decl': False, + 'decoder_func': 'DoGetVertexAttribIuiv', + 'expectation': False, + 'client_test': False, + 'unsafe': True, + }, 'GetVertexAttribPointerv': { 'type': 'Custom', 'data_transfer_methods': ['shm'], 'result': ['SizedResult<GLuint>'], 'client_test': False, }, + 'InvalidateFramebuffer': { + 'type': 'PUTn', + 'count': 1, + 'client_test': False, + 'unit_test': False, + 'unsafe': True, + }, + 'InvalidateSubFramebuffer': { + 'type': 'PUTn', + 'count': 1, + 'client_test': False, + 'unit_test': False, + 'unsafe': True, + }, 'IsBuffer': { 'type': 'Is', 'decoder_func': 'DoIsBuffer', @@ -2009,6 +2964,7 @@ _FUNCTION_INFO = { 'IsEnabled': { 'type': 'Is', 'decoder_func': 'DoIsEnabled', + 'client_test': False, 'impl_func': False, 'expectation': False, }, @@ -2032,11 +2988,30 @@ _FUNCTION_INFO = { 'decoder_func': 'DoIsShader', 'expectation': False, }, + 'IsSampler': { + 'type': 'Is', + 'id_mapping': [ 'Sampler' ], + 'expectation': False, + 'unsafe': True, + }, + 'IsSync': { + 'type': 'Is', + 'id_mapping': [ 'Sync' ], + 'cmd_args': 'GLuint sync', + 'expectation': False, + 'unsafe': True, + }, 'IsTexture': { 'type': 'Is', 'decoder_func': 'DoIsTexture', 'expectation': False, }, + 'IsTransformFeedback': { + 'type': 'Is', + 'id_mapping': [ 'TransformFeedback' ], + 'expectation': False, + 'unsafe': True, + }, 'LinkProgram': { 'decoder_func': 'DoLinkProgram', 'impl_func': False, @@ -2056,11 +3031,24 @@ _FUNCTION_INFO = { }, 'MapTexSubImage2DCHROMIUM': { 'gen_cmd': False, - 'extension': True, + 'extension': "CHROMIUM_sub_image", 'chromium': True, 'client_test': False, 'pepper_interface': 'ChromiumMapSub', }, + 'MapBufferRange': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'cmd_args': 'GLenumBufferTarget target, GLintptrNotNegative offset, ' + 'GLsizeiptr size, GLbitfieldMapBufferAccess access, ' + 'uint32_t data_shm_id, uint32_t data_shm_offset, ' + 'uint32_t result_shm_id, uint32_t result_shm_offset', + 'unsafe': True, + 'result': ['uint32_t'], + }, + 'PauseTransformFeedback': { + 'unsafe': True, + }, 'PixelStorei': {'type': 'Manual'}, 'PostSubBufferCHROMIUM': { 'type': 'Custom', @@ -2117,6 +3105,9 @@ _FUNCTION_INFO = { 'unit_test': False, 'extension_flag': 'multisampled_render_to_texture', }, + 'ReadBuffer': { + 'unsafe': True, + }, 'ReadPixels': { 'cmd_comment': '// ReadPixels has the result separated from the pixel buffer so that\n' @@ -2139,17 +3130,53 @@ _FUNCTION_INFO = { 'decoder_func': 'DoReleaseShaderCompiler', 'unit_test': False, }, + 'ResumeTransformFeedback': { + 'unsafe': True, + }, + 'SamplerParameterf': { + 'valid_args': { + '2': 'GL_NEAREST' + }, + 'id_mapping': [ 'Sampler' ], + 'unsafe': True, + }, + 'SamplerParameterfv': { + 'type': 'PUT', + 'data_value': 'GL_NEAREST', + 'count': 1, + 'gl_test_func': 'glSamplerParameterf', + 'decoder_func': 'DoSamplerParameterfv', + 'first_element_only': True, + 'id_mapping': [ 'Sampler' ], + 'unsafe': True, + }, + 'SamplerParameteri': { + 'valid_args': { + '2': 'GL_NEAREST' + }, + 'id_mapping': [ 'Sampler' ], + 'unsafe': True, + }, + 'SamplerParameteriv': { + 'type': 'PUT', + 'data_value': 'GL_NEAREST', + 'count': 1, + 'gl_test_func': 'glSamplerParameteri', + 'decoder_func': 'DoSamplerParameteriv', + 'first_element_only': True, + 'unsafe': True, + }, 'ShaderBinary': { 'type': 'Custom', 'client_test': False, }, 'ShaderSource': { - 'type': 'Manual', + 'type': 'PUTSTR', + 'decoder_func': 'DoShaderSource', + 'expectation': False, 'data_transfer_methods': ['bucket'], - 'needs_size': True, - 'client_test': False, 'cmd_args': - 'GLuint shader, const char* data', + 'GLuint shader, const char** str', 'pepper_args': 'GLuint shader, GLsizei count, const char** str, const GLint* length', }, @@ -2173,11 +3200,25 @@ _FUNCTION_INFO = { 'extension': True, 'trace_level': 1, }, + 'SwapInterval': { + 'impl_func': False, + 'decoder_func': 'DoSwapInterval', + 'unit_test': False, + 'client_test': False, + 'extension': True, + 'trace_level': 1, + }, 'TexImage2D': { 'type': 'Manual', 'data_transfer_methods': ['shm'], 'client_test': False, }, + 'TexImage3D': { + 'type': 'Manual', + 'data_transfer_methods': ['shm'], + 'client_test': False, + 'unsafe': True, + }, 'TexParameterf': { 'decoder_func': 'DoTexParameterf', 'valid_args': { @@ -2206,6 +3247,9 @@ _FUNCTION_INFO = { 'gl_test_func': 'glTexParameteri', 'first_element_only': True, }, + 'TexStorage3D': { + 'unsafe': True, + }, 'TexSubImage2D': { 'type': 'Manual', 'data_transfer_methods': ['shm'], @@ -2216,6 +3260,25 @@ _FUNCTION_INFO = { 'GLenumTextureFormat format, GLenumPixelType type, ' 'const void* pixels, GLboolean internal' }, + 'TexSubImage3D': { + 'type': 'Manual', + 'data_transfer_methods': ['shm'], + 'client_test': False, + 'cmd_args': 'GLenumTextureTarget target, GLint level, ' + 'GLint xoffset, GLint yoffset, GLint zoffset, ' + 'GLsizei width, GLsizei height, GLsizei depth, ' + 'GLenumTextureFormat format, GLenumPixelType type, ' + 'const void* pixels, GLboolean internal', + 'unsafe': True, + }, + 'TransformFeedbackVaryings': { + 'type': 'PUTSTR', + 'data_transfer_methods': ['bucket'], + 'decoder_func': 'DoTransformFeedbackVaryings', + 'cmd_args': + 'GLuint program, const char** varyings, GLenum buffermode', + 'unsafe': True, + }, 'Uniform1f': {'type': 'PUTXn', 'count': 1}, 'Uniform1fv': { 'type': 'PUTn', @@ -2229,6 +3292,16 @@ _FUNCTION_INFO = { 'decoder_func': 'DoUniform1iv', 'unit_test': False, }, + 'Uniform1ui': { + 'type': 'PUTXn', + 'count': 1, + 'unsafe': True, + }, + 'Uniform1uiv': { + 'type': 'PUTn', + 'count': 1, + 'unsafe': True, + }, 'Uniform2i': {'type': 'PUTXn', 'count': 2}, 'Uniform2f': {'type': 'PUTXn', 'count': 2}, 'Uniform2fv': { @@ -2241,6 +3314,16 @@ _FUNCTION_INFO = { 'count': 2, 'decoder_func': 'DoUniform2iv', }, + 'Uniform2ui': { + 'type': 'PUTXn', + 'count': 2, + 'unsafe': True, + }, + 'Uniform2uiv': { + 'type': 'PUTn', + 'count': 2, + 'unsafe': True, + }, 'Uniform3i': {'type': 'PUTXn', 'count': 3}, 'Uniform3f': {'type': 'PUTXn', 'count': 3}, 'Uniform3fv': { @@ -2253,6 +3336,16 @@ _FUNCTION_INFO = { 'count': 3, 'decoder_func': 'DoUniform3iv', }, + 'Uniform3ui': { + 'type': 'PUTXn', + 'count': 3, + 'unsafe': True, + }, + 'Uniform3uiv': { + 'type': 'PUTn', + 'count': 3, + 'unsafe': True, + }, 'Uniform4i': {'type': 'PUTXn', 'count': 4}, 'Uniform4f': {'type': 'PUTXn', 'count': 4}, 'Uniform4fv': { @@ -2265,21 +3358,66 @@ _FUNCTION_INFO = { 'count': 4, 'decoder_func': 'DoUniform4iv', }, + 'Uniform4ui': { + 'type': 'PUTXn', + 'count': 4, + 'unsafe': True, + }, + 'Uniform4uiv': { + 'type': 'PUTn', + 'count': 4, + 'unsafe': True, + }, 'UniformMatrix2fv': { 'type': 'PUTn', 'count': 4, 'decoder_func': 'DoUniformMatrix2fv', }, + 'UniformMatrix2x3fv': { + 'type': 'PUTn', + 'count': 6, + 'unsafe': True, + }, + 'UniformMatrix2x4fv': { + 'type': 'PUTn', + 'count': 8, + 'unsafe': True, + }, 'UniformMatrix3fv': { 'type': 'PUTn', 'count': 9, 'decoder_func': 'DoUniformMatrix3fv', }, + 'UniformMatrix3x2fv': { + 'type': 'PUTn', + 'count': 6, + 'unsafe': True, + }, + 'UniformMatrix3x4fv': { + 'type': 'PUTn', + 'count': 12, + 'unsafe': True, + }, 'UniformMatrix4fv': { 'type': 'PUTn', 'count': 16, 'decoder_func': 'DoUniformMatrix4fv', }, + 'UniformMatrix4x2fv': { + 'type': 'PUTn', + 'count': 8, + 'unsafe': True, + }, + 'UniformMatrix4x3fv': { + 'type': 'PUTn', + 'count': 12, + 'unsafe': True, + }, + 'UniformBlockBinding': { + 'type': 'Custom', + 'impl_func': False, + 'unsafe': True, + }, 'UnmapBufferCHROMIUM': { 'gen_cmd': False, 'extension': True, @@ -2293,9 +3431,13 @@ _FUNCTION_INFO = { 'client_test': False, 'pepper_interface': 'ChromiumMapSub', }, + 'UnmapBuffer': { + 'type': 'Custom', + 'unsafe': True, + }, 'UnmapTexSubImage2DCHROMIUM': { 'gen_cmd': False, - 'extension': True, + 'extension': "CHROMIUM_sub_image", 'chromium': True, 'client_test': False, 'pepper_interface': 'ChromiumMapSub', @@ -2329,12 +3471,48 @@ _FUNCTION_INFO = { 'count': 4, 'decoder_func': 'DoVertexAttrib4fv', }, + 'VertexAttribI4i': { + 'unsafe': True, + 'decoder_func': 'DoVertexAttribI4i', + }, + 'VertexAttribI4iv': { + 'type': 'PUT', + 'count': 4, + 'unsafe': True, + 'decoder_func': 'DoVertexAttribI4iv', + }, + 'VertexAttribI4ui': { + 'unsafe': True, + 'decoder_func': 'DoVertexAttribI4ui', + }, + 'VertexAttribI4uiv': { + 'type': 'PUT', + 'count': 4, + 'unsafe': True, + 'decoder_func': 'DoVertexAttribI4uiv', + }, + 'VertexAttribIPointer': { + 'type': 'Manual', + 'cmd_args': 'GLuint indx, GLintVertexAttribSize size, ' + 'GLenumVertexAttribIType type, GLsizei stride, ' + 'GLuint offset', + 'client_test': False, + 'unsafe': True, + }, 'VertexAttribPointer': { - 'type': 'Manual', - 'cmd_args': 'GLuint indx, GLintVertexAttribSize size, ' - 'GLenumVertexAttribType type, GLboolean normalized, ' - 'GLsizei stride, GLuint offset', - 'client_test': False, + 'type': 'Manual', + 'cmd_args': 'GLuint indx, GLintVertexAttribSize size, ' + 'GLenumVertexAttribType type, GLboolean normalized, ' + 'GLsizei stride, GLuint offset', + 'client_test': False, + }, + 'WaitSync': { + 'type': 'Custom', + 'cmd_args': 'GLuint sync, GLbitfieldSyncFlushFlags flags, ' + 'GLuint timeout_0, GLuint timeout_1', + 'impl_func': False, + 'client_test': False, + 'unsafe': True, }, 'Scissor': { 'type': 'StateSet', @@ -2344,11 +3522,11 @@ _FUNCTION_INFO = { 'decoder_func': 'DoViewport', }, 'ResizeCHROMIUM': { - 'type': 'Custom', - 'impl_func': False, - 'unit_test': False, - 'extension': True, - 'chromium': True, + 'type': 'Custom', + 'impl_func': False, + 'unit_test': False, + 'extension': True, + 'chromium': True, }, 'GetRequestableExtensionsCHROMIUM': { 'type': 'Custom', @@ -2390,6 +3568,12 @@ _FUNCTION_INFO = { 'extension': True, 'chromium': True, }, + 'CopySubTextureCHROMIUM': { + 'decoder_func': 'DoCopySubTextureCHROMIUM', + 'unit_test': False, + 'extension': True, + 'chromium': True, + }, 'TexStorage2DEXT': { 'unit_test': False, 'extension': True, @@ -2440,6 +3624,7 @@ _FUNCTION_INFO = { 'unit_test': False, 'pepper_interface': 'Query', 'not_shared': 'True', + 'extension': "occlusion_query_EXT", }, 'DeleteQueriesEXT': { 'type': 'DELn', @@ -2448,11 +3633,13 @@ _FUNCTION_INFO = { 'resource_types': 'Queries', 'unit_test': False, 'pepper_interface': 'Query', + 'extension': "occlusion_query_EXT", }, 'IsQueryEXT': { 'gen_cmd': False, 'client_test': False, 'pepper_interface': 'Query', + 'extension': "occlusion_query_EXT", }, 'BeginQueryEXT': { 'type': 'Manual', @@ -2460,6 +3647,10 @@ _FUNCTION_INFO = { 'data_transfer_methods': ['shm'], 'gl_test_func': 'glBeginQuery', 'pepper_interface': 'Query', + 'extension': "occlusion_query_EXT", + }, + 'BeginTransformFeedback': { + 'unsafe': True, }, 'EndQueryEXT': { 'type': 'Manual', @@ -2467,18 +3658,24 @@ _FUNCTION_INFO = { 'gl_test_func': 'glEndnQuery', 'client_test': False, 'pepper_interface': 'Query', + 'extension': "occlusion_query_EXT", + }, + 'EndTransformFeedback': { + 'unsafe': True, }, 'GetQueryivEXT': { 'gen_cmd': False, 'client_test': False, 'gl_test_func': 'glGetQueryiv', 'pepper_interface': 'Query', + 'extension': "occlusion_query_EXT", }, 'GetQueryObjectuivEXT': { 'gen_cmd': False, 'client_test': False, 'gl_test_func': 'glGetQueryObjectuiv', 'pepper_interface': 'Query', + 'extension': "occlusion_query_EXT", }, 'BindUniformLocationCHROMIUM': { 'type': 'GLchar', @@ -2565,6 +3762,13 @@ _FUNCTION_INFO = { 'ShallowFlushCHROMIUM': { 'impl_func': False, 'gen_cmd': False, + 'extension': "CHROMIUM_miscellaneous", + 'chromium': True, + 'client_test': False, + }, + 'OrderingBarrierCHROMIUM': { + 'impl_func': False, + 'gen_cmd': False, 'extension': True, 'chromium': True, 'client_test': False, @@ -2573,7 +3777,7 @@ _FUNCTION_INFO = { 'type': 'Custom', 'impl_func': False, 'client_test': False, - 'cmd_args': 'GLuint bucket_id', + 'cmd_args': 'GLuint category_bucket_id, GLuint name_bucket_id', 'extension': True, 'chromium': True, }, @@ -2629,8 +3833,6 @@ _FUNCTION_INFO = { 'DiscardFramebufferEXT': { 'type': 'PUTn', 'count': 1, - 'cmd_args': 'GLenum target, GLsizei count, ' - 'const GLenum* attachments', 'decoder_func': 'DoDiscardFramebufferEXT', 'unit_test': False, 'client_test': False, @@ -2895,15 +4097,17 @@ class TypeHandler(object): file.Write("\n") size = len(args) * _SIZE_OF_UINT32 + _SIZE_OF_COMMAND_HEADER - file.Write("COMPILE_ASSERT(sizeof(%s) == %d,\n" % (func.name, size)) - file.Write(" Sizeof_%s_is_not_%d);\n" % (func.name, size)) - file.Write("COMPILE_ASSERT(offsetof(%s, header) == 0,\n" % func.name) - file.Write(" OffsetOf_%s_header_not_0);\n" % func.name) + file.Write("static_assert(sizeof(%s) == %d,\n" % (func.name, size)) + file.Write(" \"size of %s should be %d\");\n" % + (func.name, size)) + file.Write("static_assert(offsetof(%s, header) == 0,\n" % func.name) + file.Write(" \"offset of %s header should be 0\");\n" % + func.name) offset = _SIZE_OF_COMMAND_HEADER for arg in args: - file.Write("COMPILE_ASSERT(offsetof(%s, %s) == %d,\n" % + file.Write("static_assert(offsetof(%s, %s) == %d,\n" % (func.name, arg.name, offset)) - file.Write(" OffsetOf_%s_%s_not_%d);\n" % + file.Write(" \"offset of %s %s should be %d\");\n" % (func.name, arg.name, offset)) offset += _SIZE_OF_UINT32 if not result == None and len(result) > 1: @@ -2912,8 +4116,9 @@ class TypeHandler(object): parts = line.split() name = parts[-1] check = """ -COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d, - OffsetOf_%(cmd_name)s_Result_%(field_name)s_not_%(offset)d); +static_assert(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d, + "offset of %(cmd_name)s Result %(field_name)s should be " + "%(offset)d"); """ file.Write((check.strip() + "\n") % { 'cmd_name': func.name, @@ -2925,8 +4130,54 @@ COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d, def WriteHandlerImplementation(self, func, file): """Writes the handler implementation for this command.""" + if func.IsUnsafe() and func.GetInfo('id_mapping'): + code_no_gen = """ if (!group_->Get%(type)sServiceId( + %(var)s, &%(service_var)s)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "%(func)s", "invalid %(var)s id"); + return error::kNoError; + } +""" + code_gen = """ if (!group_->Get%(type)sServiceId( + %(var)s, &%(service_var)s)) { + if (!group_->bind_generates_resource()) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, "%(func)s", "invalid %(var)s id"); + return error::kNoError; + } + GLuint client_id = %(var)s; + gl%(gen_func)s(1, &%(service_var)s); + Create%(type)s(client_id, %(service_var)s); + } +""" + gen_func = func.GetInfo('gen_func') + for id_type in func.GetInfo('id_mapping'): + service_var = id_type.lower() + if id_type == 'Sync': + service_var = "service_%s" % service_var + file.Write(" GLsync %s = 0;\n" % service_var) + if gen_func and id_type in gen_func: + file.Write(code_gen % { 'type': id_type, + 'var': id_type.lower(), + 'service_var': service_var, + 'func': func.GetGLFunctionName(), + 'gen_func': gen_func }) + else: + file.Write(code_no_gen % { 'type': id_type, + 'var': id_type.lower(), + 'service_var': service_var, + 'func': func.GetGLFunctionName() }) + args = [] + for arg in func.GetOriginalArgs(): + if arg.type == "GLsync": + args.append("service_%s" % arg.name) + elif arg.name.endswith("size") and arg.type == "GLsizei": + args.append("num_%s" % func.GetLastOriginalArg().name) + elif arg.name == "length": + args.append("nullptr") + else: + args.append(arg.name) file.Write(" %s(%s);\n" % - (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) + (func.GetGLFunctionName(), ", ".join(args))) def WriteCmdSizeTest(self, func, file): """Writes the size test for a command.""" @@ -2972,13 +4223,23 @@ COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d, file.Write(" // TODO(gman): Compute correct size.\n") file.Write(" EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);\n") + def __WriteIdMapping(self, func, file): + """Writes client side / service side ID mapping.""" + if not func.IsUnsafe() or not func.GetInfo('id_mapping'): + return + for id_type in func.GetInfo('id_mapping'): + file.Write(" group_->Get%sServiceId(%s, &%s);\n" % + (id_type, id_type.lower(), id_type.lower())) + def WriteImmediateHandlerImplementation (self, func, file): """Writes the handler impl for the immediate version of a command.""" + self.__WriteIdMapping(func, file) file.Write(" %s(%s);\n" % (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) def WriteBucketHandlerImplementation (self, func, file): """Writes the handler impl for the bucket version of a command.""" + self.__WriteIdMapping(func, file) file.Write(" %s(%s);\n" % (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) @@ -2986,7 +4247,12 @@ COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d, """Writes function header for service implementation handlers.""" file.Write("""error::Error GLES2DecoderImpl::Handle%(name)s( uint32_t immediate_data_size, const void* cmd_data) { - const gles2::cmds::%(name)s& c = + """ % {'name': func.name}) + if func.IsUnsafe(): + file.Write("""if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + """) + file.Write("""const gles2::cmds::%(name)s& c = *static_cast<const gles2::cmds::%(name)s*>(cmd_data); (void)c; """ % {'name': func.name}) @@ -3014,12 +4280,10 @@ COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d, self.WriteServiceHandlerFunctionHeader(func, file) self.WriteHandlerExtensionCheck(func, file) self.WriteHandlerDeferReadWrite(func, file); - last_arg = func.GetLastOriginalArg() - all_but_last_arg = func.GetOriginalArgs()[:-1] - for arg in all_but_last_arg: + for arg in func.GetOriginalArgs(): + if arg.IsPointer(): + self.WriteGetDataSizeCode(func, file) arg.WriteGetCode(file) - self.WriteGetDataSizeCode(func, file) - last_arg.WriteGetCode(file) func.WriteHandlerValidation(file) func.WriteHandlerImplementation(file) file.Write(" return error::kNoError;\n") @@ -3031,12 +4295,8 @@ COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d, self.WriteServiceHandlerFunctionHeader(func, file) self.WriteHandlerExtensionCheck(func, file) self.WriteHandlerDeferReadWrite(func, file); - last_arg = func.GetLastOriginalArg() - all_but_last_arg = func.GetOriginalArgs()[:-1] - for arg in all_but_last_arg: + for arg in func.GetCmdArgs(): arg.WriteGetCode(file) - self.WriteGetDataSizeCode(func, file) - last_arg.WriteGetCode(file) func.WriteHandlerValidation(file) func.WriteHandlerImplementation(file) file.Write(" return error::kNoError;\n") @@ -3096,6 +4356,8 @@ COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d, def WriteInvalidUnitTest(self, func, file, test, *extras): """Writes an invalid unit test for the service implementation.""" + if func.IsUnsafe(): + return for invalid_arg_index, invalid_arg in enumerate(func.GetOriginalArgs()): # Service implementation does not test constants, as they are not part of # the call in the service side. @@ -3133,7 +4395,7 @@ COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d, 'all_but_last_args': ", ".join(arg_strings[:-1]), 'gl_args': ", ".join(gl_arg_strings), 'parse_result': parse_result, - 'gl_error_test': gl_error_test, + 'gl_error_test': gl_error_test, } for extra in extras: vars.update(extra) @@ -3148,36 +4410,40 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { SetupExpectationsForEnableDisable(%(gl_args)s, true); SpecializedSetup<cmds::%(name)s, 0>(true); cmds::%(name)s cmd; - cmd.Init(%(args)s); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} -""" + cmd.Init(%(args)s);""" elif func.name == 'Disable': valid_test = """ TEST_P(%(test_name)s, %(name)sValidArgs) { SetupExpectationsForEnableDisable(%(gl_args)s, false); SpecializedSetup<cmds::%(name)s, 0>(true); cmds::%(name)s cmd; - cmd.Init(%(args)s); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} -""" + cmd.Init(%(args)s);""" else: valid_test = """ TEST_P(%(test_name)s, %(name)sValidArgs) { EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)); SpecializedSetup<cmds::%(name)s, 0>(true); cmds::%(name)s cmd; - cmd.Init(%(args)s); + cmd.Init(%(args)s);""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} +""" + else: + valid_test += """ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } """ self.WriteValidUnitTest(func, file, valid_test, *extras) - invalid_test = """ + if not func.IsUnsafe(): + invalid_test = """ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0); SpecializedSetup<cmds::%(name)s, 0>(false); @@ -3186,7 +4452,7 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));%(gl_error_test)s } """ - self.WriteInvalidUnitTest(func, file, invalid_test, *extras) + self.WriteInvalidUnitTest(func, file, invalid_test, *extras) def WriteImmediateServiceUnitTest(self, func, file, *extras): """Writes the service unit test for an immediate command.""" @@ -3298,6 +4564,35 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { (func.return_type, func.original_name, func.MakeTypedOriginalArgString(""))) + def WriteMojoGLES2ImplHeader(self, func, file): + """Writes the Mojo GLES2 implementation header.""" + file.Write("%s %s(%s) override;\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + + def WriteMojoGLES2Impl(self, func, file): + """Writes the Mojo GLES2 implementation.""" + file.Write("%s MojoGLES2Impl::%s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + extensions = ["CHROMIUM_sync_point", "CHROMIUM_texture_mailbox", + "CHROMIUM_sub_image", "CHROMIUM_miscellaneous", + "occlusion_query_EXT"] + if func.IsCoreGLFunction() or func.GetInfo("extension") in extensions: + file.Write("MojoGLES2MakeCurrent(context_);"); + func_return = "gl" + func.original_name + "(" + \ + func.MakeOriginalArgString("") + ");" + if func.return_type == "void": + file.Write(func_return); + else: + file.Write("return " + func_return); + else: + file.Write("NOTREACHED() << \"Unimplemented %s.\";\n" % + func.original_name); + if func.return_type != "void": + file.Write("return 0;") + file.Write("}") + def WriteGLES2InterfaceStub(self, func, file): """Writes the GLES2 Interface stub declaration.""" file.Write("%s %s(%s) override;\n" % @@ -3374,7 +4669,7 @@ TEST_F(GLES2ImplementationTest, %(name)sInvalidConstantArg%(invalid_index)d) { }) else: if client_test != False: - file.Write("// TODO: Implement unit test for %s\n" % func.name) + file.Write("// TODO(zmo): Implement unit test for %s\n" % func.name) def WriteDestinationInitalizationValidation(self, func, file): """Writes the client side destintion initialization validation.""" @@ -3468,7 +4763,7 @@ class StateSetHandler(TypeHandler): # Make this behavior consistent within Chromium, and avoid leaking GL # errors by generating the error in the command buffer instead of # letting the GL driver generate it. - code.append("base::IsNaN(%s)" % args[ndx].name) + code.append("std::isnan(%s)" % args[ndx].name) if len(code): file.Write(" if (%s) {\n" % " ||\n ".join(code)) file.Write( @@ -3830,10 +5125,6 @@ class HandWrittenHandler(CustomHandler): """Overrriden from TypeHandler.""" pass - def WriteBucketCmdHelper(self, func, file): - """Overrriden from TypeHandler.""" - pass - def WriteCmdHelper(self, func, file): """Overrriden from TypeHandler.""" pass @@ -3860,7 +5151,8 @@ class ManualHandler(CustomHandler): def InitFunction(self, func): """Overrriden from TypeHandler.""" - if (func.name == 'CompressedTexImage2DBucket'): + if (func.name == 'CompressedTexImage2DBucket' or + func.name == 'CompressedTexImage3DBucket'): func.cmd_args = func.cmd_args[:-1] func.AddCmdArg(Argument('bucket_id', 'GLuint')) else: @@ -3909,14 +5201,15 @@ class ManualHandler(CustomHandler): class DataHandler(TypeHandler): - """Handler for glBufferData, glBufferSubData, glTexImage2D, glTexSubImage2D, - glCompressedTexImage2D, glCompressedTexImageSub2D.""" + """Handler for glBufferData, glBufferSubData, glTexImage*D, glTexSubImage*D, + glCompressedTexImage*D, glCompressedTexImageSub*D.""" def __init__(self): TypeHandler.__init__(self) def InitFunction(self, func): """Overrriden from TypeHandler.""" - if func.name == 'CompressedTexSubImage2DBucket': + if (func.name == 'CompressedTexSubImage2DBucket' or + func.name == 'CompressedTexSubImage3DBucket'): func.cmd_args = func.cmd_args[:-1] func.AddCmdArg(Argument('bucket_id', 'GLuint')) @@ -3929,9 +5222,12 @@ class DataHandler(TypeHandler): if name == 'BufferData' or name == 'BufferSubData': file.Write(" uint32_t data_size = size;\n") elif (name == 'CompressedTexImage2D' or - name == 'CompressedTexSubImage2D'): + name == 'CompressedTexSubImage2D' or + name == 'CompressedTexImage3D' or + name == 'CompressedTexSubImage3D'): file.Write(" uint32_t data_size = imageSize;\n") - elif (name == 'CompressedTexSubImage2DBucket'): + elif (name == 'CompressedTexSubImage2DBucket' or + name == 'CompressedTexSubImage3DBucket'): file.Write(" Bucket* bucket = GetBucket(c.bucket_id);\n") file.Write(" uint32_t data_size = bucket->size();\n") file.Write(" GLsizei imageSize = data_size;\n") @@ -3994,7 +5290,8 @@ class DataHandler(TypeHandler): def WriteBucketServiceImplementation(self, func, file): """Overrriden from TypeHandler.""" - if not func.name == 'CompressedTexSubImage2DBucket': + if ((not func.name == 'CompressedTexSubImage2DBucket') and + (not func.name == 'CompressedTexSubImage3DBucket')): TypeHandler.WriteBucketServiceImplemenation(self, func, file) @@ -4013,7 +5310,18 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)); SpecializedSetup<cmds::%(name)s, 0>(true); cmds::%(name)s cmd; - cmd.Init(%(args)s); + cmd.Init(%(args)s);""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} +""" + else: + valid_test += """ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -4042,29 +5350,63 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)); SpecializedSetup<cmds::%(name)s, 0>(true); cmds::%(name)s cmd; - cmd.Init(%(args)s); + cmd.Init(%(args)s);""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} +""" + else: + valid_test += """ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } """ if func.GetInfo("gen_func"): - valid_test += """ + valid_test += """ TEST_P(%(test_name)s, %(name)sValidArgsNewId) { - EXPECT_CALL(*gl_, %(gl_func_name)s(%(first_gl_arg)s, kNewServiceId)); + EXPECT_CALL(*gl_, + %(gl_func_name)s(%(gl_args_with_new_id)s)); EXPECT_CALL(*gl_, %(gl_gen_func_name)s(1, _)) .WillOnce(SetArgumentPointee<1>(kNewServiceId)); SpecializedSetup<cmds::%(name)s, 0>(true); cmds::%(name)s cmd; - cmd.Init(%(first_arg)s, kNewClientId); + cmd.Init(%(args_with_new_id)s);""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); EXPECT_TRUE(Get%(resource_type)s(kNewClientId) != NULL); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } """ + else: + valid_test += """ + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_TRUE(Get%(resource_type)s(kNewClientId) != NULL); +} +""" + + gl_args_with_new_id = [] + args_with_new_id = [] + for arg in func.GetOriginalArgs(): + if hasattr(arg, 'resource_type'): + gl_args_with_new_id.append('kNewServiceId') + args_with_new_id.append('kNewClientId') + else: + gl_args_with_new_id.append(arg.GetValidGLArg(func)) + args_with_new_id.append(arg.GetValidArg(func)) self.WriteValidUnitTest(func, file, valid_test, { - 'first_arg': func.GetOriginalArgs()[0].GetValidArg(func), - 'first_gl_arg': func.GetOriginalArgs()[0].GetValidGLArg(func), - 'resource_type': func.GetOriginalArgs()[1].resource_type, + 'args_with_new_id': ", ".join(args_with_new_id), + 'gl_args_with_new_id': ", ".join(gl_args_with_new_id), + 'resource_type': func.GetResourceIdArg().resource_type, 'gl_gen_func_name': func.GetInfo("gen_func"), }, *extras) @@ -4102,21 +5444,12 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { SetGLError(GL_INVALID_OPERATION, "%(name)s\", \"%(id)s reserved id"); return; } - if (%(name)sHelper(%(arg_string)s)) { - helper_->%(name)s(%(arg_string)s); - } + %(name)sHelper(%(arg_string)s); CheckGLError(); } """ - name_arg = None - if len(func.GetOriginalArgs()) == 1: - # Bind functions that have no target (like BindVertexArrayOES) - name_arg = func.GetOriginalArgs()[0] - else: - # Bind functions that have both a target and a name (like BindTexture) - name_arg = func.GetOriginalArgs()[1] - + name_arg = func.GetResourceIdArg() file.Write(code % { 'name': func.name, 'arg_string': func.MakeOriginalArgString(""), @@ -4139,10 +5472,13 @@ TEST_F(GLES2ImplementationTest, %(name)s) { expected.cmd.Init(%(cmd_args)s); gl_->%(name)s(%(args)s); - EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));""" + if not func.IsUnsafe(): + code += """ ClearCommands(); gl_->%(name)s(%(args)s); - EXPECT_TRUE(NoCommandsWritten()); + EXPECT_TRUE(NoCommandsWritten());""" + code += """ } """ cmd_arg_strings = [ @@ -4187,10 +5523,25 @@ class GENnHandler(TypeHandler): def WriteImmediateHandlerImplementation(self, func, file): """Overrriden from TypeHandler.""" - file.Write(" if (!%sHelper(n, %s)) {\n" - " return error::kInvalidArguments;\n" - " }\n" % - (func.original_name, func.GetLastOriginalArg().name)) + if func.IsUnsafe(): + file.Write(""" for (GLsizei ii = 0; ii < n; ++ii) { + if (group_->Get%(resource_name)sServiceId(%(last_arg_name)s[ii], NULL)) { + return error::kInvalidArguments; + } + } + scoped_ptr<GLuint[]> service_ids(new GLuint[n]); + gl%(func_name)s(n, service_ids.get()); + for (GLsizei ii = 0; ii < n; ++ii) { + group_->Add%(resource_name)sId(%(last_arg_name)s[ii], service_ids[ii]); + } +""" % { 'func_name': func.original_name, + 'last_arg_name': func.GetLastOriginalArg().name, + 'resource_name': func.GetInfo('resource_type') }) + else: + file.Write(" if (!%sHelper(n, %s)) {\n" + " return error::kInvalidArguments;\n" + " }\n" % + (func.original_name, func.GetLastOriginalArg().name)) def WriteGLES2Implementation(self, func, file): """Overrriden from TypeHandler.""" @@ -4276,8 +5627,17 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { cmds::%(name)s cmd; cmd.Init(%(args)s); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - EXPECT_TRUE(Get%(resource_name)s(kNewClientId) != NULL); + EXPECT_EQ(GL_NO_ERROR, GetGLError());""" + if func.IsUnsafe(): + valid_test += """ + GLuint service_id; + EXPECT_TRUE(Get%(resource_name)sServiceId(kNewClientId, &service_id)); + EXPECT_EQ(kNewServiceId, service_id) +} +""" + else: + valid_test += """ + EXPECT_TRUE(Get%(resource_name)s(kNewClientId, &service_id) != NULL); } """ self.WriteValidUnitTest(func, file, valid_test, { @@ -4305,11 +5665,27 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { .WillOnce(SetArgumentPointee<1>(kNewServiceId)); cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>(); GLuint temp = kNewClientId; - SpecializedSetup<cmds::%(name)s, 0>(true); + SpecializedSetup<cmds::%(name)s, 0>(true);""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true);""" + valid_test += """ cmd->Init(1, &temp); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp))); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_EQ(GL_NO_ERROR, GetGLError());""" + if func.IsUnsafe(): + valid_test += """ + GLuint service_id; + EXPECT_TRUE(Get%(resource_name)sServiceId(kNewClientId, &service_id)); + EXPECT_EQ(kNewServiceId, service_id); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, + ExecuteImmediateCmd(*cmd, sizeof(temp))); +} +""" + else: + valid_test += """ EXPECT_TRUE(Get%(resource_name)s(kNewClientId) != NULL); } """ @@ -4321,7 +5697,17 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs) { EXPECT_CALL(*gl_, %(gl_func_name)s(_, _)).Times(0); cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>(); SpecializedSetup<cmds::%(name)s, 0>(false); - cmd->Init(1, &client_%(resource_name)s_id_); + cmd->Init(1, &client_%(resource_name)s_id_);""" + if func.IsUnsafe(): + invalid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kInvalidArguments, + ExecuteImmediateCmd(*cmd, sizeof(&client_%(resource_name)s_id_))); + decoder_->set_unsafe_es3_apis_enabled(false); +} +""" + else: + invalid_test += """ EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(&client_%(resource_name)s_id_))); } @@ -4431,26 +5817,61 @@ class CreateHandler(TypeHandler): """Overrriden from TypeHandler.""" func.AddCmdArg(Argument("client_id", 'uint32_t')) + def __GetResourceType(self, func): + if func.return_type == "GLsync": + return "Sync" + else: + return func.name[6:] # Create* + def WriteServiceUnitTest(self, func, file, *extras): """Overrriden from TypeHandler.""" valid_test = """ TEST_P(%(test_name)s, %(name)sValidArgs) { - EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)) - .WillOnce(Return(kNewServiceId)); + %(id_type_cast)sEXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)) + .WillOnce(Return(%(const_service_id)s)); SpecializedSetup<cmds::%(name)s, 0>(true); cmds::%(name)s cmd; - cmd.Init(%(args)s%(comma)skNewClientId); + cmd.Init(%(args)s%(comma)skNewClientId);""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true);""" + valid_test += """ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - EXPECT_TRUE(Get%(resource_type)s(kNewClientId) != NULL); + EXPECT_EQ(GL_NO_ERROR, GetGLError());""" + if func.IsUnsafe(): + valid_test += """ + %(return_type)s service_id = 0; + EXPECT_TRUE(Get%(resource_type)sServiceId(kNewClientId, &service_id)); + EXPECT_EQ(%(const_service_id)s, service_id); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} +""" + else: + valid_test += """ + EXPECT_TRUE(Get%(resource_type)s(kNewClientId)); } """ comma = "" - if len(func.GetOriginalArgs()): - comma =", " + cmd_arg_count = 0 + for arg in func.GetOriginalArgs(): + if not arg.IsConstant(): + cmd_arg_count += 1 + if cmd_arg_count: + comma = ", " + if func.return_type == 'GLsync': + id_type_cast = ("const GLsync kNewServiceIdGLuint = reinterpret_cast" + "<GLsync>(kNewServiceId);\n ") + const_service_id = "kNewServiceIdGLuint" + else: + id_type_cast = "" + const_service_id = "kNewServiceId" self.WriteValidUnitTest(func, file, valid_test, { 'comma': comma, - 'resource_type': func.name[6:], + 'resource_type': self.__GetResourceType(func), + 'return_type': func.return_type, + 'id_type_cast': id_type_cast, + 'const_service_id': const_service_id, }, *extras) invalid_test = """ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { @@ -4467,11 +5888,33 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { def WriteHandlerImplementation (self, func, file): """Overrriden from TypeHandler.""" - file.Write(" uint32_t client_id = c.client_id;\n") - file.Write(" if (!%sHelper(%s)) {\n" % - (func.name, func.MakeCmdArgString(""))) - file.Write(" return error::kInvalidArguments;\n") - file.Write(" }\n") + if func.IsUnsafe(): + code = """ uint32_t client_id = c.client_id; + %(return_type)s service_id = 0; + if (group_->Get%(resource_name)sServiceId(client_id, &service_id)) { + return error::kInvalidArguments; + } + service_id = %(gl_func_name)s(%(gl_args)s); + if (service_id) { + group_->Add%(resource_name)sId(client_id, service_id); + } +""" + else: + code = """ uint32_t client_id = c.client_id; + if (Get%(resource_name)s(client_id)) { + return error::kInvalidArguments; + } + %(return_type)s service_id = %(gl_func_name)s(%(gl_args)s); + if (service_id) { + Create%(resource_name)s(client_id, service_id%(gl_args_with_comma)s); + } +""" + file.Write(code % { + 'resource_name': self.__GetResourceType(func), + 'return_type': func.return_type, + 'gl_func_name': func.GetGLFunctionName(), + 'gl_args': func.MakeOriginalArgString(""), + 'gl_args_with_comma': func.MakeOriginalArgString("", True) }) def WriteGLES2Implementation(self, func, file): """Overrriden from TypeHandler.""" @@ -4484,14 +5927,21 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { for arg in func.GetOriginalArgs(): arg.WriteClientSideValidationCode(file, func) file.Write(" GLuint client_id;\n") - file.Write( - " GetIdHandler(id_namespaces::kProgramsAndShaders)->\n") + if func.return_type == "GLsync": + file.Write( + " GetIdHandler(id_namespaces::kSyncs)->\n") + else: + file.Write( + " GetIdHandler(id_namespaces::kProgramsAndShaders)->\n") file.Write(" MakeIds(this, 0, 1, &client_id);\n") file.Write(" helper_->%s(%s);\n" % (func.name, func.MakeCmdArgString(""))) file.Write(' GPU_CLIENT_LOG("returned " << client_id);\n') file.Write(" CheckGLError();\n") - file.Write(" return client_id;\n") + if func.return_type == "GLsync": + file.Write(" return reinterpret_cast<GLsync>(client_id);\n") + else: + file.Write(" return client_id;\n") file.Write("}\n") file.Write("\n") @@ -4504,6 +5954,9 @@ class DeleteHandler(TypeHandler): def WriteServiceImplementation(self, func, file): """Overrriden from TypeHandler.""" + if func.IsUnsafe(): + TypeHandler.WriteServiceImplementation(self, func, file) + # HandleDeleteShader and HandleDeleteProgram are manually written. pass def WriteGLES2Implementation(self, func, file): @@ -4524,6 +5977,25 @@ class DeleteHandler(TypeHandler): file.Write("}\n") file.Write("\n") + def WriteHandlerImplementation (self, func, file): + """Overrriden from TypeHandler.""" + assert len(func.GetOriginalArgs()) == 1 + arg = func.GetOriginalArgs()[0] + if func.IsUnsafe(): + file.Write(""" %(arg_type)s service_id = 0; + if (group_->Get%(resource_type)sServiceId(%(arg_name)s, &service_id)) { + glDelete%(resource_type)s(service_id); + group_->Remove%(resource_type)sId(%(arg_name)s); + } else { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "gl%(func_name)s", "unknown %(arg_name)s"); + } +""" % { 'resource_type': func.GetInfo('resource_type'), + 'arg_name': arg.name, + 'arg_type': arg.type, + 'func_name': func.original_name }) + else: + file.Write(" %sHelper(%s);\n" % (func.original_name, arg.name)) class DELnHandler(TypeHandler): """Handler for glDelete___ type functions.""" @@ -4605,10 +6077,25 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { .Times(1); cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>(); SpecializedSetup<cmds::%(name)s, 0>(true); - cmd.Init(1, &client_%(resource_name)s_id_); + cmd.Init(1, &client_%(resource_name)s_id_);""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true);""" + valid_test += """ EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(client_%(resource_name)s_id_))); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_EQ(GL_NO_ERROR, GetGLError());""" + if func.IsUnsafe(): + valid_test += """ + EXPECT_FALSE(Get%(upper_resource_name)sServiceId( + client_%(resource_name)s_id_, NULL)); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, + ExecuteImmediateCmd(cmd, sizeof(client_%(resource_name)s_id_))); +} +""" + else: + valid_test += """ EXPECT_TRUE( Get%(upper_resource_name)s(client_%(resource_name)s_id_) == NULL); } @@ -4622,7 +6109,19 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs) { cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>(); SpecializedSetup<cmds::%(name)s, 0>(false); GLuint temp = kInvalidClientId; - cmd.Init(1, &temp); + cmd.Init(1, &temp);""" + if func.IsUnsafe(): + invalid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, + ExecuteImmediateCmd(cmd, sizeof(temp))); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, + ExecuteImmediateCmd(cmd, sizeof(temp))); +} +""" + else: + invalid_test += """ EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); } @@ -4636,8 +6135,20 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs) { def WriteImmediateHandlerImplementation (self, func, file): """Overrriden from TypeHandler.""" - file.Write(" %sHelper(n, %s);\n" % - (func.original_name, func.GetLastOriginalArg().name)) + if func.IsUnsafe(): + file.Write(""" for (GLsizei ii = 0; ii < n; ++ii) { + GLuint service_id = 0; + if (group_->Get%(resource_type)sServiceId( + %(last_arg_name)s[ii], &service_id)) { + glDelete%(resource_type)ss(1, &service_id); + group_->Remove%(resource_type)sId(%(last_arg_name)s[ii]); + } + } +""" % { 'resource_type': func.GetInfo('resource_type'), + 'last_arg_name': func.GetLastOriginalArg().name }) + else: + file.Write(" %sHelper(n, %s);\n" % + (func.original_name, func.GetLastOriginalArg().name)) def WriteGLES2Implementation(self, func, file): """Overrriden from TypeHandler.""" @@ -4783,8 +6294,8 @@ class GETnHandler(TypeHandler): """Overrriden from TypeHandler.""" self.WriteServiceHandlerFunctionHeader(func, file) last_arg = func.GetLastOriginalArg() - - all_but_last_args = func.GetOriginalArgs()[:-1] + # All except shm_id and shm_offset. + all_but_last_args = func.GetCmdArgs()[:-2] for arg in all_but_last_args: arg.WriteGetCode(file) @@ -4792,11 +6303,13 @@ class GETnHandler(TypeHandler): GLsizei num_values = 0; GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( - c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); - %(last_arg_type)s params = result ? result->GetData() : NULL; + c.%(last_arg_name)s_shm_id, c.%(last_arg_name)s_shm_offset, + Result::ComputeSize(num_values)); + %(last_arg_type)s %(last_arg_name)s = result ? result->GetData() : NULL; """ file.Write(code % { 'last_arg_type': last_arg.type, + 'last_arg_name': last_arg.name, 'func_name': func.name, }) func.WriteHandlerValidation(file) @@ -4841,8 +6354,19 @@ class GETnHandler(TypeHandler): for arg in func.GetOriginalArgs(): arg.WriteClientSideValidationCode(file, func) all_but_last_args = func.GetOriginalArgs()[:-1] - arg_string = ( - ", ".join(["%s" % arg.name for arg in all_but_last_args])) + args = [] + has_length_arg = False + for arg in all_but_last_args: + if arg.type == 'GLsync': + args.append('ToGLuint(%s)' % arg.name) + elif arg.name.endswith('size') and arg.type == 'GLsizei': + continue + elif arg.name == 'length': + has_length_arg = True + continue + else: + args.append(arg.name) + arg_string = ", ".join(args) all_arg_string = ( ", ".join([ "%s" % arg.name @@ -4860,12 +6384,18 @@ class GETnHandler(TypeHandler): helper_->%(func_name)s(%(arg_string)s, GetResultShmId(), GetResultShmOffset()); WaitForCmd(); - result->CopyResult(params); + result->CopyResult(%(last_arg_name)s); GPU_CLIENT_LOG_CODE_BLOCK({ for (int32_t i = 0; i < result->GetNumResults(); ++i) { GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); } - }); + });""" + if has_length_arg: + code += """ + if (length) { + *length = result->GetNumResults(); + }""" + code += """ CheckGLError(); } """ @@ -4873,6 +6403,7 @@ class GETnHandler(TypeHandler): 'func_name': func.name, 'arg_string': arg_string, 'all_arg_string': all_arg_string, + 'last_arg_name': func.GetLastOriginalArg().name, }) def WriteGLES2ImplementationUnitTest(self, func, file): @@ -4882,24 +6413,27 @@ TEST_F(GLES2ImplementationTest, %(name)s) { struct Cmds { cmds::%(name)s cmd; }; - typedef cmds::%(name)s::Result Result; - Result::Type result = 0; + typedef cmds::%(name)s::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = GetExpectedResultMemory( + sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(%(cmd_args)s, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->%(name)s(%(args)s, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); } """ first_cmd_arg = func.GetCmdArgs()[0].GetValidNonCachedClientSideCmdArg(func) if not first_cmd_arg: return - first_gl_arg = func.GetCmdArgs()[0].GetValidNonCachedClientSideArg(func) + first_gl_arg = func.GetOriginalArgs()[0].GetValidNonCachedClientSideArg( + func) + cmd_arg_strings = [first_cmd_arg] for arg in func.GetCmdArgs()[1:-2]: cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func)) @@ -4927,32 +6461,61 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { EXPECT_CALL(*gl_, %(gl_func_name)s(%(local_gl_args)s)); result->size = 0; cmds::%(name)s cmd; - cmd.Init(%(args)s); + cmd.Init(%(cmd_args)s);""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true);""" + valid_test += """ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( %(valid_pname)s), result->GetNumResults()); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_EQ(GL_NO_ERROR, GetGLError());""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));""" + valid_test += """ } """ gl_arg_strings = [] + cmd_arg_strings = [] valid_pname = '' for arg in func.GetOriginalArgs()[:-1]: - arg_value = arg.GetValidGLArg(func) - gl_arg_strings.append(arg_value) + if arg.name == 'length': + gl_arg_value = 'nullptr' + elif arg.name.endswith('size'): + gl_arg_value = ("decoder_->GetGLES2Util()->GLGetNumValuesReturned(%s)" % + valid_pname) + elif arg.type == 'GLsync': + gl_arg_value = 'reinterpret_cast<GLsync>(kServiceSyncId)' + else: + gl_arg_value = arg.GetValidGLArg(func) + gl_arg_strings.append(gl_arg_value) if arg.name == 'pname': - valid_pname = arg_value + valid_pname = gl_arg_value + if arg.name.endswith('size') or arg.name == 'length': + continue + if arg.type == 'GLsync': + arg_value = 'client_sync_id_' + else: + arg_value = arg.GetValidArg(func) + cmd_arg_strings.append(arg_value) if func.GetInfo('gl_test_func') == 'glGetIntegerv': gl_arg_strings.append("_") else: gl_arg_strings.append("result->GetData()") + cmd_arg_strings.append("shared_memory_id_") + cmd_arg_strings.append("shared_memory_offset_") self.WriteValidUnitTest(func, file, valid_test, { 'local_gl_args': ", ".join(gl_arg_strings), + 'cmd_args': ", ".join(cmd_arg_strings), 'valid_pname': valid_pname, }, *extras) - invalid_test = """ + if not func.IsUnsafe(): + invalid_test = """ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0); SpecializedSetup<cmds::%(name)s, 0>(false); @@ -4965,7 +6528,7 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { EXPECT_EQ(0u, result->size);%(gl_error_test)s } """ - self.WriteInvalidUnitTest(func, file, invalid_test, *extras) + self.WriteInvalidUnitTest(func, file, invalid_test, *extras) class ArrayArgTypeHandler(TypeHandler): """Base class for type handlers that handle args that are arrays""" @@ -5048,10 +6611,20 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { EXPECT_CALL( *gl_, %(gl_func_name)s(%(gl_args)s, %(data_ref)sreinterpret_cast< - %(data_type)s*>(ImmediateDataAddress(&cmd)))); + %(data_type)s*>(ImmediateDataAddress(&cmd))));""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true);""" + valid_test += """ EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_EQ(GL_NO_ERROR, GetGLError());""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, + ExecuteImmediateCmd(cmd, sizeof(temp)));""" + valid_test += """ } """ gl_arg_strings = [ @@ -5071,13 +6644,32 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { invalid_test = """ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { - cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>(); + cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();""" + if func.IsUnsafe(): + invalid_test += """ + EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_any_args)s, _)).Times(1); +""" + else: + invalid_test += """ EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_any_args)s, _)).Times(0); +""" + invalid_test += """ SpecializedSetup<cmds::%(name)s, 0>(false); %(data_type)s temp[%(data_count)s] = { %(data_value)s, }; - cmd.Init(%(all_but_last_args)s, &temp[0]); + cmd.Init(%(all_but_last_args)s, &temp[0]);""" + if func.IsUnsafe(): + invalid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::%(parse_result)s, - ExecuteImmediateCmd(cmd, sizeof(temp)));%(gl_error_test)s + ExecuteImmediateCmd(cmd, sizeof(temp))); + decoder_->set_unsafe_es3_apis_enabled(false); +} +""" + else: + invalid_test += """ + EXPECT_EQ(error::%(parse_result)s, + ExecuteImmediateCmd(cmd, sizeof(temp))); + %(gl_error_test)s } """ self.WriteInvalidUnitTest(func, file, invalid_test, extra, *extras) @@ -5095,6 +6687,10 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { file.Write(" return error::kOutOfBounds;\n") file.Write(" }\n") + def __NeedsToCalcDataCount(self, func): + use_count_func = func.GetInfo('use_count_func') + return use_count_func != None and use_count_func != False + def WriteGLES2Implementation(self, func, file): """Overrriden from TypeHandler.""" impl_func = func.GetInfo('impl_func') @@ -5106,11 +6702,16 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { file.Write(" GPU_CLIENT_SINGLE_THREAD_CHECK();\n") func.WriteDestinationInitalizationValidation(file) self.WriteClientGLCallLog(func, file) - last_arg_name = func.GetLastOriginalArg().name - values_str = ' << ", " << '.join( - ["%s[%d]" % (last_arg_name, ndx) \ - for ndx in range(0, self.GetArrayCount(func))]) - file.Write(' GPU_CLIENT_LOG("values: " << %s);\n' % values_str) + + if self.__NeedsToCalcDataCount(func): + file.Write(" size_t count = GLES2Util::Calc%sDataCount(%s);\n" % + (func.name, func.GetOriginalArgs()[0].name)) + file.Write(" DCHECK_LE(count, %du);\n" % self.GetArrayCount(func)) + else: + file.Write(" size_t count = %d;" % self.GetArrayCount(func)) + file.Write(" for (size_t ii = 0; ii < count; ++ii)\n") + file.Write(' GPU_CLIENT_LOG("value[" << ii << "]: " << %s[ii]);\n' % + func.GetLastOriginalArg().name) for arg in func.GetOriginalArgs(): arg.WriteClientSideValidationCode(file, func) file.Write(" helper_->%sImmediate(%s);\n" % @@ -5160,14 +6761,24 @@ TEST_F(GLES2ImplementationTest, %(name)s) { """Overrriden from TypeHandler.""" file.Write(" static uint32_t ComputeDataSize() {\n") file.Write(" return static_cast<uint32_t>(\n") - file.Write(" sizeof(%s) * %d); // NOLINT\n" % + file.Write(" sizeof(%s) * %d);\n" % (self.GetArrayType(func), self.GetArrayCount(func))) file.Write(" }\n") file.Write("\n") + if self.__NeedsToCalcDataCount(func): + file.Write(" static uint32_t ComputeEffectiveDataSize(%s %s) {\n" % + (func.GetOriginalArgs()[0].type, + func.GetOriginalArgs()[0].name)) + file.Write(" return static_cast<uint32_t>(\n") + file.Write(" sizeof(%s) * GLES2Util::Calc%sDataCount(%s));\n" % + (self.GetArrayType(func), func.original_name, + func.GetOriginalArgs()[0].name)) + file.Write(" }\n") + file.Write("\n") file.Write(" static uint32_t ComputeSize() {\n") file.Write(" return static_cast<uint32_t>(\n") file.Write( - " sizeof(ValueType) + ComputeDataSize()); // NOLINT\n") + " sizeof(ValueType) + ComputeDataSize());\n") file.Write(" }\n") file.Write("\n") @@ -5190,7 +6801,17 @@ TEST_F(GLES2ImplementationTest, %(name)s) { for arg in args: file.Write(" %s = _%s;\n" % (arg.name, arg.name)) file.Write(" memcpy(ImmediateDataAddress(this),\n") - file.Write(" _%s, ComputeDataSize());\n" % last_arg.name) + if self.__NeedsToCalcDataCount(func): + file.Write(" _%s, ComputeEffectiveDataSize(%s));" % + (last_arg.name, func.GetOriginalArgs()[0].name)) + file.Write(""" + DCHECK_GE(ComputeDataSize(), ComputeEffectiveDataSize(%(arg)s)); + char* pointer = reinterpret_cast<char*>(ImmediateDataAddress(this)) + + ComputeEffectiveDataSize(%(arg)s); + memset(pointer, 0, ComputeDataSize() - ComputeEffectiveDataSize(%(arg)s)); +""" % { 'arg': func.GetOriginalArgs()[0].name, }) + else: + file.Write(" _%s, ComputeDataSize());\n" % last_arg.name) file.Write(" }\n") file.Write("\n") @@ -5317,10 +6938,20 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { reinterpret_cast<%(data_type)s*>(ImmediateDataAddress(&cmd)))); SpecializedSetup<cmds::%(name)s, 0>(true); %(data_type)s temp[%(data_count)s * 2] = { 0, }; - cmd.Init(%(args)s, &temp[0]); + cmd.Init(%(args)s, &temp[0]);""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true);""" + valid_test += """ EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_EQ(GL_NO_ERROR, GetGLError());""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, + ExecuteImmediateCmd(cmd, sizeof(temp)));""" + valid_test += """ } """ gl_arg_strings = [] @@ -5374,13 +7005,13 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { file.Write(" GPU_CLIENT_SINGLE_THREAD_CHECK();\n") func.WriteDestinationInitalizationValidation(file) self.WriteClientGLCallLog(func, file) - last_arg_name = func.GetLastOriginalArg().name + last_pointer_name = func.GetLastOriginalPointerArg().name file.Write(""" GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < count; ++i) { """) values_str = ' << ", " << '.join( ["%s[%d + i * %d]" % ( - last_arg_name, ndx, self.GetArrayCount(func)) for ndx in range( + last_pointer_name, ndx, self.GetArrayCount(func)) for ndx in range( 0, self.GetArrayCount(func))]) file.Write(' GPU_CLIENT_LOG(" " << i << ": " << %s);\n' % values_str) file.Write(" }\n });\n") @@ -5408,18 +7039,26 @@ TEST_F(GLES2ImplementationTest, %(name)s) { data[ii][jj] = static_cast<%(type)s>(ii * %(count)d + jj); } } - expected.cmd.Init(%(cmd_args)s, &data[0][0]); - gl_->%(name)s(%(args)s, &data[0][0]); + expected.cmd.Init(%(cmd_args)s); + gl_->%(name)s(%(args)s); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } """ - cmd_arg_strings = [ - arg.GetValidClientSideCmdArg(func) for arg in func.GetCmdArgs()[0:-2] - ] + cmd_arg_strings = [] + for arg in func.GetCmdArgs(): + if arg.name.endswith("_shm_id"): + cmd_arg_strings.append("&data[0][0]") + elif arg.name.endswith("_shm_offset"): + continue + else: + cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func)) gl_arg_strings = [] count_param = 0 - for arg in func.GetOriginalArgs()[0:-1]: - valid_value = arg.GetValidClientSideArg(func) + for arg in func.GetOriginalArgs(): + if arg.IsPointer(): + valid_value = "&data[0][0]" + else: + valid_value = arg.GetValidClientSideArg(func) gl_arg_strings.append(valid_value) if arg.name == "count": count_param = int(valid_value) @@ -5448,7 +7087,7 @@ TEST_F(GLES2ImplementationTest, %(name)sInvalidConstantArg%(invalid_index)d) { data[ii][jj] = static_cast<%(type)s>(ii * %(count)d + jj); } } - gl_->%(name)s(%(args)s, &data[0][0]); + gl_->%(name)s(%(args)s); EXPECT_TRUE(NoCommandsWritten()); EXPECT_EQ(%(gl_error)s, CheckError()); } @@ -5456,9 +7095,11 @@ TEST_F(GLES2ImplementationTest, %(name)sInvalidConstantArg%(invalid_index)d) { for invalid_arg in constants: gl_arg_strings = [] invalid = invalid_arg.GetInvalidArg(func) - for arg in func.GetOriginalArgs()[0:-1]: + for arg in func.GetOriginalArgs(): if arg is invalid_arg: gl_arg_strings.append(invalid[0]) + elif arg.IsPointer(): + gl_arg_strings.append("&data[0][0]") else: valid_value = arg.GetValidClientSideArg(func) gl_arg_strings.append(valid_value) @@ -5501,28 +7142,24 @@ TEST_F(GLES2ImplementationTest, %(name)sInvalidConstantArg%(invalid_index)d) { def WriteImmediateCmdInit(self, func, file): """Overrriden from TypeHandler.""" - last_arg = func.GetLastOriginalArg() - file.Write(" void Init(%s, %s _%s) {\n" % - (func.MakeTypedCmdArgString("_"), - last_arg.type, last_arg.name)) + file.Write(" void Init(%s) {\n" % + func.MakeTypedInitString("_")) file.Write(" SetHeader(_count);\n") args = func.GetCmdArgs() for arg in args: file.Write(" %s = _%s;\n" % (arg.name, arg.name)) file.Write(" memcpy(ImmediateDataAddress(this),\n") - file.Write(" _%s, ComputeDataSize(_count));\n" % last_arg.name) + pointer_arg = func.GetLastOriginalPointerArg() + file.Write(" _%s, ComputeDataSize(_count));\n" % pointer_arg.name) file.Write(" }\n") file.Write("\n") def WriteImmediateCmdSet(self, func, file): """Overrriden from TypeHandler.""" - last_arg = func.GetLastOriginalArg() - copy_args = func.MakeCmdArgString("_", False) - file.Write(" void* Set(void* cmd%s, %s _%s) {\n" % - (func.MakeTypedCmdArgString("_", True), - last_arg.type, last_arg.name)) - file.Write(" static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" % - (copy_args, last_arg.name)) + file.Write(" void* Set(void* cmd%s) {\n" % + func.MakeTypedInitString("_", True)) + file.Write(" static_cast<ValueType*>(cmd)->Init(%s);\n" % + func.MakeInitString("_")) file.Write(" const uint32_t size = ComputeSize(_count);\n") file.Write(" return NextImmediateCmdAddressTotalSize<ValueType>(" "cmd, size);\n") @@ -5549,7 +7186,7 @@ TEST_F(GLES2ImplementationTest, %(name)sInvalidConstantArg%(invalid_index)d) { def WriteImmediateFormatTest(self, func, file): """Overrriden from TypeHandler.""" - args = func.GetCmdArgs() + args = func.GetOriginalArgs() count_param = 0 for arg in args: if arg.name == "count": @@ -5570,13 +7207,20 @@ TEST_F(GLES2ImplementationTest, %(name)sInvalidConstantArg%(invalid_index)d) { file.Write(" void* next_cmd = cmd.Set(\n") file.Write(" &cmd") for value, arg in enumerate(args): - file.Write(",\n static_cast<%s>(%d)" % (arg.type, value + 1)) - file.Write(",\n data);\n") + if arg.IsPointer(): + file.Write(",\n data") + elif arg.IsConstant(): + continue + else: + file.Write(",\n static_cast<%s>(%d)" % (arg.type, value + 1)) + file.Write(");\n") file.Write(" EXPECT_EQ(static_cast<uint32_t>(cmds::%s::kCmdId),\n" % func.name) file.Write(" cmd.header.command);\n") file.Write(" EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);\n") for value, arg in enumerate(args): + if arg.IsPointer() or arg.IsConstant(): + continue file.Write(" EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" % (arg.type, value + 1, arg.name)) file.Write(" CheckBytesWrittenMatchesExpectedSize(\n") @@ -5586,6 +7230,332 @@ TEST_F(GLES2ImplementationTest, %(name)sInvalidConstantArg%(invalid_index)d) { file.Write("}\n") file.Write("\n") +class PUTSTRHandler(ArrayArgTypeHandler): + """Handler for functions that pass a string array.""" + + def __init__(self): + ArrayArgTypeHandler.__init__(self) + + def __GetDataArg(self, func): + """Return the argument that points to the 2D char arrays""" + for arg in func.GetOriginalArgs(): + if arg.IsPointer2D(): + return arg + return None + + def __GetLengthArg(self, func): + """Return the argument that holds length for each char array""" + for arg in func.GetOriginalArgs(): + if arg.IsPointer() and not arg.IsPointer2D(): + return arg + return None + + def WriteGLES2Implementation(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s GLES2Implementation::%s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write(" GPU_CLIENT_SINGLE_THREAD_CHECK();\n") + func.WriteDestinationInitalizationValidation(file) + self.WriteClientGLCallLog(func, file) + data_arg = self.__GetDataArg(func) + length_arg = self.__GetLengthArg(func) + log_code_block = """ GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei ii = 0; ii < count; ++ii) { + if (%(data)s[ii]) {""" + if length_arg == None: + log_code_block += """ + GPU_CLIENT_LOG(" " << ii << ": ---\\n" << %(data)s[ii] << "\\n---");""" + else: + log_code_block += """ + if (%(length)s && %(length)s[ii] >= 0) { + const std::string my_str(%(data)s[ii], %(length)s[ii]); + GPU_CLIENT_LOG(" " << ii << ": ---\\n" << my_str << "\\n---"); + } else { + GPU_CLIENT_LOG(" " << ii << ": ---\\n" << %(data)s[ii] << "\\n---"); + }""" + log_code_block += """ + } else { + GPU_CLIENT_LOG(" " << ii << ": NULL"); + } + } + }); +""" + file.Write(log_code_block % { + 'data': data_arg.name, + 'length': length_arg.name if not length_arg == None else '' + }) + for arg in func.GetOriginalArgs(): + arg.WriteClientSideValidationCode(file, func) + + bucket_args = [] + for arg in func.GetOriginalArgs(): + if arg.name == 'count' or arg == self.__GetLengthArg(func): + continue + if arg == self.__GetDataArg(func): + bucket_args.append('kResultBucketId') + else: + bucket_args.append(arg.name) + code_block = """ + if (!PackStringsToBucket(count, %(data)s, %(length)s, "gl%(func_name)s")) { + return; + } + helper_->%(func_name)sBucket(%(bucket_args)s); + helper_->SetBucketSize(kResultBucketId, 0); + CheckGLError(); +} + +""" + file.Write(code_block % { + 'data': data_arg.name, + 'length': length_arg.name if not length_arg == None else 'NULL', + 'func_name': func.name, + 'bucket_args': ', '.join(bucket_args), + }) + + def WriteGLES2ImplementationUnitTest(self, func, file): + """Overrriden from TypeHandler.""" + code = """ +TEST_F(GLES2ImplementationTest, %(name)s) { + const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const char* kString1 = "happy"; + const char* kString2 = "ending"; + const size_t kString1Size = ::strlen(kString1) + 1; + const size_t kString2Size = ::strlen(kString2) + 1; + const size_t kHeaderSize = sizeof(GLint) * 3; + const size_t kSourceSize = kHeaderSize + kString1Size + kString2Size; + const size_t kPaddedHeaderSize = + transfer_buffer_->RoundToAlignment(kHeaderSize); + const size_t kPaddedString1Size = + transfer_buffer_->RoundToAlignment(kString1Size); + const size_t kPaddedString2Size = + transfer_buffer_->RoundToAlignment(kString2Size); + struct Cmds { + cmd::SetBucketSize set_bucket_size; + cmd::SetBucketData set_bucket_header; + cmd::SetToken set_token1; + cmd::SetBucketData set_bucket_data1; + cmd::SetToken set_token2; + cmd::SetBucketData set_bucket_data2; + cmd::SetToken set_token3; + cmds::%(name)sBucket cmd_bucket; + cmd::SetBucketSize clear_bucket_size; + }; + + ExpectedMemoryInfo mem0 = GetExpectedMemory(kPaddedHeaderSize); + ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size); + ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size); + + Cmds expected; + expected.set_bucket_size.Init(kBucketId, kSourceSize); + expected.set_bucket_header.Init( + kBucketId, 0, kHeaderSize, mem0.id, mem0.offset); + expected.set_token1.Init(GetNextToken()); + expected.set_bucket_data1.Init( + kBucketId, kHeaderSize, kString1Size, mem1.id, mem1.offset); + expected.set_token2.Init(GetNextToken()); + expected.set_bucket_data2.Init( + kBucketId, kHeaderSize + kString1Size, kString2Size, mem2.id, + mem2.offset); + expected.set_token3.Init(GetNextToken()); + expected.cmd_bucket.Init(%(bucket_args)s); + expected.clear_bucket_size.Init(kBucketId, 0); + const char* kStrings[] = { kString1, kString2 }; + gl_->%(name)s(%(gl_args)s); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} +""" + gl_args = [] + bucket_args = [] + for arg in func.GetOriginalArgs(): + if arg == self.__GetDataArg(func): + gl_args.append('kStrings') + bucket_args.append('kBucketId') + elif arg == self.__GetLengthArg(func): + gl_args.append('NULL') + elif arg.name == 'count': + gl_args.append('2') + else: + gl_args.append(arg.GetValidClientSideArg(func)) + bucket_args.append(arg.GetValidClientSideArg(func)) + file.Write(code % { + 'name': func.name, + 'gl_args': ", ".join(gl_args), + 'bucket_args': ", ".join(bucket_args), + }) + + if self.__GetLengthArg(func) == None: + return + code = """ +TEST_F(GLES2ImplementationTest, %(name)sWithLength) { + const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const char* kString = "foobar******"; + const size_t kStringSize = 6; // We only need "foobar". + const size_t kHeaderSize = sizeof(GLint) * 2; + const size_t kSourceSize = kHeaderSize + kStringSize + 1; + const size_t kPaddedHeaderSize = + transfer_buffer_->RoundToAlignment(kHeaderSize); + const size_t kPaddedStringSize = + transfer_buffer_->RoundToAlignment(kStringSize + 1); + struct Cmds { + cmd::SetBucketSize set_bucket_size; + cmd::SetBucketData set_bucket_header; + cmd::SetToken set_token1; + cmd::SetBucketData set_bucket_data; + cmd::SetToken set_token2; + cmds::ShaderSourceBucket shader_source_bucket; + cmd::SetBucketSize clear_bucket_size; + }; + + ExpectedMemoryInfo mem0 = GetExpectedMemory(kPaddedHeaderSize); + ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedStringSize); + + Cmds expected; + expected.set_bucket_size.Init(kBucketId, kSourceSize); + expected.set_bucket_header.Init( + kBucketId, 0, kHeaderSize, mem0.id, mem0.offset); + expected.set_token1.Init(GetNextToken()); + expected.set_bucket_data.Init( + kBucketId, kHeaderSize, kStringSize + 1, mem1.id, mem1.offset); + expected.set_token2.Init(GetNextToken()); + expected.shader_source_bucket.Init(%(bucket_args)s); + expected.clear_bucket_size.Init(kBucketId, 0); + const char* kStrings[] = { kString }; + const GLint kLength[] = { kStringSize }; + gl_->%(name)s(%(gl_args)s); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} +""" + gl_args = [] + for arg in func.GetOriginalArgs(): + if arg == self.__GetDataArg(func): + gl_args.append('kStrings') + elif arg == self.__GetLengthArg(func): + gl_args.append('kLength') + elif arg.name == 'count': + gl_args.append('1') + else: + gl_args.append(arg.GetValidClientSideArg(func)) + file.Write(code % { + 'name': func.name, + 'gl_args': ", ".join(gl_args), + 'bucket_args': ", ".join(bucket_args), + }) + + def WriteBucketServiceUnitTest(self, func, file, *extras): + """Overrriden from TypeHandler.""" + cmd_args = [] + cmd_args_with_invalid_id = [] + gl_args = [] + for index, arg in enumerate(func.GetOriginalArgs()): + if arg == self.__GetLengthArg(func): + gl_args.append('_') + elif arg.name == 'count': + gl_args.append('1') + elif arg == self.__GetDataArg(func): + cmd_args.append('kBucketId') + cmd_args_with_invalid_id.append('kBucketId') + gl_args.append('_') + elif index == 0: # Resource ID arg + cmd_args.append(arg.GetValidArg(func)) + cmd_args_with_invalid_id.append('kInvalidClientId') + gl_args.append(arg.GetValidGLArg(func)) + else: + cmd_args.append(arg.GetValidArg(func)) + cmd_args_with_invalid_id.append(arg.GetValidArg(func)) + gl_args.append(arg.GetValidGLArg(func)) + + test = """ +TEST_P(%(test_name)s, %(name)sValidArgs) { + EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)); + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = { kSource0 }; + const char kValidStrEnd = 0; + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kValidStrEnd); + cmds::%(name)s cmd; + cmd.Init(%(cmd_args)s); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));""" + if func.IsUnsafe(): + test += """ + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +""" + test += """ +} +""" + self.WriteValidUnitTest(func, file, test, { + 'cmd_args': ", ".join(cmd_args), + 'gl_args': ", ".join(gl_args), + }, *extras) + + test = """ +TEST_P(%(test_name)s, %(name)sInvalidArgs) { + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = { kSource0 }; + const char kValidStrEnd = 0; + decoder_->set_unsafe_es3_apis_enabled(true); + cmds::%(name)s cmd; + // Test no bucket. + cmd.Init(%(cmd_args)s); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + // Test invalid client. + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kValidStrEnd); + cmd.Init(%(cmd_args_with_invalid_id)s); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} +""" + self.WriteValidUnitTest(func, file, test, { + 'cmd_args': ", ".join(cmd_args), + 'cmd_args_with_invalid_id': ", ".join(cmd_args_with_invalid_id), + }, *extras) + + test = """ +TEST_P(%(test_name)s, %(name)sInvalidHeader) { + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = { kSource0 }; + const char kValidStrEnd = 0; + const GLsizei kCount = static_cast<GLsizei>(arraysize(kSource)); + const GLsizei kTests[] = { + kCount + 1, + 0, + std::numeric_limits<GLsizei>::max(), + -1, + }; + decoder_->set_unsafe_es3_apis_enabled(true); + for (size_t ii = 0; ii < arraysize(kTests); ++ii) { + SetBucketAsCStrings(kBucketId, 1, kSource, kTests[ii], kValidStrEnd); + cmds::%(name)s cmd; + cmd.Init(%(cmd_args)s); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd)); + } +} +""" + self.WriteValidUnitTest(func, file, test, { + 'cmd_args': ", ".join(cmd_args), + }, *extras) + + test = """ +TEST_P(%(test_name)s, %(name)sInvalidStringEnding) { + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = { kSource0 }; + const char kInvalidStrEnd = '*'; + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kInvalidStrEnd); + cmds::%(name)s cmd; + cmd.Init(%(cmd_args)s); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd)); +} +""" + self.WriteValidUnitTest(func, file, test, { + 'cmd_args': ", ".join(cmd_args), + }, *extras) + class PUTXnHandler(ArrayArgTypeHandler): """Handler for glUniform?f functions.""" @@ -5594,7 +7564,13 @@ class PUTXnHandler(ArrayArgTypeHandler): def WriteHandlerImplementation(self, func, file): """Overrriden from TypeHandler.""" - code = """ %(type)s temp[%(count)s] = { %(values)s}; + code = """ %(type)s temp[%(count)s] = { %(values)s};""" + if func.IsUnsafe(): + code += """ + gl%(name)sv(%(location)s, 1, &temp[0]); +""" + else: + code += """ Do%(name)sv(%(location)s, 1, &temp[0]); """ values = "" @@ -5620,9 +7596,18 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { EXPECT_CALL(*gl_, %(name)sv(%(local_args)s)); SpecializedSetup<cmds::%(name)s, 0>(true); cmds::%(name)s cmd; - cmd.Init(%(args)s); + cmd.Init(%(args)s);""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true);""" + valid_test += """ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_EQ(GL_NO_ERROR, GetGLError());""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));""" + valid_test += """ } """ args = func.GetOriginalArgs() @@ -5829,9 +7814,18 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)); SpecializedSetup<cmds::%(name)s, 0>(true); cmds::%(name)s cmd; - cmd.Init(%(args)s%(comma)sshared_memory_id_, shared_memory_offset_); + cmd.Init(%(args)s%(comma)sshared_memory_id_, shared_memory_offset_);""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true);""" + valid_test += """ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_EQ(GL_NO_ERROR, GetGLError());""" + if func.IsUnsafe(): + valid_test += """ + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));""" + valid_test += """ } """ comma = "" @@ -5857,12 +7851,20 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { invalid_test = """ TEST_P(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) { EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0); - SpecializedSetup<cmds::%(name)s, 0>(false); + SpecializedSetup<cmds::%(name)s, 0>(false);""" + if func.IsUnsafe(): + invalid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true);""" + invalid_test += """ cmds::%(name)s cmd; cmd.Init(%(args)s%(comma)skInvalidSharedMemoryId, shared_memory_offset_); EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); cmd.Init(%(args)s%(comma)sshared_memory_id_, kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));""" + if func.IsUnsafe(): + invalid_test += """ + decoder_->set_unsafe_es3_apis_enabled(true);""" + invalid_test += """ } """ self.WriteValidUnitTest(func, file, invalid_test, { @@ -5885,8 +7887,17 @@ TEST_P(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) { """ file.Write(code % {'func_name': func.name}) func.WriteHandlerValidation(file) - file.Write(" *result_dst = %s(%s);\n" % - (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) + if func.IsUnsafe(): + assert func.GetInfo('id_mapping') + assert len(func.GetInfo('id_mapping')) == 1 + assert len(args) == 1 + id_type = func.GetInfo('id_mapping')[0] + file.Write(" %s service_%s = 0;\n" % (args[0].type, id_type.lower())) + file.Write(" *result_dst = group_->Get%sServiceId(%s, &service_%s);\n" % + (id_type, id_type.lower(), id_type.lower())) + else: + file.Write(" *result_dst = %s(%s);\n" % + (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) file.Write(" return error::kNoError;\n") file.Write("}\n") file.Write("\n") @@ -5909,13 +7920,15 @@ TEST_P(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) { file.Write(" return %s;\n" % error_value) file.Write(" }\n") file.Write(" *result = 0;\n") - arg_string = func.MakeOriginalArgString("") - comma = "" - if len(arg_string) > 0: - comma = ", " + assert len(func.GetOriginalArgs()) == 1 + id_arg = func.GetOriginalArgs()[0] + if id_arg.type == 'GLsync': + arg_string = "ToGLuint(%s)" % func.MakeOriginalArgString("") + else: + arg_string = func.MakeOriginalArgString("") file.Write( - " helper_->%s(%s%sGetResultShmId(), GetResultShmOffset());\n" % - (func.name, arg_string, comma)) + " helper_->%s(%s, GetResultShmId(), GetResultShmOffset());\n" % + (func.name, arg_string)) file.Write(" WaitForCmd();\n") file.Write(" %s result_value = *result" % func.return_type) if func.return_type == "GLboolean": @@ -5939,20 +7952,23 @@ TEST_F(GLES2ImplementationTest, %(name)s) { Cmds expected; ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(cmds::%(name)s::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + expected.cmd.Init(%(cmd_id_value)s, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32_t(1))) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) .RetiresOnSaturation(); - GLboolean result = gl_->%(name)s(1); + GLboolean result = gl_->%(name)s(%(gl_id_value)s); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); EXPECT_TRUE(result); } """ + args = func.GetOriginalArgs() + assert len(args) == 1 file.Write(code % { - 'name': func.name, - }) + 'name': func.name, + 'cmd_id_value': args[0].GetValidClientSideCmdArg(func), + 'gl_id_value': args[0].GetValidClientSideArg(func) }) class STRnHandler(TypeHandler): @@ -6094,6 +8110,14 @@ class NamedType(object): self.invalid = info['invalid'] else: self.invalid = [] + if 'valid_es3' in info: + self.valid_es3 = info['valid_es3'] + else: + self.valid_es3 = [] + if 'deprecated_es3' in info: + self.deprecated_es3 = info['deprecated_es3'] + else: + self.deprecated_es3 = [] def GetType(self): return self.info['type'] @@ -6104,6 +8128,12 @@ class NamedType(object): def GetValidValues(self): return self.valid + def GetValidValuesES3(self): + return self.valid_es3 + + def GetDeprecatedValuesES3(self): + return self.deprecated_es3 + def IsConstant(self): if not 'is_complete' in self.info: return False @@ -6143,6 +8173,10 @@ class Argument(object): """Returns true if argument is a pointer.""" return False + def IsPointer2D(self): + """Returns true if argument is a 2D pointer.""" + return False + def IsConstant(self): """Returns true if the argument has only one valid value.""" return False @@ -6172,7 +8206,11 @@ class Argument(object): if valid_arg != None: return valid_arg + if self.IsPointer(): + return 'nullptr' index = func.GetOriginalArgs().index(self) + if self.type == 'GLsync': + return ("reinterpret_cast<GLsync>(%d)" % (index + 1)) return str(index + 1) def GetValidClientSideCmdArg(self, func): @@ -6190,13 +8228,19 @@ class Argument(object): def GetValidGLArg(self, func): """Gets a valid GL value for this argument.""" - return self.GetValidArg(func) + value = self.GetValidArg(func) + if self.type == 'GLsync': + return ("reinterpret_cast<GLsync>(%s)" % value) + return value def GetValidNonCachedClientSideArg(self, func): """Returns a valid value for this argument in a GL call. Using the value will produce a command buffer service invocation. Returns None if there is no such value.""" - return '123' + value = '123' + if self.type == 'GLsync': + return ("reinterpret_cast<GLsync>(%s)" % value) + return value def GetValidNonCachedClientSideCmdArg(self, func): """Returns a valid value for this argument in a command buffer command. @@ -6223,8 +8267,12 @@ class Argument(object): def WriteGetCode(self, file): """Writes the code to get an argument from a command structure.""" + if self.type == 'GLsync': + my_type = 'GLuint' + else: + my_type = self.type file.Write(" %s %s = static_cast<%s>(c.%s);\n" % - (self.type, self.name, self.type, self.name)) + (my_type, self.name, my_type, self.name)) def WriteValidationCode(self, file, func): """Writes the validation code for an argument.""" @@ -6325,21 +8373,29 @@ class SizeArgument(Argument): def WriteValidationCode(self, file, func): """overridden from Argument.""" - file.Write(" if (%s < 0) {\n" % self.name) - file.Write( - " LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, \"gl%s\", \"%s < 0\");\n" % - (func.original_name, self.name)) - file.Write(" return error::kNoError;\n") - file.Write(" }\n") + if func.IsUnsafe(): + return + code = """ if (%(var_name)s < 0) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "gl%(func_name)s", "%(var_name)s < 0"); + return error::kNoError; + } +""" + file.Write(code % { + "var_name": self.name, + "func_name": func.original_name, + }) def WriteClientSideValidationCode(self, file, func): """overridden from Argument.""" - file.Write(" if (%s < 0) {\n" % self.name) - file.Write( - " SetGLError(GL_INVALID_VALUE, \"gl%s\", \"%s < 0\");\n" % - (func.original_name, self.name)) - file.Write(" return;\n") - file.Write(" }\n") + code = """ if (%(var_name)s < 0) { + SetGLError(GL_INVALID_VALUE, "gl%(func_name)s", "%(var_name)s < 0"); + return; + } +""" + file.Write(code % { + "var_name": self.name, + "func_name": func.original_name, + }) class SizeNotNegativeArgument(SizeArgument): @@ -6358,7 +8414,8 @@ class SizeNotNegativeArgument(SizeArgument): class EnumBaseArgument(Argument): - """Base class for EnumArgument, IntArgument and ValidatedBoolArgument""" + """Base class for EnumArgument, IntArgument, BitfieldArgument, and + ValidatedBoolArgument.""" def __init__(self, name, gl_type, type, gl_error): Argument.__init__(self, name, gl_type) @@ -6376,6 +8433,8 @@ class EnumBaseArgument(Argument): return self.named_type.GetConstantValue() def WriteValidationCode(self, file, func): + if func.IsUnsafe(): + return if self.named_type.IsConstant(): return file.Write(" if (!validators_->%s.IsValid(%s)) {\n" % @@ -6472,7 +8531,7 @@ class EnumArgument(EnumBaseArgument): class IntArgument(EnumBaseArgument): - """A class for a GLint argument that can only except specific values. + """A class for a GLint argument that can only accept specific values. For example glTexImage2D takes a GLint for its internalformat argument instead of a GLenum. @@ -6483,7 +8542,7 @@ class IntArgument(EnumBaseArgument): class ValidatedBoolArgument(EnumBaseArgument): - """A class for a GLboolean argument that can only except specific values. + """A class for a GLboolean argument that can only accept specific values. For example glUniformMatrix takes a GLboolean for it's transpose but it must be false. @@ -6497,6 +8556,18 @@ class ValidatedBoolArgument(EnumBaseArgument): return 'GLES2Util::GetStringBool(%s)' % self.name +class BitFieldArgument(EnumBaseArgument): + """A class for a GLbitfield argument that can only accept specific values. + + For example glFenceSync takes a GLbitfield for its flags argument bit it + must be 0. + """ + + def __init__(self, name, type): + EnumBaseArgument.__init__(self, name, "GLbitfield", type, + "GL_INVALID_VALUE") + + class ImmediatePointerArgument(Argument): """A class that represents an immediate argument to a function. @@ -6527,6 +8598,8 @@ class ImmediatePointerArgument(Argument): def WriteValidationCode(self, file, func): """Overridden from Argument.""" + if self.optional: + return file.Write(" if (%s == NULL) {\n" % self.name) file.Write(" return error::kOutOfBounds;\n") file.Write(" }\n") @@ -6544,39 +8617,6 @@ class ImmediatePointerArgument(Argument): return "static_cast<const void*>(%s)" % self.name -class BucketPointerArgument(Argument): - """A class that represents an bucket argument to a function.""" - - def __init__(self, name, type): - Argument.__init__(self, name, type) - - def AddCmdArgs(self, args): - """Overridden from Argument.""" - pass - - def WriteGetCode(self, file): - """Overridden from Argument.""" - file.Write( - " %s %s = bucket->GetData(0, data_size);\n" % - (self.type, self.name)) - - def WriteValidationCode(self, file, func): - """Overridden from Argument.""" - pass - - def GetImmediateVersion(self): - """Overridden from Argument.""" - return None - - def WriteDestinationInitalizationValidation(self, file, func): - """Overridden from Argument.""" - self.WriteDestinationInitalizationValidatationIfNeeded(file, func) - - def GetLogArg(self): - """Overridden from Argument.""" - return "static_cast<const void*>(%s)" % self.name - - class PointerArgument(Argument): """A class that represents a pointer argument to a function.""" @@ -6584,9 +8624,13 @@ class PointerArgument(Argument): Argument.__init__(self, name, type) def IsPointer(self): - """Returns true if argument is a pointer.""" + """Overridden from Argument.""" return True + def IsPointer2D(self): + """Overridden from Argument.""" + return self.type.count('*') == 2 + def GetPointedType(self): match = re.match('(const\s+)?(?P<element_type>[\w]+)\s*\*', self.type) assert match @@ -6641,6 +8685,8 @@ class PointerArgument(Argument): def WriteValidationCode(self, file, func): """Overridden from Argument.""" + if self.optional: + return file.Write(" if (%s == NULL) {\n" % self.name) file.Write(" return error::kOutOfBounds;\n") file.Write(" }\n") @@ -6651,7 +8697,9 @@ class PointerArgument(Argument): def GetBucketVersion(self): """Overridden from Argument.""" - if self.type == "const char*": + if self.type.find('char') >= 0: + if self.IsPointer2D(): + return InputStringArrayBucketArgument(self.name, self.type) return InputStringBucketArgument(self.name, self.type) return BucketPointerArgument(self.name, self.type) @@ -6660,27 +8708,83 @@ class PointerArgument(Argument): self.WriteDestinationInitalizationValidatationIfNeeded(file, func) +class BucketPointerArgument(PointerArgument): + """A class that represents an bucket argument to a function.""" + + def __init__(self, name, type): + Argument.__init__(self, name, type) + + def AddCmdArgs(self, args): + """Overridden from Argument.""" + pass + + def WriteGetCode(self, file): + """Overridden from Argument.""" + file.Write( + " %s %s = bucket->GetData(0, data_size);\n" % + (self.type, self.name)) + + def WriteValidationCode(self, file, func): + """Overridden from Argument.""" + pass + + def GetImmediateVersion(self): + """Overridden from Argument.""" + return None + + def WriteDestinationInitalizationValidation(self, file, func): + """Overridden from Argument.""" + self.WriteDestinationInitalizationValidatationIfNeeded(file, func) + + def GetLogArg(self): + """Overridden from Argument.""" + return "static_cast<const void*>(%s)" % self.name + + class InputStringBucketArgument(Argument): - """An string input argument where the string is passed in a bucket.""" + """A string input argument where the string is passed in a bucket.""" def __init__(self, name, type): Argument.__init__(self, name + "_bucket_id", "uint32_t") + def IsPointer(self): + """Overridden from Argument.""" + return True + + def IsPointer2D(self): + """Overridden from Argument.""" + return False + + +class InputStringArrayBucketArgument(Argument): + """A string array input argument where the strings are passed in a bucket.""" + + def __init__(self, name, type): + Argument.__init__(self, name + "_bucket_id", "uint32_t") + self._original_name = name + def WriteGetCode(self, file): """Overridden from Argument.""" code = """ - Bucket* %(name)s_bucket = GetBucket(c.%(name)s); - if (!%(name)s_bucket) { + Bucket* bucket = GetBucket(c.%(name)s); + if (!bucket) { return error::kInvalidArguments; } - std::string %(name)s_str; - if (!%(name)s_bucket->GetAsString(&%(name)s_str)) { + GLsizei count = 0; + std::vector<char*> strs; + std::vector<GLint> len; + if (!bucket->GetAsStrings(&count, &strs, &len)) { return error::kInvalidArguments; } - const char* %(name)s = %(name)s_str.c_str(); + const char** %(original_name)s = + strs.size() > 0 ? const_cast<const char**>(&strs[0]) : NULL; + const GLint* length = + len.size() > 0 ? const_cast<const GLint*>(&len[0]) : NULL; + (void)length; """ file.Write(code % { 'name': self.name, + 'original_name': self._original_name, }) def GetValidArg(self, func): @@ -6689,6 +8793,14 @@ class InputStringBucketArgument(Argument): def GetValidGLArg(self, func): return "_" + def IsPointer(self): + """Overridden from Argument.""" + return True + + def IsPointer2D(self): + """Overridden from Argument.""" + return True + class ResourceIdArgument(Argument): """A class that represents a resource id argument to a function.""" @@ -6696,17 +8808,26 @@ class ResourceIdArgument(Argument): def __init__(self, name, type): match = re.match("(GLid\w+)", type) self.resource_type = match.group(1)[4:] - type = type.replace(match.group(1), "GLuint") + if self.resource_type == "Sync": + type = type.replace(match.group(1), "GLsync") + else: + type = type.replace(match.group(1), "GLuint") Argument.__init__(self, name, type) def WriteGetCode(self, file): """Overridden from Argument.""" - file.Write(" %s %s = c.%s;\n" % (self.type, self.name, self.name)) + if self.type == "GLsync": + my_type = "GLuint" + else: + my_type = self.type + file.Write(" %s %s = c.%s;\n" % (my_type, self.name, self.name)) def GetValidArg(self, func): return "client_%s_id_" % self.resource_type.lower() def GetValidGLArg(self, func): + if self.resource_type == "Sync": + return "reinterpret_cast<GLsync>(kService%sId)" % self.resource_type return "kService%sId" % self.resource_type @@ -6780,6 +8901,7 @@ class Function(object): 'Manual': ManualHandler(), 'PUT': PUTHandler(), 'PUTn': PUTnHandler(), + 'PUTSTR': PUTSTRHandler(), 'PUTXn': PUTXnHandler(), 'StateSet': StateSetHandler(), 'StateSetRGBAlpha': StateSetRGBAlphaHandler(), @@ -6809,6 +8931,13 @@ class Function(object): self.num_pointer_args = sum( [1 for arg in self.args_for_cmds if arg.IsPointer()]) + if self.num_pointer_args > 0: + for arg in reversed(self.original_args): + if arg.IsPointer(): + self.last_original_pointer_arg = arg + break + else: + self.last_original_pointer_arg = None self.info = info self.type_handler = self.type_handlers[info['type']] self.can_auto_generate = (self.num_pointer_args == 0 and @@ -6854,6 +8983,10 @@ class Function(object): """Returns whether the function is immediate data function or not.""" return False + def IsUnsafe(self): + """Returns whether the function has service side validation or not.""" + return self.GetInfo('unsafe', False) + def GetInfo(self, name, default = None): """Returns a value from the function info for this function.""" if name in self.info: @@ -6882,7 +9015,8 @@ class Function(object): def IsCoreGLFunction(self): return (not self.IsExtension() and - not self.GetInfo('pepper_interface')) + not self.GetInfo('pepper_interface') and + not self.IsUnsafe()) def InPepperInterface(self, interface): ext = self.GetInfo('pepper_interface') @@ -6950,7 +9084,16 @@ class Function(object): """Gets the last original argument to this function.""" return self.original_args[len(self.original_args) - 1] - def __MaybePrependComma(self, arg_string, add_comma): + def GetLastOriginalPointerArg(self): + return self.last_original_pointer_arg + + def GetResourceIdArg(self): + for arg in self.original_args: + if hasattr(arg, 'resource_type'): + return arg + return None + + def _MaybePrependComma(self, arg_string, add_comma): """Adds a comma if arg_string is not empty and add_comma is true.""" comma = "" if add_comma and len(arg_string): @@ -6962,14 +9105,14 @@ class Function(object): args = self.GetOriginalArgs() arg_string = ", ".join( ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args]) - return self.__MaybePrependComma(arg_string, add_comma) + return self._MaybePrependComma(arg_string, add_comma) def MakeOriginalArgString(self, prefix, add_comma = False, separator = ", "): """Gets the list of arguments as they are in GL.""" args = self.GetOriginalArgs() arg_string = separator.join( ["%s%s" % (prefix, arg.name) for arg in args]) - return self.__MaybePrependComma(arg_string, add_comma) + return self._MaybePrependComma(arg_string, add_comma) def MakeTypedHelperArgString(self, prefix, add_comma = False): """Gets a list of typed GL arguments after removing unneeded arguments.""" @@ -6980,7 +9123,7 @@ class Function(object): prefix, arg.name, ) for arg in args if not arg.IsConstant()]) - return self.__MaybePrependComma(arg_string, add_comma) + return self._MaybePrependComma(arg_string, add_comma) def MakeHelperArgString(self, prefix, add_comma = False, separator = ", "): """Gets a list of GL arguments after removing unneeded arguments.""" @@ -6988,7 +9131,7 @@ class Function(object): arg_string = separator.join( ["%s%s" % (prefix, arg.name) for arg in args if not arg.IsConstant()]) - return self.__MaybePrependComma(arg_string, add_comma) + return self._MaybePrependComma(arg_string, add_comma) def MakeTypedPepperArgString(self, prefix): """Gets a list of arguments as they need to be for Pepper.""" @@ -7037,28 +9180,28 @@ class Function(object): args = self.GetCmdArgs() arg_string = ", ".join( ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args]) - return self.__MaybePrependComma(arg_string, add_comma) + return self._MaybePrependComma(arg_string, add_comma) def MakeCmdArgString(self, prefix, add_comma = False): """Gets the list of arguments as they need to be for command buffers.""" args = self.GetCmdArgs() arg_string = ", ".join( ["%s%s" % (prefix, arg.name) for arg in args]) - return self.__MaybePrependComma(arg_string, add_comma) + return self._MaybePrependComma(arg_string, add_comma) def MakeTypedInitString(self, prefix, add_comma = False): """Gets a typed list of arguments as they need to be for cmd Init/Set.""" args = self.GetInitArgs() arg_string = ", ".join( ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args]) - return self.__MaybePrependComma(arg_string, add_comma) + return self._MaybePrependComma(arg_string, add_comma) def MakeInitString(self, prefix, add_comma = False): """Gets the list of arguments as they need to be for cmd Init/Set.""" args = self.GetInitArgs() arg_string = ", ".join( ["%s%s" % (prefix, arg.name) for arg in args]) - return self.__MaybePrependComma(arg_string, add_comma) + return self._MaybePrependComma(arg_string, add_comma) def MakeLogArgString(self): """Makes a string of the arguments for the LOG macros""" @@ -7166,6 +9309,14 @@ class Function(object): """Writes the GLES2 Interface declaration.""" self.type_handler.WriteGLES2InterfaceHeader(self, file) + def WriteMojoGLES2ImplHeader(self, file): + """Writes the Mojo GLES2 implementation header declaration.""" + self.type_handler.WriteMojoGLES2ImplHeader(self, file) + + def WriteMojoGLES2Impl(self, file): + """Writes the Mojo GLES2 implementation declaration.""" + self.type_handler.WriteMojoGLES2Impl(self, file) + def WriteGLES2InterfaceStub(self, file): """Writes the GLES2 Interface Stub declaration.""" self.type_handler.WriteGLES2InterfaceStub(self, file) @@ -7366,9 +9517,17 @@ class BucketFunction(Function): self.type_handler.WriteBucketHandlerImplementation(self, file) def WriteServiceUnitTest(self, file, *extras): - """Writes the service implementation for a command.""" + """Overridden from Function""" self.type_handler.WriteBucketServiceUnitTest(self, file, *extras) + def MakeOriginalArgString(self, prefix, add_comma = False, separator = ", "): + """Overridden from Function""" + args = self.GetOriginalArgs() + arg_string = separator.join( + ["%s%s" % (prefix, arg.name[0:-10] if arg.name.endswith("_bucket_id") + else arg.name) for arg in args]) + return super(BucketFunction, self)._MaybePrependComma(arg_string, add_comma) + def CreateArg(arg_string): """Creates an Argument.""" @@ -7389,6 +9548,8 @@ def CreateArg(arg_string): return ResourceIdArgument(arg_parts[-1], " ".join(arg_parts[0:-1])) elif arg_parts[0].startswith('GLenum') and len(arg_parts[0]) > 6: return EnumArgument(arg_parts[-1], " ".join(arg_parts[0:-1])) + elif arg_parts[0].startswith('GLbitfield') and len(arg_parts[0]) > 10: + return BitFieldArgument(arg_parts[-1], " ".join(arg_parts[0:-1])) elif arg_parts[0].startswith('GLboolean') and len(arg_parts[0]) > 9: return ValidatedBoolArgument(arg_parts[-1], " ".join(arg_parts[0:-1])) elif arg_parts[0].startswith('GLboolean'): @@ -7551,6 +9712,16 @@ class GLGenerator(object): def WriteFormat(self, filename): """Writes the command buffer format""" file = CHeaderWriter(filename) + # Forward declaration of a few enums used in constant argument + # to avoid including GL header files. + enum_defines = { + 'GL_SYNC_GPU_COMMANDS_COMPLETE': '0x9117', + 'GL_SYNC_FLUSH_COMMANDS_BIT': '0x00000001', + } + file.Write('\n') + for enum in enum_defines: + file.Write("#define %s %s\n" % (enum, enum_defines[enum])) + file.Write('\n') for func in self.functions: if True: #gen_cmd = func.GetInfo('gen_cmd') @@ -7773,20 +9944,31 @@ bool %s::GetStateAs%s( file.Write(""" void ContextState::InitCapabilities(const ContextState* prev_state) const { """) - def WriteCapabilities(test_prev): + def WriteCapabilities(test_prev, es3_caps): for capability in _CAPABILITY_FLAGS: capability_name = capability['name'] + capability_es3 = 'es3' in capability and capability['es3'] == True + if capability_es3 and not es3_caps or not capability_es3 and es3_caps: + continue if test_prev: file.Write(""" if (prev_state->enable_flags.cached_%s != - enable_flags.cached_%s)\n""" % + enable_flags.cached_%s) {\n""" % (capability_name, capability_name)) file.Write(" EnableDisable(GL_%s, enable_flags.cached_%s);\n" % (capability_name.upper(), capability_name)) + if test_prev: + file.Write(" }") file.Write(" if (prev_state) {") - WriteCapabilities(True) + WriteCapabilities(True, False) + file.Write(" if (feature_info_->IsES3Capable()) {\n") + WriteCapabilities(True, True) + file.Write(" }\n") file.Write(" } else {") - WriteCapabilities(False) + WriteCapabilities(False, False) + file.Write(" if (feature_info_->IsES3Capable()) {\n") + WriteCapabilities(False, True) + file.Write(" }\n") file.Write(" }") file.Write("""} @@ -7832,11 +10014,21 @@ void ContextState::InitState(const ContextState *prev_state) const { else: file.Write(" if (prev_state->%s != %s) {\n " % (item_name, item_name)) + if 'gl_version_flag' in item: + item_name = item['gl_version_flag'] + inverted = '' + if item_name[0] == '!': + inverted = '!' + item_name = item_name[1:] + file.Write(" if (%sfeature_info_->gl_version_info().%s) {\n" % + (inverted, item_name)) file.Write(" gl%s(%s, %s);\n" % (state['func'], (item['enum_set'] if 'enum_set' in item else item['enum']), item['name'])) + if 'gl_version_flag' in item: + file.Write(" }\n") if test_prev: if 'extension_flag' in item: file.Write(" ") @@ -8022,13 +10214,24 @@ bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) { filename % 0, "// It is included by gles2_cmd_decoder_unittest_base.cc\n") file.Write( -"""void GLES2DecoderTestBase::SetupInitCapabilitiesExpectations() { -""") +"""void GLES2DecoderTestBase::SetupInitCapabilitiesExpectations( + bool es3_capable) {""") for capability in _CAPABILITY_FLAGS: - file.Write(" ExpectEnableDisable(GL_%s, %s);\n" % - (capability['name'].upper(), - ('false', 'true')['default' in capability])) - file.Write("""} + capability_es3 = 'es3' in capability and capability['es3'] == True + if not capability_es3: + file.Write(" ExpectEnableDisable(GL_%s, %s);\n" % + (capability['name'].upper(), + ('false', 'true')['default' in capability])) + + file.Write(" if (es3_capable) {") + for capability in _CAPABILITY_FLAGS: + capability_es3 = 'es3' in capability and capability['es3'] == True + if capability_es3: + file.Write(" ExpectEnableDisable(GL_%s, %s);\n" % + (capability['name'].upper(), + ('false', 'true')['default' in capability])) + file.Write(""" } +} void GLES2DecoderTestBase::SetupInitStateExpectations() { """) @@ -8169,6 +10372,71 @@ extern const NameToFunc g_gles2_function_table[] = { file.Close() self.generated_cpp_filenames.append(file.filename) + def WriteMojoGLES2ImplHeader(self, filename): + """Writes the Mojo GLES2 implementation header.""" + file = CHeaderWriter( + filename, + "// This file is included by gles2_interface.h to declare the\n" + "// GL api functions.\n") + + code = """ +#include "gpu/command_buffer/client/gles2_interface.h" +#include "third_party/mojo/src/mojo/public/c/gles2/gles2.h" + +namespace mojo { + +class MojoGLES2Impl : public gpu::gles2::GLES2Interface { + public: + explicit MojoGLES2Impl(MojoGLES2Context context) { + context_ = context; + } + ~MojoGLES2Impl() override {} + """ + file.Write(code); + for func in self.original_functions: + func.WriteMojoGLES2ImplHeader(file) + code = """ + private: + MojoGLES2Context context_; +}; + +} // namespace mojo + """ + file.Write(code); + file.Close() + self.generated_cpp_filenames.append(file.filename) + + def WriteMojoGLES2Impl(self, filename): + """Writes the Mojo GLES2 implementation.""" + file = CWriter(filename) + file.Write(_LICENSE) + file.Write(_DO_NOT_EDIT_WARNING) + + code = """ +#include "mojo/gpu/mojo_gles2_impl_autogen.h" + +#include "base/logging.h" +#include "third_party/mojo/src/mojo/public/c/gles2/chromium_miscellaneous.h" +#include "third_party/mojo/src/mojo/public/c/gles2/chromium_sub_image.h" +#include "third_party/mojo/src/mojo/public/c/gles2/chromium_sync_point.h" +#include "third_party/mojo/src/mojo/public/c/gles2/chromium_texture_mailbox.h" +#include "third_party/mojo/src/mojo/public/c/gles2/gles2.h" +#include "third_party/mojo/src/mojo/public/c/gles2/occlusion_query_ext.h" + +namespace mojo { + + """ + file.Write(code); + for func in self.original_functions: + func.WriteMojoGLES2Impl(file) + code = """ + +} // namespace mojo + """ + file.Write(code); + file.Close() + self.generated_cpp_filenames.append(file.filename) + def WriteGLES2InterfaceStub(self, filename): """Writes the GLES2 interface stub header.""" file = CHeaderWriter( @@ -8270,6 +10538,20 @@ extern const NameToFunc g_gles2_function_table[] = { file.Write(" %s,\n" % value) file.Write("};\n") file.Write("\n") + if named_type.GetValidValuesES3(): + file.Write("static const %s valid_%s_table_es3[] = {\n" % + (named_type.GetType(), ToUnderscore(name))) + for value in named_type.GetValidValuesES3(): + file.Write(" %s,\n" % value) + file.Write("};\n") + file.Write("\n") + if named_type.GetDeprecatedValuesES3(): + file.Write("static const %s deprecated_%s_table_es3[] = {\n" % + (named_type.GetType(), ToUnderscore(name))) + for value in named_type.GetDeprecatedValuesES3(): + file.Write(" %s,\n" % value) + file.Write("};\n") + file.Write("\n") file.Write("Validators::Validators()") pre = ' : ' for count, name in enumerate(names): @@ -8288,6 +10570,25 @@ extern const NameToFunc g_gles2_function_table[] = { pre = ',\n ' file.Write(" {\n"); file.Write("}\n\n"); + + file.Write("void Validators::UpdateValuesES3() {\n") + for name in names: + named_type = NamedType(_NAMED_TYPE_INFO[name]) + if named_type.GetDeprecatedValuesES3(): + code = """ %(name)s.RemoveValues( + deprecated_%(name)s_table_es3, arraysize(deprecated_%(name)s_table_es3)); +""" + file.Write(code % { + 'name': ToUnderscore(name), + }) + if named_type.GetValidValuesES3(): + code = """ %(name)s.AddValues( + valid_%(name)s_table_es3, arraysize(valid_%(name)s_table_es3)); +""" + file.Write(code % { + 'name': ToUnderscore(name), + }) + file.Write("}\n\n"); file.Close() self.generated_cpp_filenames.append(file.filename) @@ -8309,6 +10610,7 @@ extern const NameToFunc g_gles2_function_table[] = { dict = {} for fname in ['third_party/khronos/GLES2/gl2.h', 'third_party/khronos/GLES2/gl2ext.h', + 'third_party/khronos/GLES3/gl3.h', 'gpu/GLES2/gl2chromium.h', 'gpu/GLES2/gl2extchromium.h']: lines = open(fname).readlines() @@ -8317,8 +10619,14 @@ extern const NameToFunc g_gles2_function_table[] = { if m: name = m.group(1) value = m.group(2) - if len(value) <= 10 and not value in dict: - dict[value] = name + if len(value) <= 10: + if not value in dict: + dict[value] = name + # check our own _CHROMIUM macro conflicts with khronos GL headers. + elif dict[value] != name and (name.endswith('_CHROMIUM') or + dict[value].endswith('_CHROMIUM')): + self.Error("code collision: %s and %s have the same code %s" % + (dict[value], name, value)) file = CHeaderWriter(filename) file.Write("static const GLES2Util::EnumToString " @@ -8339,9 +10647,13 @@ const size_t GLES2Util::enum_to_string_table_len_ = if _NAMED_TYPE_INFO[enum]['type'] == 'GLenum': file.Write("std::string GLES2Util::GetString%s(uint32_t value) {\n" % enum) - if len(_NAMED_TYPE_INFO[enum]['valid']) > 0: + valid_list = _NAMED_TYPE_INFO[enum]['valid'] + if 'valid_es3' in _NAMED_TYPE_INFO[enum]: + valid_list = valid_list + _NAMED_TYPE_INFO[enum]['valid_es3'] + assert len(valid_list) == len(set(valid_list)) + if len(valid_list) > 0: file.Write(" static const EnumToString string_table[] = {\n") - for value in _NAMED_TYPE_INFO[enum]['valid']: + for value in valid_list: file.Write(' { %s, "%s" },\n' % (value, value)) file.Write(""" }; return GLES2Util::GetQualifiedEnumString( @@ -8582,8 +10894,11 @@ const size_t GLES2Util::enum_to_string_table_len_ = self.generated_cpp_filenames.append(file.filename) def Format(generated_files): + formatter = "clang-format" + if platform.system() == "Windows": + formatter += ".bat" for filename in generated_files: - call(["clang-format", "-i", "-style=chromium", filename]) + call([formatter, "-i", "-style=chromium", filename]) def main(argv): """This is the main function.""" @@ -8640,6 +10955,10 @@ def main(argv): "gpu/command_buffer/common/gles2_cmd_format_test_autogen.h") gen.WriteGLES2InterfaceHeader( "gpu/command_buffer/client/gles2_interface_autogen.h") + gen.WriteMojoGLES2ImplHeader( + "mojo/gpu/mojo_gles2_impl_autogen.h") + gen.WriteMojoGLES2Impl( + "mojo/gpu/mojo_gles2_impl_autogen.cc") gen.WriteGLES2InterfaceStub( "gpu/command_buffer/client/gles2_interface_stub_autogen.h") gen.WriteGLES2InterfaceStubImpl( @@ -8683,7 +11002,8 @@ def main(argv): gen.WriteCommonUtilsImpl( "gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h") gen.WriteGLES2Header("gpu/GLES2/gl2chromium_autogen.h") - mojo_gles2_prefix = "mojo/public/c/gles2/gles2_call_visitor" + mojo_gles2_prefix = ("third_party/mojo/src/mojo/public/c/gles2/" + "gles2_call_visitor") gen.WriteMojoGLCallVisitor(mojo_gles2_prefix + "_autogen.h") gen.WriteMojoGLCallVisitorForExtension( mojo_gles2_prefix + "_chromium_texture_mailbox_autogen.h", @@ -8691,6 +11011,15 @@ def main(argv): gen.WriteMojoGLCallVisitorForExtension( mojo_gles2_prefix + "_chromium_sync_point_autogen.h", "CHROMIUM_sync_point") + gen.WriteMojoGLCallVisitorForExtension( + mojo_gles2_prefix + "_chromium_sub_image_autogen.h", + "CHROMIUM_sub_image") + gen.WriteMojoGLCallVisitorForExtension( + mojo_gles2_prefix + "_chromium_miscellaneous_autogen.h", + "CHROMIUM_miscellaneous") + gen.WriteMojoGLCallVisitorForExtension( + mojo_gles2_prefix + "_occlusion_query_ext_autogen.h", + "occlusion_query_EXT") Format(gen.generated_cpp_filenames) diff --git a/chromium/gpu/command_buffer/client/BUILD.gn b/chromium/gpu/command_buffer/client/BUILD.gn index 810948a6eed..bbb7c0b99d1 100644 --- a/chromium/gpu/command_buffer/client/BUILD.gn +++ b/chromium/gpu/command_buffer/client/BUILD.gn @@ -2,13 +2,46 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -source_set("client") { +# The files here go into the "gpu" component in a component build (with +# "command_buffer_client" and "gles2_cmd_helper" just forwarding) and goes into +# separate static libraries in non-component build. This needs to match the +# GYP build which was likely an attempt to make larger components to help with +# loading. +group("client") { + if (is_component_build) { + public_deps = [ + "//gpu", + ] + } else { + public_deps = [ + ":client_sources", + ] + } +} + +group("gles2_cmd_helper") { + if (is_component_build) { + public_deps = [ + "//gpu", + ] + } else { + public_deps = [ + ":gles2_cmd_helper_sources", + ] + } +} + +source_set("client_sources") { + visibility = [ "//gpu/*" ] + sources = [ "cmd_buffer_helper.cc", "cmd_buffer_helper.h", "fenced_allocator.cc", "fenced_allocator.h", "gpu_control.h", + "gpu_memory_buffer_manager.cc", + "gpu_memory_buffer_manager.h", "mapped_memory.cc", "mapped_memory.h", "ring_buffer.cc", @@ -17,69 +50,61 @@ source_set("client") { "transfer_buffer.h", ] - defines = [ "GPU_IMPLEMENTATION" ] - - if (is_win) { + configs += [ # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. - cflags = [ "/wd4267" ] # size_t to int truncation. - } + "//build/config/compiler:no_size_t_to_int_warning", + "//gpu:gpu_implementation", + ] all_dependent_configs = [ "//third_party/khronos:khronos_headers" ] deps = [ - "//gpu/command_buffer/common", + "//gpu/command_buffer/common:common_sources", ] } -group("gles2_cmd_helper") { - if (is_component_build) { - deps = [ "//gpu" ] - } else { - deps = [ ":gles2_cmd_helper_sources" ] - } -} - source_set("gles2_cmd_helper_sources") { - visibility = [ ":gles2_cmd_helper", "//gpu" ] + visibility = [ "//gpu/*" ] sources = [ "gles2_cmd_helper.cc", "gles2_cmd_helper.h", "gles2_cmd_helper_autogen.h", ] - defines = [ "GPU_IMPLEMENTATION" ] - - if (is_win) { + configs += [ # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. - cflags = [ "/wd4267" ] # size_t to int truncation. - } + "//build/config/compiler:no_size_t_to_int_warning", + "//gpu:gpu_implementation", + ] - deps = [ ":client" ] + deps = [ + ":client_sources", + ] } gles2_c_lib_source_files = [ "gles2_c_lib.cc", "gles2_c_lib_autogen.h", "gles2_c_lib_export.h", - "gles2_lib.h", "gles2_lib.cc", + "gles2_lib.h", ] gles2_implementation_source_files = [ "buffer_tracker.cc", "buffer_tracker.h", - "client_context_state.h", "client_context_state.cc", + "client_context_state.h", "client_context_state_autogen.h", "client_context_state_impl_autogen.h", "gles2_impl_export.h", - "gles2_implementation_autogen.h", "gles2_implementation.cc", "gles2_implementation.h", + "gles2_implementation_autogen.h", "gles2_implementation_impl_autogen.h", - "gles2_trace_implementation_autogen.h", "gles2_trace_implementation.cc", "gles2_trace_implementation.h", + "gles2_trace_implementation_autogen.h", "gles2_trace_implementation_impl_autogen.h", "gpu_switches.cc", "gpu_switches.h", @@ -97,48 +122,59 @@ gles2_implementation_source_files = [ # in. Useful when a target uses the interface, but permits its users to choose # an implementation. source_set("gles2_interface") { - sources = [ "gles2_interface.h" ] + sources = [ + "gles2_interface.h", + ] public_configs = [ "//third_party/khronos:khronos_headers" ] deps = [ "//base", ] } -source_set("gpu_memory_buffer_manager") { - sources = [ - "gpu_memory_buffer_manager.cc", - "gpu_memory_buffer_manager.h", - ] +# Library emulates GLES2 using command_buffers. +component("gles2_implementation") { + sources = gles2_implementation_source_files + + # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. + configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] + + defines = [ "GLES2_IMPL_IMPLEMENTATION" ] + all_dependent_configs = [ "//third_party/khronos:khronos_headers" ] + deps = [ - "//ui/gfx", + ":gles2_cmd_helper", + ":gles2_interface", + "//base", + "//gpu/command_buffer/common:gles2_utils", + "//ui/gfx/geometry", ] } # Library emulates GLES2 using command_buffers. -component("gles2_implementation") { +component("gles2_implementation_no_check") { sources = gles2_implementation_source_files - defines = [ "GLES2_IMPL_IMPLEMENTATION" ] - all_dependent_configs = [ "//third_party/khronos:khronos_headers" ] + # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. + configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] - if (is_win) { - # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. - cflags = [ "/wd4267" ] # size_t to int truncation. - } + defines = [ + "GLES2_IMPL_IMPLEMENTATION", + "GLES2_CONFORMANCE_TESTS=1", + ] deps = [ ":gles2_cmd_helper", - ":gles2_interface", "//base", - "//gpu/command_buffer/common", + "//gpu/command_buffer/common:gles2_utils", + "//ui/gfx", "//ui/gfx/geometry", ] } component("gl_in_process_context") { sources = [ - "gl_in_process_context.h", "gl_in_process_context.cc", + "gl_in_process_context.h", "gl_in_process_context_export.h", ] @@ -146,7 +182,6 @@ component("gl_in_process_context") { deps = [ ":gles2_implementation", - ":gpu_memory_buffer_manager", "//gpu", "//gpu/command_buffer/common:gles2_utils", "//base", @@ -160,10 +195,8 @@ component("gles2_c_lib") { sources = gles2_c_lib_source_files defines = [ "GLES2_C_LIB_IMPLEMENTATION" ] - if (is_win) { - # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. - cflags = [ "/wd4267" ] # size_t to int truncation. - } + # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. + configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] deps = [ ":client", @@ -174,3 +207,22 @@ component("gles2_c_lib") { ] } +# GYP version: gpu/gpu.gyp:gles2_c_lib_nocheck +# Same as gles2_c_lib except with no parameter checking. Required for +# OpenGL ES 2.0 conformance tests. +component("gles2_c_lib_nocheck") { + sources = gles2_c_lib_source_files + + defines = [ + "GLES2_C_LIB_IMPLEMENTATION", + "GLES2_CONFORMANCE_TESTS=1", + ] + deps = [ + ":client", + ":gles2_implementation_no_check", + ":gles2_interface", + "//base", + "//base/third_party/dynamic_annotations", + "//gpu/command_buffer/common", + ] +} diff --git a/chromium/gpu/command_buffer/client/client_context_state.h b/chromium/gpu/command_buffer/client/client_context_state.h index f5a93a6272c..a92c04a4385 100644 --- a/chromium/gpu/command_buffer/client/client_context_state.h +++ b/chromium/gpu/command_buffer/client/client_context_state.h @@ -7,7 +7,7 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_H_ #define GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_H_ -#include <GLES2/gl2.h> +#include <GLES3/gl3.h> #include <vector> #include "gles2_impl_export.h" diff --git a/chromium/gpu/command_buffer/client/client_context_state_autogen.h b/chromium/gpu/command_buffer/client/client_context_state_autogen.h index 72a4f72ed03..3084fb3aa51 100644 --- a/chromium/gpu/command_buffer/client/client_context_state_autogen.h +++ b/chromium/gpu/command_buffer/client/client_context_state_autogen.h @@ -23,6 +23,8 @@ struct EnableFlags { bool sample_coverage; bool scissor_test; bool stencil_test; + bool rasterizer_discard; + bool primitive_restart_fixed_index; }; #endif // GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/client_context_state_impl_autogen.h b/chromium/gpu/command_buffer/client/client_context_state_impl_autogen.h index cff14f7a82c..036f92ccdc9 100644 --- a/chromium/gpu/command_buffer/client/client_context_state_impl_autogen.h +++ b/chromium/gpu/command_buffer/client/client_context_state_impl_autogen.h @@ -21,7 +21,9 @@ ClientContextState::EnableFlags::EnableFlags() sample_alpha_to_coverage(false), sample_coverage(false), scissor_test(false), - stencil_test(false) { + stencil_test(false), + rasterizer_discard(false), + primitive_restart_fixed_index(false) { } bool ClientContextState::SetCapabilityState(GLenum cap, @@ -83,6 +85,18 @@ bool ClientContextState::SetCapabilityState(GLenum cap, enable_flags.stencil_test = enabled; } return true; + case GL_RASTERIZER_DISCARD: + if (enable_flags.rasterizer_discard != enabled) { + *changed = true; + enable_flags.rasterizer_discard = enabled; + } + return true; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + if (enable_flags.primitive_restart_fixed_index != enabled) { + *changed = true; + enable_flags.primitive_restart_fixed_index = enabled; + } + return true; default: return false; } @@ -116,6 +130,12 @@ bool ClientContextState::GetEnabled(GLenum cap, bool* enabled) const { case GL_STENCIL_TEST: *enabled = enable_flags.stencil_test; return true; + case GL_RASTERIZER_DISCARD: + *enabled = enable_flags.rasterizer_discard; + return true; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + *enabled = enable_flags.primitive_restart_fixed_index; + return true; default: return false; } diff --git a/chromium/gpu/command_buffer/client/client_test_helper.cc b/chromium/gpu/command_buffer/client/client_test_helper.cc index 3c50f6b20cc..258e8217a84 100644 --- a/chromium/gpu/command_buffer/client/client_test_helper.cc +++ b/chromium/gpu/command_buffer/client/client_test_helper.cc @@ -130,6 +130,10 @@ void MockClientCommandBuffer::Flush(int32 put_offset) { FlushHelper(put_offset); } +void MockClientCommandBuffer::OrderingBarrier(int32 put_offset) { + FlushHelper(put_offset); +} + void MockClientCommandBuffer::DelegateToFake() { ON_CALL(*this, DestroyTransferBuffer(_)) .WillByDefault(Invoke( diff --git a/chromium/gpu/command_buffer/client/client_test_helper.h b/chromium/gpu/command_buffer/client/client_test_helper.h index 6778a831e48..c155bf11717 100644 --- a/chromium/gpu/command_buffer/client/client_test_helper.h +++ b/chromium/gpu/command_buffer/client/client_test_helper.h @@ -63,13 +63,14 @@ class MockCommandBufferBase : public CommandBufferServiceBase { class MockClientCommandBuffer : public MockCommandBufferBase { public: MockClientCommandBuffer(); - virtual ~MockClientCommandBuffer(); + ~MockClientCommandBuffer() override; // This is so we can use all the gmock functions when Flush is called. MOCK_METHOD0(OnFlush, void()); MOCK_METHOD1(DestroyTransferBuffer, void(int32 id)); - virtual void Flush(int32 put_offset) override; + void Flush(int32 put_offset) override; + void OrderingBarrier(int32 put_offset) override; void DelegateToFake(); }; @@ -80,6 +81,7 @@ class MockClientCommandBufferMockFlush : public MockClientCommandBuffer { virtual ~MockClientCommandBufferMockFlush(); MOCK_METHOD1(Flush, void(int32 put_offset)); + MOCK_METHOD1(OrderingBarrier, void(int32 put_offset)); void DelegateToFake(); }; @@ -108,6 +110,7 @@ class MockClientGpuControl : public GpuControl { MOCK_METHOD2(SignalQuery, void(uint32 query, const base::Closure& callback)); MOCK_METHOD1(SetSurfaceVisible, void(bool visible)); MOCK_METHOD1(CreateStreamTexture, uint32(uint32)); + MOCK_METHOD1(SetLock, void(base::Lock*)); private: DISALLOW_COPY_AND_ASSIGN(MockClientGpuControl); diff --git a/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc b/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc index a99201e4b36..038ba41fda0 100644 --- a/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc +++ b/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc @@ -150,7 +150,7 @@ void CommandBufferHelper::Flush() { if (put_ == total_entry_count_) put_ = 0; - if (usable() && last_put_sent_ != put_) { + if (usable()) { last_flush_time_ = base::TimeTicks::Now(); last_put_sent_ = put_; command_buffer_->Flush(put_); @@ -159,6 +159,18 @@ void CommandBufferHelper::Flush() { } } +void CommandBufferHelper::OrderingBarrier() { + // Wrap put_ before setting the barrier. + if (put_ == total_entry_count_) + put_ = 0; + + if (usable()) { + command_buffer_->OrderingBarrier(put_); + ++flush_generation_; + CalcImmediateEntries(0); + } +} + #if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK) void CommandBufferHelper::PeriodicFlushCheck() { base::TimeTicks current_time = base::TimeTicks::Now(); diff --git a/chromium/gpu/command_buffer/client/cmd_buffer_helper.h b/chromium/gpu/command_buffer/client/cmd_buffer_helper.h index 954107f1590..3f7fba78269 100644 --- a/chromium/gpu/command_buffer/client/cmd_buffer_helper.h +++ b/chromium/gpu/command_buffer/client/cmd_buffer_helper.h @@ -66,6 +66,11 @@ class GPU_EXPORT CommandBufferHelper { // returns, the command buffer service is aware of all pending commands. void Flush(); + // Ensures that commands up to the put pointer will be processed in the + // command buffer service before any future commands on other command buffers + // sharing a channel. + void OrderingBarrier(); + // Waits until all the commands have been executed. Returns whether it // was successful. The function will fail if the command buffer service has // disconnected. @@ -137,11 +142,12 @@ class GPU_EXPORT CommandBufferHelper { template <typename T> void ForceNullCheck(T* data) { -#if defined(OS_WIN) && defined(ARCH_CPU_64_BITS) +#if defined(COMPILER_MSVC) && defined(ARCH_CPU_64_BITS) && !defined(__clang__) // 64-bit MSVC's alias analysis was determining that the command buffer // entry couldn't be NULL, so it optimized out the NULL check. // Dereferencing the same datatype through a volatile pointer seems to // prevent that from happening. http://crbug.com/361936 + // TODO(jbauman): Remove once we're on VC2015, http://crbug.com/412902 if (data) static_cast<volatile T*>(data)->header; #endif @@ -151,7 +157,8 @@ class GPU_EXPORT CommandBufferHelper { // a reference to it. template <typename T> T* GetCmdSpace() { - COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); + static_assert(T::kArgFlags == cmd::kFixed, + "T::kArgFlags should equal cmd::kFixed"); int32 space_needed = ComputeNumEntries(sizeof(T)); T* data = static_cast<T*>(GetSpace(space_needed)); ForceNullCheck(data); @@ -161,7 +168,8 @@ class GPU_EXPORT CommandBufferHelper { // Typed version of GetSpace for immediate commands. template <typename T> T* GetImmediateCmdSpace(size_t data_space) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + static_assert(T::kArgFlags == cmd::kAtLeastN, + "T::kArgFlags should equal cmd::kAtLeastN"); int32 space_needed = ComputeNumEntries(sizeof(T) + data_space); T* data = static_cast<T*>(GetSpace(space_needed)); ForceNullCheck(data); @@ -171,7 +179,8 @@ class GPU_EXPORT CommandBufferHelper { // Typed version of GetSpace for immediate commands. template <typename T> T* GetImmediateCmdSpaceTotalSize(size_t total_space) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + static_assert(T::kArgFlags == cmd::kAtLeastN, + "T::kArgFlags should equal cmd::kAtLeastN"); int32 space_needed = ComputeNumEntries(total_space); T* data = static_cast<T*>(GetSpace(space_needed)); ForceNullCheck(data); @@ -318,6 +327,7 @@ class GPU_EXPORT CommandBufferHelper { int32 token_; int32 put_; int32 last_put_sent_; + int32 last_barrier_put_sent_; #if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK) int commands_issued_; diff --git a/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc index fe688879234..6348abb3266 100644 --- a/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc +++ b/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc @@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/memory/linked_ptr.h" -#include "base/message_loop/message_loop.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" #include "gpu/command_buffer/service/command_buffer_service.h" #include "gpu/command_buffer/service/gpu_scheduler.h" @@ -17,10 +16,6 @@ #include "gpu/command_buffer/service/transfer_buffer_manager.h" #include "testing/gtest/include/gtest/gtest.h" -#if defined(OS_MACOSX) -#include "base/mac/scoped_nsautorelease_pool.h" -#endif - namespace gpu { using testing::Return; @@ -256,10 +251,6 @@ class CommandBufferHelperTest : public testing::Test { CommandBufferOffset get_helper_put() { return helper_->put_; } -#if defined(OS_MACOSX) - base::mac::ScopedNSAutoreleasePool autorelease_pool_; -#endif - base::MessageLoop message_loop_; scoped_ptr<AsyncAPIMock> api_mock_; scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; scoped_ptr<CommandBufferServiceLocked> command_buffer_; @@ -471,8 +462,8 @@ TEST_F(CommandBufferHelperTest, TestCommandProcessing) { TEST_F(CommandBufferHelperTest, TestCommandWrapping) { // Add num_commands * commands of size 3 through the helper to make sure we // do wrap. kTotalNumCommandEntries must not be a multiple of 3. - COMPILE_ASSERT(kTotalNumCommandEntries % 3 != 0, - Is_multiple_of_num_command_entries); + static_assert(kTotalNumCommandEntries % 3 != 0, + "kTotalNumCommandEntries must not be a multiple of 3"); const int kNumCommands = (kTotalNumCommandEntries / 3) * 2; CommandBufferEntry args1[2]; args1[0].value_uint32 = 5; @@ -495,8 +486,8 @@ TEST_F(CommandBufferHelperTest, TestCommandWrapping) { TEST_F(CommandBufferHelperTest, TestCommandWrappingExactMultiple) { const int32 kCommandSize = kTotalNumCommandEntries / 2; const size_t kNumArgs = kCommandSize - 1; - COMPILE_ASSERT(kTotalNumCommandEntries % kCommandSize == 0, - Not_multiple_of_num_command_entries); + static_assert(kTotalNumCommandEntries % kCommandSize == 0, + "kTotalNumCommandEntries should be a multiple of kCommandSize"); CommandBufferEntry args1[kNumArgs]; for (size_t ii = 0; ii < kNumArgs; ++ii) { args1[ii].value_uint32 = ii + 1; @@ -709,4 +700,64 @@ TEST_F(CommandBufferHelperTest, TestFlushGeneration) { EXPECT_EQ(error::kNoError, GetError()); } +TEST_F(CommandBufferHelperTest, TestOrderingBarrierFlushGeneration) { + // Explicit flushing only. + helper_->SetAutomaticFlushes(false); + + // Generation should change after OrderingBarrier() but not before. + uint32 gen1, gen2, gen3; + + gen1 = GetHelperFlushGeneration(); + AddUniqueCommandWithExpect(error::kNoError, 2); + gen2 = GetHelperFlushGeneration(); + helper_->OrderingBarrier(); + gen3 = GetHelperFlushGeneration(); + EXPECT_EQ(gen2, gen1); + EXPECT_NE(gen3, gen2); + + helper_->Finish(); + + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check the error status. + EXPECT_EQ(error::kNoError, GetError()); +} + +// Expect Flush() to always call CommandBuffer::Flush(). +TEST_F(CommandBufferHelperTest, TestFlushToCommandBuffer) { + // Explicit flushing only. + helper_->SetAutomaticFlushes(false); + + int flush_count1, flush_count2, flush_count3; + + flush_count1 = command_buffer_->FlushCount(); + AddUniqueCommandWithExpect(error::kNoError, 2); + helper_->Flush(); + flush_count2 = command_buffer_->FlushCount(); + helper_->Flush(); + flush_count3 = command_buffer_->FlushCount(); + + EXPECT_EQ(flush_count2, flush_count1 + 1); + EXPECT_EQ(flush_count3, flush_count2 + 1); +} + +// Expect OrderingBarrier() to always call CommandBuffer::OrderingBarrier(). +TEST_F(CommandBufferHelperTest, TestOrderingBarrierToCommandBuffer) { + // Explicit flushing only. + helper_->SetAutomaticFlushes(false); + + int flush_count1, flush_count2, flush_count3; + + flush_count1 = command_buffer_->FlushCount(); + AddUniqueCommandWithExpect(error::kNoError, 2); + helper_->OrderingBarrier(); + flush_count2 = command_buffer_->FlushCount(); + helper_->OrderingBarrier(); + flush_count3 = command_buffer_->FlushCount(); + + EXPECT_EQ(flush_count2, flush_count1 + 1); + EXPECT_EQ(flush_count3, flush_count2 + 1); +} + } // namespace gpu diff --git a/chromium/gpu/command_buffer/client/context_support.h b/chromium/gpu/command_buffer/client/context_support.h index 2678ba95afa..6c5b23f0d1e 100644 --- a/chromium/gpu/command_buffer/client/context_support.h +++ b/chromium/gpu/command_buffer/client/context_support.h @@ -6,8 +6,8 @@ #define GPU_COMMAND_BUFFER_CLIENT_CONTEXT_SUPPORT_H_ #include "base/callback.h" +#include "ui/gfx/geometry/rect.h" #include "ui/gfx/overlay_transform.h" -#include "ui/gfx/rect.h" namespace gpu { diff --git a/chromium/gpu/command_buffer/client/fenced_allocator.cc b/chromium/gpu/command_buffer/client/fenced_allocator.cc index 80038571be9..6db6e501977 100644 --- a/chromium/gpu/command_buffer/client/fenced_allocator.cc +++ b/chromium/gpu/command_buffer/client/fenced_allocator.cc @@ -14,23 +14,22 @@ namespace gpu { namespace { -// Allocation alignment, must be a power of two. -const unsigned int kAllocAlignment = 16; - // Round down to the largest multiple of kAllocAlignment no greater than |size|. unsigned int RoundDown(unsigned int size) { - return size & ~(kAllocAlignment - 1); + return size & ~(FencedAllocator::kAllocAlignment - 1); } // Round up to the smallest multiple of kAllocAlignment no smaller than |size|. unsigned int RoundUp(unsigned int size) { - return (size + (kAllocAlignment - 1)) & ~(kAllocAlignment - 1); + return (size + (FencedAllocator::kAllocAlignment - 1)) & + ~(FencedAllocator::kAllocAlignment - 1); } } // namespace #ifndef _MSC_VER const FencedAllocator::Offset FencedAllocator::kInvalidOffset; +const unsigned int FencedAllocator::kAllocAlignment; #endif FencedAllocator::FencedAllocator(unsigned int size, diff --git a/chromium/gpu/command_buffer/client/fenced_allocator.h b/chromium/gpu/command_buffer/client/fenced_allocator.h index 8e222e135bf..578870d2b04 100644 --- a/chromium/gpu/command_buffer/client/fenced_allocator.h +++ b/chromium/gpu/command_buffer/client/fenced_allocator.h @@ -35,6 +35,9 @@ class GPU_EXPORT FencedAllocator { // Invalid offset, returned by Alloc in case of failure. static const Offset kInvalidOffset = 0xffffffffU; + // Allocation alignment, must be a power of two. + static const unsigned int kAllocAlignment = 16; + // Creates a FencedAllocator. Note that the size of the buffer is passed, but // not its base address: everything is handled as offsets into the buffer. FencedAllocator(unsigned int size, diff --git a/chromium/gpu/command_buffer/client/fenced_allocator_test.cc b/chromium/gpu/command_buffer/client/fenced_allocator_test.cc index 3af9367a942..6b9f00f41a3 100644 --- a/chromium/gpu/command_buffer/client/fenced_allocator_test.cc +++ b/chromium/gpu/command_buffer/client/fenced_allocator_test.cc @@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/memory/aligned_memory.h" -#include "base/message_loop/message_loop.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" #include "gpu/command_buffer/client/fenced_allocator.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" @@ -17,10 +16,6 @@ #include "gpu/command_buffer/service/transfer_buffer_manager.h" #include "testing/gtest/include/gtest/gtest.h" -#if defined(OS_MACOSX) -#include "base/mac/scoped_nsautorelease_pool.h" -#endif - namespace gpu { using testing::Return; @@ -74,10 +69,6 @@ class BaseFencedAllocatorTest : public testing::Test { return command_buffer_->GetLastState().token; } -#if defined(OS_MACOSX) - base::mac::ScopedNSAutoreleasePool autorelease_pool_; -#endif - base::MessageLoop message_loop_; scoped_ptr<AsyncAPIMock> api_mock_; scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; scoped_ptr<CommandBufferService> command_buffer_; diff --git a/chromium/gpu/command_buffer/client/gl_in_process_context.cc b/chromium/gpu/command_buffer/client/gl_in_process_context.cc index 015a2a7824b..5d8049bceee 100644 --- a/chromium/gpu/command_buffer/client/gl_in_process_context.cc +++ b/chromium/gpu/command_buffer/client/gl_in_process_context.cc @@ -26,7 +26,7 @@ #include "gpu/command_buffer/client/transfer_buffer.h" #include "gpu/command_buffer/common/command_buffer.h" #include "gpu/command_buffer/common/constants.h" -#include "ui/gfx/size.h" +#include "ui/gfx/geometry/size.h" #include "ui/gl/gl_image.h" #if defined(OS_ANDROID) @@ -66,9 +66,10 @@ class GLInProcessContextImpl void SetContextLostCallback(const base::Closure& callback) override; gles2::GLES2Implementation* GetImplementation() override; size_t GetMappedMemoryLimit() override; + void SetLock(base::Lock* lock) override; #if defined(OS_ANDROID) - virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture( + scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture( uint32 stream_id) override; #endif @@ -85,6 +86,7 @@ class GLInProcessContextImpl const GLInProcessContextSharedMemoryLimits mem_limits_; bool context_lost_; base::Closure context_lost_callback_; + base::Lock* lock_; DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl); }; @@ -96,7 +98,7 @@ base::LazyInstance<std::set<GLInProcessContextImpl*> > g_all_shared_contexts = GLInProcessContextImpl::GLInProcessContextImpl( const GLInProcessContextSharedMemoryLimits& mem_limits) - : mem_limits_(mem_limits), context_lost_(false) { + : mem_limits_(mem_limits), context_lost_(false), lock_(nullptr) { } GLInProcessContextImpl::~GLInProcessContextImpl() { @@ -115,12 +117,20 @@ size_t GLInProcessContextImpl::GetMappedMemoryLimit() { return mem_limits_.mapped_memory_reclaim_limit; } +void GLInProcessContextImpl::SetLock(base::Lock* lock) { + command_buffer_->SetLock(lock); + lock_ = lock; +} + void GLInProcessContextImpl::SetContextLostCallback( const base::Closure& callback) { context_lost_callback_ = callback; } void GLInProcessContextImpl::OnContextLost() { + scoped_ptr<base::AutoLock> lock; + if (lock_) + lock.reset(new base::AutoLock(*lock_)); context_lost_ = true; if (!context_lost_callback_.is_null()) { context_lost_callback_.Run(); diff --git a/chromium/gpu/command_buffer/client/gl_in_process_context.h b/chromium/gpu/command_buffer/client/gl_in_process_context.h index ef1820c6c41..8c3a1c52b45 100644 --- a/chromium/gpu/command_buffer/client/gl_in_process_context.h +++ b/chromium/gpu/command_buffer/client/gl_in_process_context.h @@ -76,6 +76,8 @@ class GL_IN_PROCESS_CONTEXT_EXPORT GLInProcessContext { virtual size_t GetMappedMemoryLimit() = 0; + virtual void SetLock(base::Lock* lock) = 0; + #if defined(OS_ANDROID) virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture( uint32 stream_id) = 0; diff --git a/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h b/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h index f78007f64ac..58881b7d77a 100644 --- a/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -24,15 +24,31 @@ void GLES2BindAttribLocation(GLuint program, GLuint index, const char* name) { void GLES2BindBuffer(GLenum target, GLuint buffer) { gles2::GetGLContext()->BindBuffer(target, buffer); } +void GLES2BindBufferBase(GLenum target, GLuint index, GLuint buffer) { + gles2::GetGLContext()->BindBufferBase(target, index, buffer); +} +void GLES2BindBufferRange(GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) { + gles2::GetGLContext()->BindBufferRange(target, index, buffer, offset, size); +} void GLES2BindFramebuffer(GLenum target, GLuint framebuffer) { gles2::GetGLContext()->BindFramebuffer(target, framebuffer); } void GLES2BindRenderbuffer(GLenum target, GLuint renderbuffer) { gles2::GetGLContext()->BindRenderbuffer(target, renderbuffer); } +void GLES2BindSampler(GLuint unit, GLuint sampler) { + gles2::GetGLContext()->BindSampler(unit, sampler); +} void GLES2BindTexture(GLenum target, GLuint texture) { gles2::GetGLContext()->BindTexture(target, texture); } +void GLES2BindTransformFeedback(GLenum target, GLuint transformfeedback) { + gles2::GetGLContext()->BindTransformFeedback(target, transformfeedback); +} void GLES2BlendColor(GLclampf red, GLclampf green, GLclampf blue, @@ -72,6 +88,25 @@ GLenum GLES2CheckFramebufferStatus(GLenum target) { void GLES2Clear(GLbitfield mask) { gles2::GetGLContext()->Clear(mask); } +void GLES2ClearBufferfi(GLenum buffer, + GLint drawbuffers, + GLfloat depth, + GLint stencil) { + gles2::GetGLContext()->ClearBufferfi(buffer, drawbuffers, depth, stencil); +} +void GLES2ClearBufferfv(GLenum buffer, + GLint drawbuffers, + const GLfloat* value) { + gles2::GetGLContext()->ClearBufferfv(buffer, drawbuffers, value); +} +void GLES2ClearBufferiv(GLenum buffer, GLint drawbuffers, const GLint* value) { + gles2::GetGLContext()->ClearBufferiv(buffer, drawbuffers, value); +} +void GLES2ClearBufferuiv(GLenum buffer, + GLint drawbuffers, + const GLuint* value) { + gles2::GetGLContext()->ClearBufferuiv(buffer, drawbuffers, value); +} void GLES2ClearColor(GLclampf red, GLclampf green, GLclampf blue, @@ -84,6 +119,9 @@ void GLES2ClearDepthf(GLclampf depth) { void GLES2ClearStencil(GLint s) { gles2::GetGLContext()->ClearStencil(s); } +GLenum GLES2ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { + return gles2::GetGLContext()->ClientWaitSync(sync, flags, timeout); +} void GLES2ColorMask(GLboolean red, GLboolean green, GLboolean blue, @@ -116,6 +154,42 @@ void GLES2CompressedTexSubImage2D(GLenum target, gles2::GetGLContext()->CompressedTexSubImage2D( target, level, xoffset, yoffset, width, height, format, imageSize, data); } +void GLES2CompressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void* data) { + gles2::GetGLContext()->CompressedTexImage3D(target, level, internalformat, + width, height, depth, border, + imageSize, data); +} +void GLES2CompressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void* data) { + gles2::GetGLContext()->CompressedTexSubImage3D( + target, level, xoffset, yoffset, zoffset, width, height, depth, format, + imageSize, data); +} +void GLES2CopyBufferSubData(GLenum readtarget, + GLenum writetarget, + GLintptr readoffset, + GLintptr writeoffset, + GLsizeiptr size) { + gles2::GetGLContext()->CopyBufferSubData(readtarget, writetarget, readoffset, + writeoffset, size); +} void GLES2CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, @@ -138,6 +212,18 @@ void GLES2CopyTexSubImage2D(GLenum target, gles2::GetGLContext()->CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); } +void GLES2CopyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { + gles2::GetGLContext()->CopyTexSubImage3D(target, level, xoffset, yoffset, + zoffset, x, y, width, height); +} GLuint GLES2CreateProgram() { return gles2::GetGLContext()->CreateProgram(); } @@ -159,12 +245,21 @@ void GLES2DeleteProgram(GLuint program) { void GLES2DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { gles2::GetGLContext()->DeleteRenderbuffers(n, renderbuffers); } +void GLES2DeleteSamplers(GLsizei n, const GLuint* samplers) { + gles2::GetGLContext()->DeleteSamplers(n, samplers); +} +void GLES2DeleteSync(GLsync sync) { + gles2::GetGLContext()->DeleteSync(sync); +} void GLES2DeleteShader(GLuint shader) { gles2::GetGLContext()->DeleteShader(shader); } void GLES2DeleteTextures(GLsizei n, const GLuint* textures) { gles2::GetGLContext()->DeleteTextures(n, textures); } +void GLES2DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) { + gles2::GetGLContext()->DeleteTransformFeedbacks(n, ids); +} void GLES2DepthFunc(GLenum func) { gles2::GetGLContext()->DepthFunc(func); } @@ -192,12 +287,24 @@ void GLES2DrawElements(GLenum mode, const void* indices) { gles2::GetGLContext()->DrawElements(mode, count, type, indices); } +void GLES2DrawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void* indices) { + gles2::GetGLContext()->DrawRangeElements(mode, start, end, count, type, + indices); +} void GLES2Enable(GLenum cap) { gles2::GetGLContext()->Enable(cap); } void GLES2EnableVertexAttribArray(GLuint index) { gles2::GetGLContext()->EnableVertexAttribArray(index); } +GLsync GLES2FenceSync(GLenum condition, GLbitfield flags) { + return gles2::GetGLContext()->FenceSync(condition, flags); +} void GLES2Finish() { gles2::GetGLContext()->Finish(); } @@ -219,6 +326,14 @@ void GLES2FramebufferTexture2D(GLenum target, gles2::GetGLContext()->FramebufferTexture2D(target, attachment, textarget, texture, level); } +void GLES2FramebufferTextureLayer(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) { + gles2::GetGLContext()->FramebufferTextureLayer(target, attachment, texture, + level, layer); +} void GLES2FrontFace(GLenum mode) { gles2::GetGLContext()->FrontFace(mode); } @@ -234,9 +349,15 @@ void GLES2GenFramebuffers(GLsizei n, GLuint* framebuffers) { void GLES2GenRenderbuffers(GLsizei n, GLuint* renderbuffers) { gles2::GetGLContext()->GenRenderbuffers(n, renderbuffers); } +void GLES2GenSamplers(GLsizei n, GLuint* samplers) { + gles2::GetGLContext()->GenSamplers(n, samplers); +} void GLES2GenTextures(GLsizei n, GLuint* textures) { gles2::GetGLContext()->GenTextures(n, textures); } +void GLES2GenTransformFeedbacks(GLsizei n, GLuint* ids) { + gles2::GetGLContext()->GenTransformFeedbacks(n, ids); +} void GLES2GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, @@ -257,6 +378,28 @@ void GLES2GetActiveUniform(GLuint program, gles2::GetGLContext()->GetActiveUniform(program, index, bufsize, length, size, type, name); } +void GLES2GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) { + gles2::GetGLContext()->GetActiveUniformBlockiv(program, index, pname, params); +} +void GLES2GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) { + gles2::GetGLContext()->GetActiveUniformBlockName(program, index, bufsize, + length, name); +} +void GLES2GetActiveUniformsiv(GLuint program, + GLsizei count, + const GLuint* indices, + GLenum pname, + GLint* params) { + gles2::GetGLContext()->GetActiveUniformsiv(program, count, indices, pname, + params); +} void GLES2GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -278,6 +421,9 @@ GLenum GLES2GetError() { void GLES2GetFloatv(GLenum pname, GLfloat* params) { gles2::GetGLContext()->GetFloatv(pname, params); } +GLint GLES2GetFragDataLocation(GLuint program, const char* name) { + return gles2::GetGLContext()->GetFragDataLocation(program, name); +} void GLES2GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, @@ -285,9 +431,26 @@ void GLES2GetFramebufferAttachmentParameteriv(GLenum target, gles2::GetGLContext()->GetFramebufferAttachmentParameteriv(target, attachment, pname, params); } +void GLES2GetInteger64v(GLenum pname, GLint64* params) { + gles2::GetGLContext()->GetInteger64v(pname, params); +} +void GLES2GetIntegeri_v(GLenum pname, GLuint index, GLint* data) { + gles2::GetGLContext()->GetIntegeri_v(pname, index, data); +} +void GLES2GetInteger64i_v(GLenum pname, GLuint index, GLint64* data) { + gles2::GetGLContext()->GetInteger64i_v(pname, index, data); +} void GLES2GetIntegerv(GLenum pname, GLint* params) { gles2::GetGLContext()->GetIntegerv(pname, params); } +void GLES2GetInternalformativ(GLenum target, + GLenum format, + GLenum pname, + GLsizei bufSize, + GLint* params) { + gles2::GetGLContext()->GetInternalformativ(target, format, pname, bufSize, + params); +} void GLES2GetProgramiv(GLuint program, GLenum pname, GLint* params) { gles2::GetGLContext()->GetProgramiv(program, pname, params); } @@ -302,6 +465,12 @@ void GLES2GetRenderbufferParameteriv(GLenum target, GLint* params) { gles2::GetGLContext()->GetRenderbufferParameteriv(target, pname, params); } +void GLES2GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) { + gles2::GetGLContext()->GetSamplerParameterfv(sampler, pname, params); +} +void GLES2GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) { + gles2::GetGLContext()->GetSamplerParameteriv(sampler, pname, params); +} void GLES2GetShaderiv(GLuint shader, GLenum pname, GLint* params) { gles2::GetGLContext()->GetShaderiv(shader, pname, params); } @@ -327,18 +496,47 @@ void GLES2GetShaderSource(GLuint shader, const GLubyte* GLES2GetString(GLenum name) { return gles2::GetGLContext()->GetString(name); } +void GLES2GetSynciv(GLsync sync, + GLenum pname, + GLsizei bufsize, + GLsizei* length, + GLint* values) { + gles2::GetGLContext()->GetSynciv(sync, pname, bufsize, length, values); +} void GLES2GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { gles2::GetGLContext()->GetTexParameterfv(target, pname, params); } void GLES2GetTexParameteriv(GLenum target, GLenum pname, GLint* params) { gles2::GetGLContext()->GetTexParameteriv(target, pname, params); } +void GLES2GetTransformFeedbackVarying(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + GLsizei* size, + GLenum* type, + char* name) { + gles2::GetGLContext()->GetTransformFeedbackVarying(program, index, bufsize, + length, size, type, name); +} +GLuint GLES2GetUniformBlockIndex(GLuint program, const char* name) { + return gles2::GetGLContext()->GetUniformBlockIndex(program, name); +} void GLES2GetUniformfv(GLuint program, GLint location, GLfloat* params) { gles2::GetGLContext()->GetUniformfv(program, location, params); } void GLES2GetUniformiv(GLuint program, GLint location, GLint* params) { gles2::GetGLContext()->GetUniformiv(program, location, params); } +void GLES2GetUniformuiv(GLuint program, GLint location, GLuint* params) { + gles2::GetGLContext()->GetUniformuiv(program, location, params); +} +void GLES2GetUniformIndices(GLuint program, + GLsizei count, + const char* const* names, + GLuint* indices) { + gles2::GetGLContext()->GetUniformIndices(program, count, names, indices); +} GLint GLES2GetUniformLocation(GLuint program, const char* name) { return gles2::GetGLContext()->GetUniformLocation(program, name); } @@ -348,12 +546,33 @@ void GLES2GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) { void GLES2GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) { gles2::GetGLContext()->GetVertexAttribiv(index, pname, params); } +void GLES2GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) { + gles2::GetGLContext()->GetVertexAttribIiv(index, pname, params); +} +void GLES2GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) { + gles2::GetGLContext()->GetVertexAttribIuiv(index, pname, params); +} void GLES2GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer) { gles2::GetGLContext()->GetVertexAttribPointerv(index, pname, pointer); } void GLES2Hint(GLenum target, GLenum mode) { gles2::GetGLContext()->Hint(target, mode); } +void GLES2InvalidateFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments) { + gles2::GetGLContext()->InvalidateFramebuffer(target, count, attachments); +} +void GLES2InvalidateSubFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { + gles2::GetGLContext()->InvalidateSubFramebuffer(target, count, attachments, x, + y, width, height); +} GLboolean GLES2IsBuffer(GLuint buffer) { return gles2::GetGLContext()->IsBuffer(buffer); } @@ -369,24 +588,39 @@ GLboolean GLES2IsProgram(GLuint program) { GLboolean GLES2IsRenderbuffer(GLuint renderbuffer) { return gles2::GetGLContext()->IsRenderbuffer(renderbuffer); } +GLboolean GLES2IsSampler(GLuint sampler) { + return gles2::GetGLContext()->IsSampler(sampler); +} GLboolean GLES2IsShader(GLuint shader) { return gles2::GetGLContext()->IsShader(shader); } +GLboolean GLES2IsSync(GLsync sync) { + return gles2::GetGLContext()->IsSync(sync); +} GLboolean GLES2IsTexture(GLuint texture) { return gles2::GetGLContext()->IsTexture(texture); } +GLboolean GLES2IsTransformFeedback(GLuint transformfeedback) { + return gles2::GetGLContext()->IsTransformFeedback(transformfeedback); +} void GLES2LineWidth(GLfloat width) { gles2::GetGLContext()->LineWidth(width); } void GLES2LinkProgram(GLuint program) { gles2::GetGLContext()->LinkProgram(program); } +void GLES2PauseTransformFeedback() { + gles2::GetGLContext()->PauseTransformFeedback(); +} void GLES2PixelStorei(GLenum pname, GLint param) { gles2::GetGLContext()->PixelStorei(pname, param); } void GLES2PolygonOffset(GLfloat factor, GLfloat units) { gles2::GetGLContext()->PolygonOffset(factor, units); } +void GLES2ReadBuffer(GLenum src) { + gles2::GetGLContext()->ReadBuffer(src); +} void GLES2ReadPixels(GLint x, GLint y, GLsizei width, @@ -406,9 +640,28 @@ void GLES2RenderbufferStorage(GLenum target, gles2::GetGLContext()->RenderbufferStorage(target, internalformat, width, height); } +void GLES2ResumeTransformFeedback() { + gles2::GetGLContext()->ResumeTransformFeedback(); +} void GLES2SampleCoverage(GLclampf value, GLboolean invert) { gles2::GetGLContext()->SampleCoverage(value, invert); } +void GLES2SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) { + gles2::GetGLContext()->SamplerParameterf(sampler, pname, param); +} +void GLES2SamplerParameterfv(GLuint sampler, + GLenum pname, + const GLfloat* params) { + gles2::GetGLContext()->SamplerParameterfv(sampler, pname, params); +} +void GLES2SamplerParameteri(GLuint sampler, GLenum pname, GLint param) { + gles2::GetGLContext()->SamplerParameteri(sampler, pname, param); +} +void GLES2SamplerParameteriv(GLuint sampler, + GLenum pname, + const GLint* params) { + gles2::GetGLContext()->SamplerParameteriv(sampler, pname, params); +} void GLES2Scissor(GLint x, GLint y, GLsizei width, GLsizei height) { gles2::GetGLContext()->Scissor(x, y, width, height); } @@ -431,6 +684,9 @@ void GLES2ShallowFinishCHROMIUM() { void GLES2ShallowFlushCHROMIUM() { gles2::GetGLContext()->ShallowFlushCHROMIUM(); } +void GLES2OrderingBarrierCHROMIUM() { + gles2::GetGLContext()->OrderingBarrierCHROMIUM(); +} void GLES2StencilFunc(GLenum func, GLint ref, GLuint mask) { gles2::GetGLContext()->StencilFunc(func, ref, mask); } @@ -467,6 +723,20 @@ void GLES2TexImage2D(GLenum target, gles2::GetGLContext()->TexImage2D(target, level, internalformat, width, height, border, format, type, pixels); } +void GLES2TexImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void* pixels) { + gles2::GetGLContext()->TexImage3D(target, level, internalformat, width, + height, depth, border, format, type, + pixels); +} void GLES2TexParameterf(GLenum target, GLenum pname, GLfloat param) { gles2::GetGLContext()->TexParameterf(target, pname, param); } @@ -479,6 +749,15 @@ void GLES2TexParameteri(GLenum target, GLenum pname, GLint param) { void GLES2TexParameteriv(GLenum target, GLenum pname, const GLint* params) { gles2::GetGLContext()->TexParameteriv(target, pname, params); } +void GLES2TexStorage3D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth) { + gles2::GetGLContext()->TexStorage3D(target, levels, internalFormat, width, + height, depth); +} void GLES2TexSubImage2D(GLenum target, GLint level, GLint xoffset, @@ -491,6 +770,28 @@ void GLES2TexSubImage2D(GLenum target, gles2::GetGLContext()->TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); } +void GLES2TexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void* pixels) { + gles2::GetGLContext()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, + width, height, depth, format, type, + pixels); +} +void GLES2TransformFeedbackVaryings(GLuint program, + GLsizei count, + const char* const* varyings, + GLenum buffermode) { + gles2::GetGLContext()->TransformFeedbackVaryings(program, count, varyings, + buffermode); +} void GLES2Uniform1f(GLint location, GLfloat x) { gles2::GetGLContext()->Uniform1f(location, x); } @@ -503,6 +804,12 @@ void GLES2Uniform1i(GLint location, GLint x) { void GLES2Uniform1iv(GLint location, GLsizei count, const GLint* v) { gles2::GetGLContext()->Uniform1iv(location, count, v); } +void GLES2Uniform1ui(GLint location, GLuint x) { + gles2::GetGLContext()->Uniform1ui(location, x); +} +void GLES2Uniform1uiv(GLint location, GLsizei count, const GLuint* v) { + gles2::GetGLContext()->Uniform1uiv(location, count, v); +} void GLES2Uniform2f(GLint location, GLfloat x, GLfloat y) { gles2::GetGLContext()->Uniform2f(location, x, y); } @@ -515,6 +822,12 @@ void GLES2Uniform2i(GLint location, GLint x, GLint y) { void GLES2Uniform2iv(GLint location, GLsizei count, const GLint* v) { gles2::GetGLContext()->Uniform2iv(location, count, v); } +void GLES2Uniform2ui(GLint location, GLuint x, GLuint y) { + gles2::GetGLContext()->Uniform2ui(location, x, y); +} +void GLES2Uniform2uiv(GLint location, GLsizei count, const GLuint* v) { + gles2::GetGLContext()->Uniform2uiv(location, count, v); +} void GLES2Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) { gles2::GetGLContext()->Uniform3f(location, x, y, z); } @@ -527,6 +840,12 @@ void GLES2Uniform3i(GLint location, GLint x, GLint y, GLint z) { void GLES2Uniform3iv(GLint location, GLsizei count, const GLint* v) { gles2::GetGLContext()->Uniform3iv(location, count, v); } +void GLES2Uniform3ui(GLint location, GLuint x, GLuint y, GLuint z) { + gles2::GetGLContext()->Uniform3ui(location, x, y, z); +} +void GLES2Uniform3uiv(GLint location, GLsizei count, const GLuint* v) { + gles2::GetGLContext()->Uniform3uiv(location, count, v); +} void GLES2Uniform4f(GLint location, GLfloat x, GLfloat y, @@ -543,24 +862,69 @@ void GLES2Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) { void GLES2Uniform4iv(GLint location, GLsizei count, const GLint* v) { gles2::GetGLContext()->Uniform4iv(location, count, v); } +void GLES2Uniform4ui(GLint location, GLuint x, GLuint y, GLuint z, GLuint w) { + gles2::GetGLContext()->Uniform4ui(location, x, y, z, w); +} +void GLES2Uniform4uiv(GLint location, GLsizei count, const GLuint* v) { + gles2::GetGLContext()->Uniform4uiv(location, count, v); +} +void GLES2UniformBlockBinding(GLuint program, GLuint index, GLuint binding) { + gles2::GetGLContext()->UniformBlockBinding(program, index, binding); +} void GLES2UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { gles2::GetGLContext()->UniformMatrix2fv(location, count, transpose, value); } +void GLES2UniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + gles2::GetGLContext()->UniformMatrix2x3fv(location, count, transpose, value); +} +void GLES2UniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + gles2::GetGLContext()->UniformMatrix2x4fv(location, count, transpose, value); +} void GLES2UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { gles2::GetGLContext()->UniformMatrix3fv(location, count, transpose, value); } +void GLES2UniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + gles2::GetGLContext()->UniformMatrix3x2fv(location, count, transpose, value); +} +void GLES2UniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + gles2::GetGLContext()->UniformMatrix3x4fv(location, count, transpose, value); +} void GLES2UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { gles2::GetGLContext()->UniformMatrix4fv(location, count, transpose, value); } +void GLES2UniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + gles2::GetGLContext()->UniformMatrix4x2fv(location, count, transpose, value); +} +void GLES2UniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + gles2::GetGLContext()->UniformMatrix4x3fv(location, count, transpose, value); +} void GLES2UseProgram(GLuint program) { gles2::GetGLContext()->UseProgram(program); } @@ -595,6 +959,29 @@ void GLES2VertexAttrib4f(GLuint indx, void GLES2VertexAttrib4fv(GLuint indx, const GLfloat* values) { gles2::GetGLContext()->VertexAttrib4fv(indx, values); } +void GLES2VertexAttribI4i(GLuint indx, GLint x, GLint y, GLint z, GLint w) { + gles2::GetGLContext()->VertexAttribI4i(indx, x, y, z, w); +} +void GLES2VertexAttribI4iv(GLuint indx, const GLint* values) { + gles2::GetGLContext()->VertexAttribI4iv(indx, values); +} +void GLES2VertexAttribI4ui(GLuint indx, + GLuint x, + GLuint y, + GLuint z, + GLuint w) { + gles2::GetGLContext()->VertexAttribI4ui(indx, x, y, z, w); +} +void GLES2VertexAttribI4uiv(GLuint indx, const GLuint* values) { + gles2::GetGLContext()->VertexAttribI4uiv(indx, values); +} +void GLES2VertexAttribIPointer(GLuint indx, + GLint size, + GLenum type, + GLsizei stride, + const void* ptr) { + gles2::GetGLContext()->VertexAttribIPointer(indx, size, type, stride, ptr); +} void GLES2VertexAttribPointer(GLuint indx, GLint size, GLenum type, @@ -607,6 +994,9 @@ void GLES2VertexAttribPointer(GLuint indx, void GLES2Viewport(GLint x, GLint y, GLsizei width, GLsizei height) { gles2::GetGLContext()->Viewport(x, y, width, height); } +void GLES2WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { + gles2::GetGLContext()->WaitSync(sync, flags, timeout); +} void GLES2BlitFramebufferCHROMIUM(GLint srcX0, GLint srcY0, GLint srcX1, @@ -665,9 +1055,15 @@ GLboolean GLES2IsQueryEXT(GLuint id) { void GLES2BeginQueryEXT(GLenum target, GLuint id) { gles2::GetGLContext()->BeginQueryEXT(target, id); } +void GLES2BeginTransformFeedback(GLenum primitivemode) { + gles2::GetGLContext()->BeginTransformFeedback(primitivemode); +} void GLES2EndQueryEXT(GLenum target) { gles2::GetGLContext()->EndQueryEXT(target); } +void GLES2EndTransformFeedback() { + gles2::GetGLContext()->EndTransformFeedback(); +} void GLES2GetQueryivEXT(GLenum target, GLenum pname, GLint* params) { gles2::GetGLContext()->GetQueryivEXT(target, pname, params); } @@ -724,6 +1120,15 @@ void* GLES2MapBufferSubDataCHROMIUM(GLuint target, void GLES2UnmapBufferSubDataCHROMIUM(const void* mem) { gles2::GetGLContext()->UnmapBufferSubDataCHROMIUM(mem); } +void* GLES2MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) { + return gles2::GetGLContext()->MapBufferRange(target, offset, size, access); +} +GLboolean GLES2UnmapBuffer(GLenum target) { + return gles2::GetGLContext()->UnmapBuffer(target); +} void* GLES2MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, @@ -751,19 +1156,31 @@ void GLES2RequestExtensionCHROMIUM(const char* extension) { void GLES2RateLimitOffscreenContextCHROMIUM() { gles2::GetGLContext()->RateLimitOffscreenContextCHROMIUM(); } -void GLES2GetMultipleIntegervCHROMIUM(const GLenum* pnames, - GLuint count, - GLint* results, - GLsizeiptr size) { - gles2::GetGLContext()->GetMultipleIntegervCHROMIUM(pnames, count, results, - size); -} void GLES2GetProgramInfoCHROMIUM(GLuint program, GLsizei bufsize, GLsizei* size, void* info) { gles2::GetGLContext()->GetProgramInfoCHROMIUM(program, bufsize, size, info); } +void GLES2GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) { + gles2::GetGLContext()->GetUniformBlocksCHROMIUM(program, bufsize, size, info); +} +void GLES2GetTransformFeedbackVaryingsCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) { + gles2::GetGLContext()->GetTransformFeedbackVaryingsCHROMIUM(program, bufsize, + size, info); +} +void GLES2GetUniformsES3CHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) { + gles2::GetGLContext()->GetUniformsES3CHROMIUM(program, bufsize, size, info); +} GLuint GLES2CreateStreamTextureCHROMIUM(GLuint texture) { return gles2::GetGLContext()->CreateStreamTextureCHROMIUM(texture); } @@ -805,12 +1222,19 @@ void GLES2TexImageIOSurface2DCHROMIUM(GLenum target, void GLES2CopyTextureCHROMIUM(GLenum target, GLenum source_id, GLenum dest_id, - GLint level, GLint internalformat, GLenum dest_type) { - gles2::GetGLContext()->CopyTextureCHROMIUM(target, source_id, dest_id, level, + gles2::GetGLContext()->CopyTextureCHROMIUM(target, source_id, dest_id, internalformat, dest_type); } +void GLES2CopySubTextureCHROMIUM(GLenum target, + GLenum source_id, + GLenum dest_id, + GLint xoffset, + GLint yoffset) { + gles2::GetGLContext()->CopySubTextureCHROMIUM(target, source_id, dest_id, + xoffset, yoffset); +} void GLES2DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, @@ -883,8 +1307,9 @@ void GLES2BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { void GLES2ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { gles2::GetGLContext()->ReleaseTexImage2DCHROMIUM(target, imageId); } -void GLES2TraceBeginCHROMIUM(const char* name) { - gles2::GetGLContext()->TraceBeginCHROMIUM(name); +void GLES2TraceBeginCHROMIUM(const char* category_name, + const char* trace_name) { + gles2::GetGLContext()->TraceBeginCHROMIUM(category_name, trace_name); } void GLES2TraceEndCHROMIUM() { gles2::GetGLContext()->TraceEndCHROMIUM(); @@ -955,6 +1380,9 @@ void GLES2ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order, plane_z_order, plane_transform, overlay_texture_id, bounds_x, bounds_y, bounds_width, bounds_height, uv_x, uv_y, uv_width, uv_height); } +void GLES2SwapInterval(GLint interval) { + gles2::GetGLContext()->SwapInterval(interval); +} void GLES2MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) { gles2::GetGLContext()->MatrixLoadfCHROMIUM(matrixMode, m); } @@ -985,6 +1413,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glBindBuffer), }, { + "glBindBufferBase", + reinterpret_cast<GLES2FunctionPointer>(glBindBufferBase), + }, + { + "glBindBufferRange", + reinterpret_cast<GLES2FunctionPointer>(glBindBufferRange), + }, + { "glBindFramebuffer", reinterpret_cast<GLES2FunctionPointer>(glBindFramebuffer), }, @@ -993,10 +1429,18 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glBindRenderbuffer), }, { + "glBindSampler", + reinterpret_cast<GLES2FunctionPointer>(glBindSampler), + }, + { "glBindTexture", reinterpret_cast<GLES2FunctionPointer>(glBindTexture), }, { + "glBindTransformFeedback", + reinterpret_cast<GLES2FunctionPointer>(glBindTransformFeedback), + }, + { "glBlendColor", reinterpret_cast<GLES2FunctionPointer>(glBlendColor), }, @@ -1033,6 +1477,22 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glClear), }, { + "glClearBufferfi", + reinterpret_cast<GLES2FunctionPointer>(glClearBufferfi), + }, + { + "glClearBufferfv", + reinterpret_cast<GLES2FunctionPointer>(glClearBufferfv), + }, + { + "glClearBufferiv", + reinterpret_cast<GLES2FunctionPointer>(glClearBufferiv), + }, + { + "glClearBufferuiv", + reinterpret_cast<GLES2FunctionPointer>(glClearBufferuiv), + }, + { "glClearColor", reinterpret_cast<GLES2FunctionPointer>(glClearColor), }, @@ -1045,6 +1505,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glClearStencil), }, { + "glClientWaitSync", + reinterpret_cast<GLES2FunctionPointer>(glClientWaitSync), + }, + { "glColorMask", reinterpret_cast<GLES2FunctionPointer>(glColorMask), }, @@ -1061,6 +1525,18 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glCompressedTexSubImage2D), }, { + "glCompressedTexImage3D", + reinterpret_cast<GLES2FunctionPointer>(glCompressedTexImage3D), + }, + { + "glCompressedTexSubImage3D", + reinterpret_cast<GLES2FunctionPointer>(glCompressedTexSubImage3D), + }, + { + "glCopyBufferSubData", + reinterpret_cast<GLES2FunctionPointer>(glCopyBufferSubData), + }, + { "glCopyTexImage2D", reinterpret_cast<GLES2FunctionPointer>(glCopyTexImage2D), }, @@ -1069,6 +1545,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glCopyTexSubImage2D), }, { + "glCopyTexSubImage3D", + reinterpret_cast<GLES2FunctionPointer>(glCopyTexSubImage3D), + }, + { "glCreateProgram", reinterpret_cast<GLES2FunctionPointer>(glCreateProgram), }, @@ -1097,6 +1577,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glDeleteRenderbuffers), }, { + "glDeleteSamplers", + reinterpret_cast<GLES2FunctionPointer>(glDeleteSamplers), + }, + { + "glDeleteSync", + reinterpret_cast<GLES2FunctionPointer>(glDeleteSync), + }, + { "glDeleteShader", reinterpret_cast<GLES2FunctionPointer>(glDeleteShader), }, @@ -1105,6 +1593,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glDeleteTextures), }, { + "glDeleteTransformFeedbacks", + reinterpret_cast<GLES2FunctionPointer>(glDeleteTransformFeedbacks), + }, + { "glDepthFunc", reinterpret_cast<GLES2FunctionPointer>(glDepthFunc), }, @@ -1137,6 +1629,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glDrawElements), }, { + "glDrawRangeElements", + reinterpret_cast<GLES2FunctionPointer>(glDrawRangeElements), + }, + { "glEnable", reinterpret_cast<GLES2FunctionPointer>(glEnable), }, @@ -1145,6 +1641,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glEnableVertexAttribArray), }, { + "glFenceSync", + reinterpret_cast<GLES2FunctionPointer>(glFenceSync), + }, + { "glFinish", reinterpret_cast<GLES2FunctionPointer>(glFinish), }, @@ -1161,6 +1661,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glFramebufferTexture2D), }, { + "glFramebufferTextureLayer", + reinterpret_cast<GLES2FunctionPointer>(glFramebufferTextureLayer), + }, + { "glFrontFace", reinterpret_cast<GLES2FunctionPointer>(glFrontFace), }, @@ -1181,10 +1685,18 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glGenRenderbuffers), }, { + "glGenSamplers", + reinterpret_cast<GLES2FunctionPointer>(glGenSamplers), + }, + { "glGenTextures", reinterpret_cast<GLES2FunctionPointer>(glGenTextures), }, { + "glGenTransformFeedbacks", + reinterpret_cast<GLES2FunctionPointer>(glGenTransformFeedbacks), + }, + { "glGetActiveAttrib", reinterpret_cast<GLES2FunctionPointer>(glGetActiveAttrib), }, @@ -1193,6 +1705,18 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glGetActiveUniform), }, { + "glGetActiveUniformBlockiv", + reinterpret_cast<GLES2FunctionPointer>(glGetActiveUniformBlockiv), + }, + { + "glGetActiveUniformBlockName", + reinterpret_cast<GLES2FunctionPointer>(glGetActiveUniformBlockName), + }, + { + "glGetActiveUniformsiv", + reinterpret_cast<GLES2FunctionPointer>(glGetActiveUniformsiv), + }, + { "glGetAttachedShaders", reinterpret_cast<GLES2FunctionPointer>(glGetAttachedShaders), }, @@ -1217,15 +1741,35 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glGetFloatv), }, { + "glGetFragDataLocation", + reinterpret_cast<GLES2FunctionPointer>(glGetFragDataLocation), + }, + { "glGetFramebufferAttachmentParameteriv", reinterpret_cast<GLES2FunctionPointer>( glGetFramebufferAttachmentParameteriv), }, { + "glGetInteger64v", + reinterpret_cast<GLES2FunctionPointer>(glGetInteger64v), + }, + { + "glGetIntegeri_v", + reinterpret_cast<GLES2FunctionPointer>(glGetIntegeri_v), + }, + { + "glGetInteger64i_v", + reinterpret_cast<GLES2FunctionPointer>(glGetInteger64i_v), + }, + { "glGetIntegerv", reinterpret_cast<GLES2FunctionPointer>(glGetIntegerv), }, { + "glGetInternalformativ", + reinterpret_cast<GLES2FunctionPointer>(glGetInternalformativ), + }, + { "glGetProgramiv", reinterpret_cast<GLES2FunctionPointer>(glGetProgramiv), }, @@ -1238,6 +1782,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glGetRenderbufferParameteriv), }, { + "glGetSamplerParameterfv", + reinterpret_cast<GLES2FunctionPointer>(glGetSamplerParameterfv), + }, + { + "glGetSamplerParameteriv", + reinterpret_cast<GLES2FunctionPointer>(glGetSamplerParameteriv), + }, + { "glGetShaderiv", reinterpret_cast<GLES2FunctionPointer>(glGetShaderiv), }, @@ -1258,6 +1810,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glGetString), }, { + "glGetSynciv", + reinterpret_cast<GLES2FunctionPointer>(glGetSynciv), + }, + { "glGetTexParameterfv", reinterpret_cast<GLES2FunctionPointer>(glGetTexParameterfv), }, @@ -1266,6 +1822,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glGetTexParameteriv), }, { + "glGetTransformFeedbackVarying", + reinterpret_cast<GLES2FunctionPointer>(glGetTransformFeedbackVarying), + }, + { + "glGetUniformBlockIndex", + reinterpret_cast<GLES2FunctionPointer>(glGetUniformBlockIndex), + }, + { "glGetUniformfv", reinterpret_cast<GLES2FunctionPointer>(glGetUniformfv), }, @@ -1274,6 +1838,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glGetUniformiv), }, { + "glGetUniformuiv", + reinterpret_cast<GLES2FunctionPointer>(glGetUniformuiv), + }, + { + "glGetUniformIndices", + reinterpret_cast<GLES2FunctionPointer>(glGetUniformIndices), + }, + { "glGetUniformLocation", reinterpret_cast<GLES2FunctionPointer>(glGetUniformLocation), }, @@ -1286,6 +1858,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glGetVertexAttribiv), }, { + "glGetVertexAttribIiv", + reinterpret_cast<GLES2FunctionPointer>(glGetVertexAttribIiv), + }, + { + "glGetVertexAttribIuiv", + reinterpret_cast<GLES2FunctionPointer>(glGetVertexAttribIuiv), + }, + { "glGetVertexAttribPointerv", reinterpret_cast<GLES2FunctionPointer>(glGetVertexAttribPointerv), }, @@ -1294,6 +1874,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glHint), }, { + "glInvalidateFramebuffer", + reinterpret_cast<GLES2FunctionPointer>(glInvalidateFramebuffer), + }, + { + "glInvalidateSubFramebuffer", + reinterpret_cast<GLES2FunctionPointer>(glInvalidateSubFramebuffer), + }, + { "glIsBuffer", reinterpret_cast<GLES2FunctionPointer>(glIsBuffer), }, @@ -1314,14 +1902,26 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glIsRenderbuffer), }, { + "glIsSampler", + reinterpret_cast<GLES2FunctionPointer>(glIsSampler), + }, + { "glIsShader", reinterpret_cast<GLES2FunctionPointer>(glIsShader), }, { + "glIsSync", + reinterpret_cast<GLES2FunctionPointer>(glIsSync), + }, + { "glIsTexture", reinterpret_cast<GLES2FunctionPointer>(glIsTexture), }, { + "glIsTransformFeedback", + reinterpret_cast<GLES2FunctionPointer>(glIsTransformFeedback), + }, + { "glLineWidth", reinterpret_cast<GLES2FunctionPointer>(glLineWidth), }, @@ -1330,6 +1930,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glLinkProgram), }, { + "glPauseTransformFeedback", + reinterpret_cast<GLES2FunctionPointer>(glPauseTransformFeedback), + }, + { "glPixelStorei", reinterpret_cast<GLES2FunctionPointer>(glPixelStorei), }, @@ -1338,6 +1942,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glPolygonOffset), }, { + "glReadBuffer", + reinterpret_cast<GLES2FunctionPointer>(glReadBuffer), + }, + { "glReadPixels", reinterpret_cast<GLES2FunctionPointer>(glReadPixels), }, @@ -1350,10 +1958,30 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glRenderbufferStorage), }, { + "glResumeTransformFeedback", + reinterpret_cast<GLES2FunctionPointer>(glResumeTransformFeedback), + }, + { "glSampleCoverage", reinterpret_cast<GLES2FunctionPointer>(glSampleCoverage), }, { + "glSamplerParameterf", + reinterpret_cast<GLES2FunctionPointer>(glSamplerParameterf), + }, + { + "glSamplerParameterfv", + reinterpret_cast<GLES2FunctionPointer>(glSamplerParameterfv), + }, + { + "glSamplerParameteri", + reinterpret_cast<GLES2FunctionPointer>(glSamplerParameteri), + }, + { + "glSamplerParameteriv", + reinterpret_cast<GLES2FunctionPointer>(glSamplerParameteriv), + }, + { "glScissor", reinterpret_cast<GLES2FunctionPointer>(glScissor), }, @@ -1374,6 +2002,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glShallowFlushCHROMIUM), }, { + "glOrderingBarrierCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glOrderingBarrierCHROMIUM), + }, + { "glStencilFunc", reinterpret_cast<GLES2FunctionPointer>(glStencilFunc), }, @@ -1402,6 +2034,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glTexImage2D), }, { + "glTexImage3D", + reinterpret_cast<GLES2FunctionPointer>(glTexImage3D), + }, + { "glTexParameterf", reinterpret_cast<GLES2FunctionPointer>(glTexParameterf), }, @@ -1418,10 +2054,22 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glTexParameteriv), }, { + "glTexStorage3D", + reinterpret_cast<GLES2FunctionPointer>(glTexStorage3D), + }, + { "glTexSubImage2D", reinterpret_cast<GLES2FunctionPointer>(glTexSubImage2D), }, { + "glTexSubImage3D", + reinterpret_cast<GLES2FunctionPointer>(glTexSubImage3D), + }, + { + "glTransformFeedbackVaryings", + reinterpret_cast<GLES2FunctionPointer>(glTransformFeedbackVaryings), + }, + { "glUniform1f", reinterpret_cast<GLES2FunctionPointer>(glUniform1f), }, @@ -1438,6 +2086,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glUniform1iv), }, { + "glUniform1ui", + reinterpret_cast<GLES2FunctionPointer>(glUniform1ui), + }, + { + "glUniform1uiv", + reinterpret_cast<GLES2FunctionPointer>(glUniform1uiv), + }, + { "glUniform2f", reinterpret_cast<GLES2FunctionPointer>(glUniform2f), }, @@ -1454,6 +2110,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glUniform2iv), }, { + "glUniform2ui", + reinterpret_cast<GLES2FunctionPointer>(glUniform2ui), + }, + { + "glUniform2uiv", + reinterpret_cast<GLES2FunctionPointer>(glUniform2uiv), + }, + { "glUniform3f", reinterpret_cast<GLES2FunctionPointer>(glUniform3f), }, @@ -1470,6 +2134,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glUniform3iv), }, { + "glUniform3ui", + reinterpret_cast<GLES2FunctionPointer>(glUniform3ui), + }, + { + "glUniform3uiv", + reinterpret_cast<GLES2FunctionPointer>(glUniform3uiv), + }, + { "glUniform4f", reinterpret_cast<GLES2FunctionPointer>(glUniform4f), }, @@ -1486,18 +2158,54 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glUniform4iv), }, { + "glUniform4ui", + reinterpret_cast<GLES2FunctionPointer>(glUniform4ui), + }, + { + "glUniform4uiv", + reinterpret_cast<GLES2FunctionPointer>(glUniform4uiv), + }, + { + "glUniformBlockBinding", + reinterpret_cast<GLES2FunctionPointer>(glUniformBlockBinding), + }, + { "glUniformMatrix2fv", reinterpret_cast<GLES2FunctionPointer>(glUniformMatrix2fv), }, { + "glUniformMatrix2x3fv", + reinterpret_cast<GLES2FunctionPointer>(glUniformMatrix2x3fv), + }, + { + "glUniformMatrix2x4fv", + reinterpret_cast<GLES2FunctionPointer>(glUniformMatrix2x4fv), + }, + { "glUniformMatrix3fv", reinterpret_cast<GLES2FunctionPointer>(glUniformMatrix3fv), }, { + "glUniformMatrix3x2fv", + reinterpret_cast<GLES2FunctionPointer>(glUniformMatrix3x2fv), + }, + { + "glUniformMatrix3x4fv", + reinterpret_cast<GLES2FunctionPointer>(glUniformMatrix3x4fv), + }, + { "glUniformMatrix4fv", reinterpret_cast<GLES2FunctionPointer>(glUniformMatrix4fv), }, { + "glUniformMatrix4x2fv", + reinterpret_cast<GLES2FunctionPointer>(glUniformMatrix4x2fv), + }, + { + "glUniformMatrix4x3fv", + reinterpret_cast<GLES2FunctionPointer>(glUniformMatrix4x3fv), + }, + { "glUseProgram", reinterpret_cast<GLES2FunctionPointer>(glUseProgram), }, @@ -1538,6 +2246,26 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glVertexAttrib4fv), }, { + "glVertexAttribI4i", + reinterpret_cast<GLES2FunctionPointer>(glVertexAttribI4i), + }, + { + "glVertexAttribI4iv", + reinterpret_cast<GLES2FunctionPointer>(glVertexAttribI4iv), + }, + { + "glVertexAttribI4ui", + reinterpret_cast<GLES2FunctionPointer>(glVertexAttribI4ui), + }, + { + "glVertexAttribI4uiv", + reinterpret_cast<GLES2FunctionPointer>(glVertexAttribI4uiv), + }, + { + "glVertexAttribIPointer", + reinterpret_cast<GLES2FunctionPointer>(glVertexAttribIPointer), + }, + { "glVertexAttribPointer", reinterpret_cast<GLES2FunctionPointer>(glVertexAttribPointer), }, @@ -1546,6 +2274,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glViewport), }, { + "glWaitSync", + reinterpret_cast<GLES2FunctionPointer>(glWaitSync), + }, + { "glBlitFramebufferCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(glBlitFramebufferCHROMIUM), }, @@ -1585,10 +2317,18 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glBeginQueryEXT), }, { + "glBeginTransformFeedback", + reinterpret_cast<GLES2FunctionPointer>(glBeginTransformFeedback), + }, + { "glEndQueryEXT", reinterpret_cast<GLES2FunctionPointer>(glEndQueryEXT), }, { + "glEndTransformFeedback", + reinterpret_cast<GLES2FunctionPointer>(glEndTransformFeedback), + }, + { "glGetQueryivEXT", reinterpret_cast<GLES2FunctionPointer>(glGetQueryivEXT), }, @@ -1653,6 +2393,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glUnmapBufferSubDataCHROMIUM), }, { + "glMapBufferRange", + reinterpret_cast<GLES2FunctionPointer>(glMapBufferRange), + }, + { + "glUnmapBuffer", + reinterpret_cast<GLES2FunctionPointer>(glUnmapBuffer), + }, + { "glMapTexSubImage2DCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(glMapTexSubImage2DCHROMIUM), }, @@ -1678,14 +2426,23 @@ extern const NameToFunc g_gles2_function_table[] = { glRateLimitOffscreenContextCHROMIUM), }, { - "glGetMultipleIntegervCHROMIUM", - reinterpret_cast<GLES2FunctionPointer>(glGetMultipleIntegervCHROMIUM), - }, - { "glGetProgramInfoCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(glGetProgramInfoCHROMIUM), }, { + "glGetUniformBlocksCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glGetUniformBlocksCHROMIUM), + }, + { + "glGetTransformFeedbackVaryingsCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>( + glGetTransformFeedbackVaryingsCHROMIUM), + }, + { + "glGetUniformsES3CHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glGetUniformsES3CHROMIUM), + }, + { "glCreateStreamTextureCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(glCreateStreamTextureCHROMIUM), }, @@ -1719,6 +2476,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glCopyTextureCHROMIUM), }, { + "glCopySubTextureCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glCopySubTextureCHROMIUM), + }, + { "glDrawArraysInstancedANGLE", reinterpret_cast<GLES2FunctionPointer>(glDrawArraysInstancedANGLE), }, @@ -1843,6 +2604,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glScheduleOverlayPlaneCHROMIUM), }, { + "glSwapInterval", + reinterpret_cast<GLES2FunctionPointer>(glSwapInterval), + }, + { "glMatrixLoadfCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(glMatrixLoadfCHROMIUM), }, diff --git a/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index cfa7a5dddec..838cec68f3b 100644 --- a/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -42,6 +42,24 @@ void BindBuffer(GLenum target, GLuint buffer) { } } +void BindBufferBase(GLenum target, GLuint index, GLuint buffer) { + gles2::cmds::BindBufferBase* c = GetCmdSpace<gles2::cmds::BindBufferBase>(); + if (c) { + c->Init(target, index, buffer); + } +} + +void BindBufferRange(GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) { + gles2::cmds::BindBufferRange* c = GetCmdSpace<gles2::cmds::BindBufferRange>(); + if (c) { + c->Init(target, index, buffer, offset, size); + } +} + void BindFramebuffer(GLenum target, GLuint framebuffer) { gles2::cmds::BindFramebuffer* c = GetCmdSpace<gles2::cmds::BindFramebuffer>(); if (c) { @@ -57,6 +75,13 @@ void BindRenderbuffer(GLenum target, GLuint renderbuffer) { } } +void BindSampler(GLuint unit, GLuint sampler) { + gles2::cmds::BindSampler* c = GetCmdSpace<gles2::cmds::BindSampler>(); + if (c) { + c->Init(unit, sampler); + } +} + void BindTexture(GLenum target, GLuint texture) { gles2::cmds::BindTexture* c = GetCmdSpace<gles2::cmds::BindTexture>(); if (c) { @@ -64,6 +89,14 @@ void BindTexture(GLenum target, GLuint texture) { } } +void BindTransformFeedback(GLenum target, GLuint transformfeedback) { + gles2::cmds::BindTransformFeedback* c = + GetCmdSpace<gles2::cmds::BindTransformFeedback>(); + if (c) { + c->Init(target, transformfeedback); + } +} + void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { gles2::cmds::BlendColor* c = GetCmdSpace<gles2::cmds::BlendColor>(); if (c) { @@ -143,6 +176,49 @@ void Clear(GLbitfield mask) { } } +void ClearBufferfi(GLenum buffer, + GLint drawbuffers, + GLfloat depth, + GLint stencil) { + gles2::cmds::ClearBufferfi* c = GetCmdSpace<gles2::cmds::ClearBufferfi>(); + if (c) { + c->Init(buffer, drawbuffers, depth, stencil); + } +} + +void ClearBufferfvImmediate(GLenum buffer, + GLint drawbuffers, + const GLfloat* value) { + const uint32_t size = gles2::cmds::ClearBufferfvImmediate::ComputeSize(); + gles2::cmds::ClearBufferfvImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::ClearBufferfvImmediate>(size); + if (c) { + c->Init(buffer, drawbuffers, value); + } +} + +void ClearBufferivImmediate(GLenum buffer, + GLint drawbuffers, + const GLint* value) { + const uint32_t size = gles2::cmds::ClearBufferivImmediate::ComputeSize(); + gles2::cmds::ClearBufferivImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::ClearBufferivImmediate>(size); + if (c) { + c->Init(buffer, drawbuffers, value); + } +} + +void ClearBufferuivImmediate(GLenum buffer, + GLint drawbuffers, + const GLuint* value) { + const uint32_t size = gles2::cmds::ClearBufferuivImmediate::ComputeSize(); + gles2::cmds::ClearBufferuivImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::ClearBufferuivImmediate>(size); + if (c) { + c->Init(buffer, drawbuffers, value); + } +} + void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { gles2::cmds::ClearColor* c = GetCmdSpace<gles2::cmds::ClearColor>(); if (c) { @@ -164,6 +240,19 @@ void ClearStencil(GLint s) { } } +void ClientWaitSync(GLuint sync, + GLbitfield flags, + GLuint timeout_0, + GLuint timeout_1, + uint32_t result_shm_id, + uint32_t result_shm_offset) { + gles2::cmds::ClientWaitSync* c = GetCmdSpace<gles2::cmds::ClientWaitSync>(); + if (c) { + c->Init(sync, flags, timeout_0, timeout_1, result_shm_id, + result_shm_offset); + } +} + void ColorMask(GLboolean red, GLboolean green, GLboolean blue, @@ -243,6 +332,87 @@ void CompressedTexSubImage2D(GLenum target, } } +void CompressedTexImage3DBucket(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLuint bucket_id) { + gles2::cmds::CompressedTexImage3DBucket* c = + GetCmdSpace<gles2::cmds::CompressedTexImage3DBucket>(); + if (c) { + c->Init(target, level, internalformat, width, height, depth, bucket_id); + } +} + +void CompressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei imageSize, + uint32_t data_shm_id, + uint32_t data_shm_offset) { + gles2::cmds::CompressedTexImage3D* c = + GetCmdSpace<gles2::cmds::CompressedTexImage3D>(); + if (c) { + c->Init(target, level, internalformat, width, height, depth, imageSize, + data_shm_id, data_shm_offset); + } +} + +void CompressedTexSubImage3DBucket(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLuint bucket_id) { + gles2::cmds::CompressedTexSubImage3DBucket* c = + GetCmdSpace<gles2::cmds::CompressedTexSubImage3DBucket>(); + if (c) { + c->Init(target, level, xoffset, yoffset, zoffset, width, height, depth, + format, bucket_id); + } +} + +void CompressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + uint32_t data_shm_id, + uint32_t data_shm_offset) { + gles2::cmds::CompressedTexSubImage3D* c = + GetCmdSpace<gles2::cmds::CompressedTexSubImage3D>(); + if (c) { + c->Init(target, level, xoffset, yoffset, zoffset, width, height, depth, + format, imageSize, data_shm_id, data_shm_offset); + } +} + +void CopyBufferSubData(GLenum readtarget, + GLenum writetarget, + GLintptr readoffset, + GLintptr writeoffset, + GLsizeiptr size) { + gles2::cmds::CopyBufferSubData* c = + GetCmdSpace<gles2::cmds::CopyBufferSubData>(); + if (c) { + c->Init(readtarget, writetarget, readoffset, writeoffset, size); + } +} + void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, @@ -271,6 +441,22 @@ void CopyTexSubImage2D(GLenum target, } } +void CopyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { + gles2::cmds::CopyTexSubImage3D* c = + GetCmdSpace<gles2::cmds::CopyTexSubImage3D>(); + if (c) { + c->Init(target, level, xoffset, yoffset, zoffset, x, y, width, height); + } +} + void CreateProgram(uint32_t client_id) { gles2::cmds::CreateProgram* c = GetCmdSpace<gles2::cmds::CreateProgram>(); if (c) { @@ -330,6 +516,22 @@ void DeleteRenderbuffersImmediate(GLsizei n, const GLuint* renderbuffers) { } } +void DeleteSamplersImmediate(GLsizei n, const GLuint* samplers) { + const uint32_t size = gles2::cmds::DeleteSamplersImmediate::ComputeSize(n); + gles2::cmds::DeleteSamplersImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::DeleteSamplersImmediate>(size); + if (c) { + c->Init(n, samplers); + } +} + +void DeleteSync(GLuint sync) { + gles2::cmds::DeleteSync* c = GetCmdSpace<gles2::cmds::DeleteSync>(); + if (c) { + c->Init(sync); + } +} + void DeleteShader(GLuint shader) { gles2::cmds::DeleteShader* c = GetCmdSpace<gles2::cmds::DeleteShader>(); if (c) { @@ -346,6 +548,17 @@ void DeleteTexturesImmediate(GLsizei n, const GLuint* textures) { } } +void DeleteTransformFeedbacksImmediate(GLsizei n, const GLuint* ids) { + const uint32_t size = + gles2::cmds::DeleteTransformFeedbacksImmediate::ComputeSize(n); + gles2::cmds::DeleteTransformFeedbacksImmediate* c = + GetImmediateCmdSpaceTotalSize< + gles2::cmds::DeleteTransformFeedbacksImmediate>(size); + if (c) { + c->Init(n, ids); + } +} + void DepthFunc(GLenum func) { gles2::cmds::DepthFunc* c = GetCmdSpace<gles2::cmds::DepthFunc>(); if (c) { @@ -421,6 +634,13 @@ void EnableVertexAttribArray(GLuint index) { } } +void FenceSync(uint32_t client_id) { + gles2::cmds::FenceSync* c = GetCmdSpace<gles2::cmds::FenceSync>(); + if (c) { + c->Init(client_id); + } +} + void Finish() { gles2::cmds::Finish* c = GetCmdSpace<gles2::cmds::Finish>(); if (c) { @@ -457,6 +677,18 @@ void FramebufferTexture2D(GLenum target, } } +void FramebufferTextureLayer(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) { + gles2::cmds::FramebufferTextureLayer* c = + GetCmdSpace<gles2::cmds::FramebufferTextureLayer>(); + if (c) { + c->Init(target, attachment, texture, level, layer); + } +} + void FrontFace(GLenum mode) { gles2::cmds::FrontFace* c = GetCmdSpace<gles2::cmds::FrontFace>(); if (c) { @@ -500,6 +732,15 @@ void GenRenderbuffersImmediate(GLsizei n, GLuint* renderbuffers) { } } +void GenSamplersImmediate(GLsizei n, GLuint* samplers) { + const uint32_t size = gles2::cmds::GenSamplersImmediate::ComputeSize(n); + gles2::cmds::GenSamplersImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::GenSamplersImmediate>(size); + if (c) { + c->Init(n, samplers); + } +} + void GenTexturesImmediate(GLsizei n, GLuint* textures) { const uint32_t size = gles2::cmds::GenTexturesImmediate::ComputeSize(n); gles2::cmds::GenTexturesImmediate* c = @@ -509,6 +750,17 @@ void GenTexturesImmediate(GLsizei n, GLuint* textures) { } } +void GenTransformFeedbacksImmediate(GLsizei n, GLuint* ids) { + const uint32_t size = + gles2::cmds::GenTransformFeedbacksImmediate::ComputeSize(n); + gles2::cmds::GenTransformFeedbacksImmediate* c = + GetImmediateCmdSpaceTotalSize< + gles2::cmds::GenTransformFeedbacksImmediate>(size); + if (c) { + c->Init(n, ids); + } +} + void GetActiveAttrib(GLuint program, GLuint index, uint32_t name_bucket_id, @@ -532,6 +784,43 @@ void GetActiveUniform(GLuint program, } } +void GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + uint32_t params_shm_id, + uint32_t params_shm_offset) { + gles2::cmds::GetActiveUniformBlockiv* c = + GetCmdSpace<gles2::cmds::GetActiveUniformBlockiv>(); + if (c) { + c->Init(program, index, pname, params_shm_id, params_shm_offset); + } +} + +void GetActiveUniformBlockName(GLuint program, + GLuint index, + uint32_t name_bucket_id, + uint32_t result_shm_id, + uint32_t result_shm_offset) { + gles2::cmds::GetActiveUniformBlockName* c = + GetCmdSpace<gles2::cmds::GetActiveUniformBlockName>(); + if (c) { + c->Init(program, index, name_bucket_id, result_shm_id, result_shm_offset); + } +} + +void GetActiveUniformsiv(GLuint program, + uint32_t indices_bucket_id, + GLenum pname, + uint32_t params_shm_id, + uint32_t params_shm_offset) { + gles2::cmds::GetActiveUniformsiv* c = + GetCmdSpace<gles2::cmds::GetActiveUniformsiv>(); + if (c) { + c->Init(program, indices_bucket_id, pname, params_shm_id, + params_shm_offset); + } +} + void GetAttachedShaders(GLuint program, uint32_t result_shm_id, uint32_t result_shm_offset, @@ -590,6 +879,17 @@ void GetFloatv(GLenum pname, } } +void GetFragDataLocation(GLuint program, + uint32_t name_bucket_id, + uint32_t location_shm_id, + uint32_t location_shm_offset) { + gles2::cmds::GetFragDataLocation* c = + GetCmdSpace<gles2::cmds::GetFragDataLocation>(); + if (c) { + c->Init(program, name_bucket_id, location_shm_id, location_shm_offset); + } +} + void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, @@ -602,6 +902,35 @@ void GetFramebufferAttachmentParameteriv(GLenum target, } } +void GetInteger64v(GLenum pname, + uint32_t params_shm_id, + uint32_t params_shm_offset) { + gles2::cmds::GetInteger64v* c = GetCmdSpace<gles2::cmds::GetInteger64v>(); + if (c) { + c->Init(pname, params_shm_id, params_shm_offset); + } +} + +void GetIntegeri_v(GLenum pname, + GLuint index, + uint32_t data_shm_id, + uint32_t data_shm_offset) { + gles2::cmds::GetIntegeri_v* c = GetCmdSpace<gles2::cmds::GetIntegeri_v>(); + if (c) { + c->Init(pname, index, data_shm_id, data_shm_offset); + } +} + +void GetInteger64i_v(GLenum pname, + GLuint index, + uint32_t data_shm_id, + uint32_t data_shm_offset) { + gles2::cmds::GetInteger64i_v* c = GetCmdSpace<gles2::cmds::GetInteger64i_v>(); + if (c) { + c->Init(pname, index, data_shm_id, data_shm_offset); + } +} + void GetIntegerv(GLenum pname, uint32_t params_shm_id, uint32_t params_shm_offset) { @@ -611,6 +940,19 @@ void GetIntegerv(GLenum pname, } } +void GetInternalformativ(GLenum target, + GLenum format, + GLenum pname, + GLsizei bufSize, + uint32_t params_shm_id, + uint32_t params_shm_offset) { + gles2::cmds::GetInternalformativ* c = + GetCmdSpace<gles2::cmds::GetInternalformativ>(); + if (c) { + c->Init(target, format, pname, bufSize, params_shm_id, params_shm_offset); + } +} + void GetProgramiv(GLuint program, GLenum pname, uint32_t params_shm_id, @@ -640,6 +982,28 @@ void GetRenderbufferParameteriv(GLenum target, } } +void GetSamplerParameterfv(GLuint sampler, + GLenum pname, + uint32_t params_shm_id, + uint32_t params_shm_offset) { + gles2::cmds::GetSamplerParameterfv* c = + GetCmdSpace<gles2::cmds::GetSamplerParameterfv>(); + if (c) { + c->Init(sampler, pname, params_shm_id, params_shm_offset); + } +} + +void GetSamplerParameteriv(GLuint sampler, + GLenum pname, + uint32_t params_shm_id, + uint32_t params_shm_offset) { + gles2::cmds::GetSamplerParameteriv* c = + GetCmdSpace<gles2::cmds::GetSamplerParameteriv>(); + if (c) { + c->Init(sampler, pname, params_shm_id, params_shm_offset); + } +} + void GetShaderiv(GLuint shader, GLenum pname, uint32_t params_shm_id, @@ -683,6 +1047,16 @@ void GetString(GLenum name, uint32_t bucket_id) { } } +void GetSynciv(GLuint sync, + GLenum pname, + uint32_t values_shm_id, + uint32_t values_shm_offset) { + gles2::cmds::GetSynciv* c = GetCmdSpace<gles2::cmds::GetSynciv>(); + if (c) { + c->Init(sync, pname, values_shm_id, values_shm_offset); + } +} + void GetTexParameterfv(GLenum target, GLenum pname, uint32_t params_shm_id, @@ -705,6 +1079,29 @@ void GetTexParameteriv(GLenum target, } } +void GetTransformFeedbackVarying(GLuint program, + GLuint index, + uint32_t name_bucket_id, + uint32_t result_shm_id, + uint32_t result_shm_offset) { + gles2::cmds::GetTransformFeedbackVarying* c = + GetCmdSpace<gles2::cmds::GetTransformFeedbackVarying>(); + if (c) { + c->Init(program, index, name_bucket_id, result_shm_id, result_shm_offset); + } +} + +void GetUniformBlockIndex(GLuint program, + uint32_t name_bucket_id, + uint32_t index_shm_id, + uint32_t index_shm_offset) { + gles2::cmds::GetUniformBlockIndex* c = + GetCmdSpace<gles2::cmds::GetUniformBlockIndex>(); + if (c) { + c->Init(program, name_bucket_id, index_shm_id, index_shm_offset); + } +} + void GetUniformfv(GLuint program, GLint location, uint32_t params_shm_id, @@ -725,6 +1122,27 @@ void GetUniformiv(GLuint program, } } +void GetUniformuiv(GLuint program, + GLint location, + uint32_t params_shm_id, + uint32_t params_shm_offset) { + gles2::cmds::GetUniformuiv* c = GetCmdSpace<gles2::cmds::GetUniformuiv>(); + if (c) { + c->Init(program, location, params_shm_id, params_shm_offset); + } +} + +void GetUniformIndices(GLuint program, + uint32_t names_bucket_id, + uint32_t indices_shm_id, + uint32_t indices_shm_offset) { + gles2::cmds::GetUniformIndices* c = + GetCmdSpace<gles2::cmds::GetUniformIndices>(); + if (c) { + c->Init(program, names_bucket_id, indices_shm_id, indices_shm_offset); + } +} + void GetUniformLocation(GLuint program, uint32_t name_bucket_id, uint32_t location_shm_id, @@ -758,6 +1176,28 @@ void GetVertexAttribiv(GLuint index, } } +void GetVertexAttribIiv(GLuint index, + GLenum pname, + uint32_t params_shm_id, + uint32_t params_shm_offset) { + gles2::cmds::GetVertexAttribIiv* c = + GetCmdSpace<gles2::cmds::GetVertexAttribIiv>(); + if (c) { + c->Init(index, pname, params_shm_id, params_shm_offset); + } +} + +void GetVertexAttribIuiv(GLuint index, + GLenum pname, + uint32_t params_shm_id, + uint32_t params_shm_offset) { + gles2::cmds::GetVertexAttribIuiv* c = + GetCmdSpace<gles2::cmds::GetVertexAttribIuiv>(); + if (c) { + c->Init(index, pname, params_shm_id, params_shm_offset); + } +} + void GetVertexAttribPointerv(GLuint index, GLenum pname, uint32_t pointer_shm_id, @@ -776,6 +1216,36 @@ void Hint(GLenum target, GLenum mode) { } } +void InvalidateFramebufferImmediate(GLenum target, + GLsizei count, + const GLenum* attachments) { + const uint32_t size = + gles2::cmds::InvalidateFramebufferImmediate::ComputeSize(count); + gles2::cmds::InvalidateFramebufferImmediate* c = + GetImmediateCmdSpaceTotalSize< + gles2::cmds::InvalidateFramebufferImmediate>(size); + if (c) { + c->Init(target, count, attachments); + } +} + +void InvalidateSubFramebufferImmediate(GLenum target, + GLsizei count, + const GLenum* attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { + const uint32_t size = + gles2::cmds::InvalidateSubFramebufferImmediate::ComputeSize(count); + gles2::cmds::InvalidateSubFramebufferImmediate* c = + GetImmediateCmdSpaceTotalSize< + gles2::cmds::InvalidateSubFramebufferImmediate>(size); + if (c) { + c->Init(target, count, attachments, x, y, width, height); + } +} + void IsBuffer(GLuint buffer, uint32_t result_shm_id, uint32_t result_shm_offset) { @@ -819,6 +1289,15 @@ void IsRenderbuffer(GLuint renderbuffer, } } +void IsSampler(GLuint sampler, + uint32_t result_shm_id, + uint32_t result_shm_offset) { + gles2::cmds::IsSampler* c = GetCmdSpace<gles2::cmds::IsSampler>(); + if (c) { + c->Init(sampler, result_shm_id, result_shm_offset); + } +} + void IsShader(GLuint shader, uint32_t result_shm_id, uint32_t result_shm_offset) { @@ -828,6 +1307,13 @@ void IsShader(GLuint shader, } } +void IsSync(GLuint sync, uint32_t result_shm_id, uint32_t result_shm_offset) { + gles2::cmds::IsSync* c = GetCmdSpace<gles2::cmds::IsSync>(); + if (c) { + c->Init(sync, result_shm_id, result_shm_offset); + } +} + void IsTexture(GLuint texture, uint32_t result_shm_id, uint32_t result_shm_offset) { @@ -837,6 +1323,16 @@ void IsTexture(GLuint texture, } } +void IsTransformFeedback(GLuint transformfeedback, + uint32_t result_shm_id, + uint32_t result_shm_offset) { + gles2::cmds::IsTransformFeedback* c = + GetCmdSpace<gles2::cmds::IsTransformFeedback>(); + if (c) { + c->Init(transformfeedback, result_shm_id, result_shm_offset); + } +} + void LineWidth(GLfloat width) { gles2::cmds::LineWidth* c = GetCmdSpace<gles2::cmds::LineWidth>(); if (c) { @@ -851,6 +1347,14 @@ void LinkProgram(GLuint program) { } } +void PauseTransformFeedback() { + gles2::cmds::PauseTransformFeedback* c = + GetCmdSpace<gles2::cmds::PauseTransformFeedback>(); + if (c) { + c->Init(); + } +} + void PixelStorei(GLenum pname, GLint param) { gles2::cmds::PixelStorei* c = GetCmdSpace<gles2::cmds::PixelStorei>(); if (c) { @@ -865,6 +1369,13 @@ void PolygonOffset(GLfloat factor, GLfloat units) { } } +void ReadBuffer(GLenum src) { + gles2::cmds::ReadBuffer* c = GetCmdSpace<gles2::cmds::ReadBuffer>(); + if (c) { + c->Init(src); + } +} + void ReadPixels(GLint x, GLint y, GLsizei width, @@ -902,6 +1413,14 @@ void RenderbufferStorage(GLenum target, } } +void ResumeTransformFeedback() { + gles2::cmds::ResumeTransformFeedback* c = + GetCmdSpace<gles2::cmds::ResumeTransformFeedback>(); + if (c) { + c->Init(); + } +} + void SampleCoverage(GLclampf value, GLboolean invert) { gles2::cmds::SampleCoverage* c = GetCmdSpace<gles2::cmds::SampleCoverage>(); if (c) { @@ -909,6 +1428,46 @@ void SampleCoverage(GLclampf value, GLboolean invert) { } } +void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) { + gles2::cmds::SamplerParameterf* c = + GetCmdSpace<gles2::cmds::SamplerParameterf>(); + if (c) { + c->Init(sampler, pname, param); + } +} + +void SamplerParameterfvImmediate(GLuint sampler, + GLenum pname, + const GLfloat* params) { + const uint32_t size = gles2::cmds::SamplerParameterfvImmediate::ComputeSize(); + gles2::cmds::SamplerParameterfvImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::SamplerParameterfvImmediate>( + size); + if (c) { + c->Init(sampler, pname, params); + } +} + +void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) { + gles2::cmds::SamplerParameteri* c = + GetCmdSpace<gles2::cmds::SamplerParameteri>(); + if (c) { + c->Init(sampler, pname, param); + } +} + +void SamplerParameterivImmediate(GLuint sampler, + GLenum pname, + const GLint* params) { + const uint32_t size = gles2::cmds::SamplerParameterivImmediate::ComputeSize(); + gles2::cmds::SamplerParameterivImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::SamplerParameterivImmediate>( + size); + if (c) { + c->Init(sampler, pname, params); + } +} + void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) { gles2::cmds::Scissor* c = GetCmdSpace<gles2::cmds::Scissor>(); if (c) { @@ -930,11 +1489,11 @@ void ShaderBinary(GLsizei n, } } -void ShaderSourceBucket(GLuint shader, uint32_t data_bucket_id) { +void ShaderSourceBucket(GLuint shader, uint32_t str_bucket_id) { gles2::cmds::ShaderSourceBucket* c = GetCmdSpace<gles2::cmds::ShaderSourceBucket>(); if (c) { - c->Init(shader, data_bucket_id); + c->Init(shader, str_bucket_id); } } @@ -999,6 +1558,23 @@ void TexImage2D(GLenum target, } } +void TexImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + uint32_t pixels_shm_id, + uint32_t pixels_shm_offset) { + gles2::cmds::TexImage3D* c = GetCmdSpace<gles2::cmds::TexImage3D>(); + if (c) { + c->Init(target, level, internalformat, width, height, depth, format, type, + pixels_shm_id, pixels_shm_offset); + } +} + void TexParameterf(GLenum target, GLenum pname, GLfloat param) { gles2::cmds::TexParameterf* c = GetCmdSpace<gles2::cmds::TexParameterf>(); if (c) { @@ -1033,6 +1609,18 @@ void TexParameterivImmediate(GLenum target, GLenum pname, const GLint* params) { } } +void TexStorage3D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth) { + gles2::cmds::TexStorage3D* c = GetCmdSpace<gles2::cmds::TexStorage3D>(); + if (c) { + c->Init(target, levels, internalFormat, width, height, depth); + } +} + void TexSubImage2D(GLenum target, GLint level, GLint xoffset, @@ -1051,6 +1639,36 @@ void TexSubImage2D(GLenum target, } } +void TexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + uint32_t pixels_shm_id, + uint32_t pixels_shm_offset, + GLboolean internal) { + gles2::cmds::TexSubImage3D* c = GetCmdSpace<gles2::cmds::TexSubImage3D>(); + if (c) { + c->Init(target, level, xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels_shm_id, pixels_shm_offset, internal); + } +} + +void TransformFeedbackVaryingsBucket(GLuint program, + uint32_t varyings_bucket_id, + GLenum buffermode) { + gles2::cmds::TransformFeedbackVaryingsBucket* c = + GetCmdSpace<gles2::cmds::TransformFeedbackVaryingsBucket>(); + if (c) { + c->Init(program, varyings_bucket_id, buffermode); + } +} + void Uniform1f(GLint location, GLfloat x) { gles2::cmds::Uniform1f* c = GetCmdSpace<gles2::cmds::Uniform1f>(); if (c) { @@ -1083,6 +1701,22 @@ void Uniform1ivImmediate(GLint location, GLsizei count, const GLint* v) { } } +void Uniform1ui(GLint location, GLuint x) { + gles2::cmds::Uniform1ui* c = GetCmdSpace<gles2::cmds::Uniform1ui>(); + if (c) { + c->Init(location, x); + } +} + +void Uniform1uivImmediate(GLint location, GLsizei count, const GLuint* v) { + const uint32_t size = gles2::cmds::Uniform1uivImmediate::ComputeSize(count); + gles2::cmds::Uniform1uivImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform1uivImmediate>(size); + if (c) { + c->Init(location, count, v); + } +} + void Uniform2f(GLint location, GLfloat x, GLfloat y) { gles2::cmds::Uniform2f* c = GetCmdSpace<gles2::cmds::Uniform2f>(); if (c) { @@ -1115,6 +1749,22 @@ void Uniform2ivImmediate(GLint location, GLsizei count, const GLint* v) { } } +void Uniform2ui(GLint location, GLuint x, GLuint y) { + gles2::cmds::Uniform2ui* c = GetCmdSpace<gles2::cmds::Uniform2ui>(); + if (c) { + c->Init(location, x, y); + } +} + +void Uniform2uivImmediate(GLint location, GLsizei count, const GLuint* v) { + const uint32_t size = gles2::cmds::Uniform2uivImmediate::ComputeSize(count); + gles2::cmds::Uniform2uivImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform2uivImmediate>(size); + if (c) { + c->Init(location, count, v); + } +} + void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) { gles2::cmds::Uniform3f* c = GetCmdSpace<gles2::cmds::Uniform3f>(); if (c) { @@ -1147,6 +1797,22 @@ void Uniform3ivImmediate(GLint location, GLsizei count, const GLint* v) { } } +void Uniform3ui(GLint location, GLuint x, GLuint y, GLuint z) { + gles2::cmds::Uniform3ui* c = GetCmdSpace<gles2::cmds::Uniform3ui>(); + if (c) { + c->Init(location, x, y, z); + } +} + +void Uniform3uivImmediate(GLint location, GLsizei count, const GLuint* v) { + const uint32_t size = gles2::cmds::Uniform3uivImmediate::ComputeSize(count); + gles2::cmds::Uniform3uivImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform3uivImmediate>(size); + if (c) { + c->Init(location, count, v); + } +} + void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { gles2::cmds::Uniform4f* c = GetCmdSpace<gles2::cmds::Uniform4f>(); if (c) { @@ -1179,6 +1845,30 @@ void Uniform4ivImmediate(GLint location, GLsizei count, const GLint* v) { } } +void Uniform4ui(GLint location, GLuint x, GLuint y, GLuint z, GLuint w) { + gles2::cmds::Uniform4ui* c = GetCmdSpace<gles2::cmds::Uniform4ui>(); + if (c) { + c->Init(location, x, y, z, w); + } +} + +void Uniform4uivImmediate(GLint location, GLsizei count, const GLuint* v) { + const uint32_t size = gles2::cmds::Uniform4uivImmediate::ComputeSize(count); + gles2::cmds::Uniform4uivImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform4uivImmediate>(size); + if (c) { + c->Init(location, count, v); + } +} + +void UniformBlockBinding(GLuint program, GLuint index, GLuint binding) { + gles2::cmds::UniformBlockBinding* c = + GetCmdSpace<gles2::cmds::UniformBlockBinding>(); + if (c) { + c->Init(program, index, binding); + } +} + void UniformMatrix2fvImmediate(GLint location, GLsizei count, const GLfloat* value) { @@ -1192,6 +1882,32 @@ void UniformMatrix2fvImmediate(GLint location, } } +void UniformMatrix2x3fvImmediate(GLint location, + GLsizei count, + const GLfloat* value) { + const uint32_t size = + gles2::cmds::UniformMatrix2x3fvImmediate::ComputeSize(count); + gles2::cmds::UniformMatrix2x3fvImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::UniformMatrix2x3fvImmediate>( + size); + if (c) { + c->Init(location, count, value); + } +} + +void UniformMatrix2x4fvImmediate(GLint location, + GLsizei count, + const GLfloat* value) { + const uint32_t size = + gles2::cmds::UniformMatrix2x4fvImmediate::ComputeSize(count); + gles2::cmds::UniformMatrix2x4fvImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::UniformMatrix2x4fvImmediate>( + size); + if (c) { + c->Init(location, count, value); + } +} + void UniformMatrix3fvImmediate(GLint location, GLsizei count, const GLfloat* value) { @@ -1205,6 +1921,32 @@ void UniformMatrix3fvImmediate(GLint location, } } +void UniformMatrix3x2fvImmediate(GLint location, + GLsizei count, + const GLfloat* value) { + const uint32_t size = + gles2::cmds::UniformMatrix3x2fvImmediate::ComputeSize(count); + gles2::cmds::UniformMatrix3x2fvImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::UniformMatrix3x2fvImmediate>( + size); + if (c) { + c->Init(location, count, value); + } +} + +void UniformMatrix3x4fvImmediate(GLint location, + GLsizei count, + const GLfloat* value) { + const uint32_t size = + gles2::cmds::UniformMatrix3x4fvImmediate::ComputeSize(count); + gles2::cmds::UniformMatrix3x4fvImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::UniformMatrix3x4fvImmediate>( + size); + if (c) { + c->Init(location, count, value); + } +} + void UniformMatrix4fvImmediate(GLint location, GLsizei count, const GLfloat* value) { @@ -1218,6 +1960,32 @@ void UniformMatrix4fvImmediate(GLint location, } } +void UniformMatrix4x2fvImmediate(GLint location, + GLsizei count, + const GLfloat* value) { + const uint32_t size = + gles2::cmds::UniformMatrix4x2fvImmediate::ComputeSize(count); + gles2::cmds::UniformMatrix4x2fvImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::UniformMatrix4x2fvImmediate>( + size); + if (c) { + c->Init(location, count, value); + } +} + +void UniformMatrix4x3fvImmediate(GLint location, + GLsizei count, + const GLfloat* value) { + const uint32_t size = + gles2::cmds::UniformMatrix4x3fvImmediate::ComputeSize(count); + gles2::cmds::UniformMatrix4x3fvImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::UniformMatrix4x3fvImmediate>( + size); + if (c) { + c->Init(location, count, value); + } +} + void UseProgram(GLuint program) { gles2::cmds::UseProgram* c = GetCmdSpace<gles2::cmds::UseProgram>(); if (c) { @@ -1300,6 +2068,53 @@ void VertexAttrib4fvImmediate(GLuint indx, const GLfloat* values) { } } +void VertexAttribI4i(GLuint indx, GLint x, GLint y, GLint z, GLint w) { + gles2::cmds::VertexAttribI4i* c = GetCmdSpace<gles2::cmds::VertexAttribI4i>(); + if (c) { + c->Init(indx, x, y, z, w); + } +} + +void VertexAttribI4ivImmediate(GLuint indx, const GLint* values) { + const uint32_t size = gles2::cmds::VertexAttribI4ivImmediate::ComputeSize(); + gles2::cmds::VertexAttribI4ivImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::VertexAttribI4ivImmediate>( + size); + if (c) { + c->Init(indx, values); + } +} + +void VertexAttribI4ui(GLuint indx, GLuint x, GLuint y, GLuint z, GLuint w) { + gles2::cmds::VertexAttribI4ui* c = + GetCmdSpace<gles2::cmds::VertexAttribI4ui>(); + if (c) { + c->Init(indx, x, y, z, w); + } +} + +void VertexAttribI4uivImmediate(GLuint indx, const GLuint* values) { + const uint32_t size = gles2::cmds::VertexAttribI4uivImmediate::ComputeSize(); + gles2::cmds::VertexAttribI4uivImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::VertexAttribI4uivImmediate>( + size); + if (c) { + c->Init(indx, values); + } +} + +void VertexAttribIPointer(GLuint indx, + GLint size, + GLenum type, + GLsizei stride, + GLuint offset) { + gles2::cmds::VertexAttribIPointer* c = + GetCmdSpace<gles2::cmds::VertexAttribIPointer>(); + if (c) { + c->Init(indx, size, type, stride, offset); + } +} + void VertexAttribPointer(GLuint indx, GLint size, GLenum type, @@ -1320,6 +2135,16 @@ void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) { } } +void WaitSync(GLuint sync, + GLbitfield flags, + GLuint timeout_0, + GLuint timeout_1) { + gles2::cmds::WaitSync* c = GetCmdSpace<gles2::cmds::WaitSync>(); + if (c) { + c->Init(sync, flags, timeout_0, timeout_1); + } +} + void BlitFramebufferCHROMIUM(GLint srcX0, GLint srcY0, GLint srcX1, @@ -1414,6 +2239,14 @@ void BeginQueryEXT(GLenum target, } } +void BeginTransformFeedback(GLenum primitivemode) { + gles2::cmds::BeginTransformFeedback* c = + GetCmdSpace<gles2::cmds::BeginTransformFeedback>(); + if (c) { + c->Init(primitivemode); + } +} + void EndQueryEXT(GLenum target, GLuint submit_count) { gles2::cmds::EndQueryEXT* c = GetCmdSpace<gles2::cmds::EndQueryEXT>(); if (c) { @@ -1421,6 +2254,14 @@ void EndQueryEXT(GLenum target, GLuint submit_count) { } } +void EndTransformFeedback() { + gles2::cmds::EndTransformFeedback* c = + GetCmdSpace<gles2::cmds::EndTransformFeedback>(); + if (c) { + c->Init(); + } +} + void InsertEventMarkerEXT(GLuint bucket_id) { gles2::cmds::InsertEventMarkerEXT* c = GetCmdSpace<gles2::cmds::InsertEventMarkerEXT>(); @@ -1515,6 +2356,28 @@ void EnableFeatureCHROMIUM(GLuint bucket_id, } } +void MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access, + uint32_t data_shm_id, + uint32_t data_shm_offset, + uint32_t result_shm_id, + uint32_t result_shm_offset) { + gles2::cmds::MapBufferRange* c = GetCmdSpace<gles2::cmds::MapBufferRange>(); + if (c) { + c->Init(target, offset, size, access, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + } +} + +void UnmapBuffer(GLenum target) { + gles2::cmds::UnmapBuffer* c = GetCmdSpace<gles2::cmds::UnmapBuffer>(); + if (c) { + c->Init(target); + } +} + void ResizeCHROMIUM(GLuint width, GLuint height, GLfloat scale_factor) { gles2::cmds::ResizeCHROMIUM* c = GetCmdSpace<gles2::cmds::ResizeCHROMIUM>(); if (c) { @@ -1538,23 +2401,33 @@ void RequestExtensionCHROMIUM(uint32_t bucket_id) { } } -void GetMultipleIntegervCHROMIUM(uint32_t pnames_shm_id, - uint32_t pnames_shm_offset, - GLuint count, - uint32_t results_shm_id, - uint32_t results_shm_offset, - GLsizeiptr size) { - gles2::cmds::GetMultipleIntegervCHROMIUM* c = - GetCmdSpace<gles2::cmds::GetMultipleIntegervCHROMIUM>(); +void GetProgramInfoCHROMIUM(GLuint program, uint32_t bucket_id) { + gles2::cmds::GetProgramInfoCHROMIUM* c = + GetCmdSpace<gles2::cmds::GetProgramInfoCHROMIUM>(); if (c) { - c->Init(pnames_shm_id, pnames_shm_offset, count, results_shm_id, - results_shm_offset, size); + c->Init(program, bucket_id); } } -void GetProgramInfoCHROMIUM(GLuint program, uint32_t bucket_id) { - gles2::cmds::GetProgramInfoCHROMIUM* c = - GetCmdSpace<gles2::cmds::GetProgramInfoCHROMIUM>(); +void GetUniformBlocksCHROMIUM(GLuint program, uint32_t bucket_id) { + gles2::cmds::GetUniformBlocksCHROMIUM* c = + GetCmdSpace<gles2::cmds::GetUniformBlocksCHROMIUM>(); + if (c) { + c->Init(program, bucket_id); + } +} + +void GetTransformFeedbackVaryingsCHROMIUM(GLuint program, uint32_t bucket_id) { + gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM* c = + GetCmdSpace<gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM>(); + if (c) { + c->Init(program, bucket_id); + } +} + +void GetUniformsES3CHROMIUM(GLuint program, uint32_t bucket_id) { + gles2::cmds::GetUniformsES3CHROMIUM* c = + GetCmdSpace<gles2::cmds::GetUniformsES3CHROMIUM>(); if (c) { c->Init(program, bucket_id); } @@ -1591,13 +2464,24 @@ void TexImageIOSurface2DCHROMIUM(GLenum target, void CopyTextureCHROMIUM(GLenum target, GLenum source_id, GLenum dest_id, - GLint level, GLint internalformat, GLenum dest_type) { gles2::cmds::CopyTextureCHROMIUM* c = GetCmdSpace<gles2::cmds::CopyTextureCHROMIUM>(); if (c) { - c->Init(target, source_id, dest_id, level, internalformat, dest_type); + c->Init(target, source_id, dest_id, internalformat, dest_type); + } +} + +void CopySubTextureCHROMIUM(GLenum target, + GLenum source_id, + GLenum dest_id, + GLint xoffset, + GLint yoffset) { + gles2::cmds::CopySubTextureCHROMIUM* c = + GetCmdSpace<gles2::cmds::CopySubTextureCHROMIUM>(); + if (c) { + c->Init(target, source_id, dest_id, xoffset, yoffset); } } @@ -1760,11 +2644,11 @@ void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { } } -void TraceBeginCHROMIUM(GLuint bucket_id) { +void TraceBeginCHROMIUM(GLuint category_bucket_id, GLuint name_bucket_id) { gles2::cmds::TraceBeginCHROMIUM* c = GetCmdSpace<gles2::cmds::TraceBeginCHROMIUM>(); if (c) { - c->Init(bucket_id); + c->Init(category_bucket_id, name_bucket_id); } } @@ -1902,6 +2786,13 @@ void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order, } } +void SwapInterval(GLint interval) { + gles2::cmds::SwapInterval* c = GetCmdSpace<gles2::cmds::SwapInterval>(); + if (c) { + c->Init(interval); + } +} + void MatrixLoadfCHROMIUMImmediate(GLenum matrixMode, const GLfloat* m) { const uint32_t size = gles2::cmds::MatrixLoadfCHROMIUMImmediate::ComputeSize(); diff --git a/chromium/gpu/command_buffer/client/gles2_implementation.cc b/chromium/gpu/command_buffer/client/gles2_implementation.cc index de53a6e1f4a..38d53b1b9a9 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation.cc +++ b/chromium/gpu/command_buffer/client/gles2_implementation.cc @@ -8,6 +8,7 @@ #include <GLES2/gl2ext.h> #include <GLES2/gl2extchromium.h> +#include <GLES3/gl3.h> #include <algorithm> #include <limits> #include <map> @@ -16,6 +17,8 @@ #include <sstream> #include <string> #include "base/bind.h" +#include "base/compiler_specific.h" +#include "base/numerics/safe_math.h" #include "gpu/command_buffer/client/buffer_tracker.h" #include "gpu/command_buffer/client/gpu_control.h" #include "gpu/command_buffer/client/program_info_manager.h" @@ -49,21 +52,6 @@ GLES2Implementation::GLStaticState::GLStaticState() { GLES2Implementation::GLStaticState::~GLStaticState() { } -GLES2Implementation::GLStaticState::IntState::IntState() - : max_combined_texture_image_units(0), - max_cube_map_texture_size(0), - max_fragment_uniform_vectors(0), - max_renderbuffer_size(0), - max_texture_image_units(0), - max_texture_size(0), - max_varying_vectors(0), - max_vertex_attribs(0), - max_vertex_texture_image_units(0), - max_vertex_uniform_vectors(0), - num_compressed_texture_formats(0), - num_shader_binary_formats(0), - bind_generates_resource_chromium(0) {} - GLES2Implementation::SingleThreadChecker::SingleThreadChecker( GLES2Implementation* gles2_implementation) : gles2_implementation_(gles2_implementation) { @@ -92,8 +80,10 @@ GLES2Implementation::GLES2Implementation( unpack_alignment_(4), unpack_flip_y_(false), unpack_row_length_(0), + unpack_image_height_(0), unpack_skip_rows_(0), unpack_skip_pixels_(0), + unpack_skip_images_(0), pack_reverse_row_order_(false), active_texture_unit_(0), bound_framebuffer_(0), @@ -114,6 +104,7 @@ GLES2Implementation::GLES2Implementation( support_client_side_arrays_(support_client_side_arrays), use_count_(0), error_message_callback_(NULL), + current_trace_stack_(0), gpu_control_(gpu_control), capabilities_(gpu_control->GetCapabilities()), weak_ptr_factory_(this) { @@ -126,7 +117,7 @@ GLES2Implementation::GLES2Implementation( this_in_hex_ = ss.str(); GPU_CLIENT_LOG_CODE_BLOCK({ - debug_ = CommandLine::ForCurrentProcess()->HasSwitch( + debug_ = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableGPUClientLogging); }); @@ -174,17 +165,22 @@ bool GLES2Implementation::Initialize( } mapped_memory_->set_chunk_size_multiple(chunk_size); - if (!QueryAndCacheStaticState()) - return false; + GLStaticState::ShaderPrecisionMap* shader_precisions = + &static_state_.shader_precisions; + capabilities_.VisitPrecisions([shader_precisions]( + GLenum shader, GLenum type, Capabilities::ShaderPrecision* result) { + const GLStaticState::ShaderPrecisionKey key(shader, type); + cmds::GetShaderPrecisionFormat::Result cached_result = { + true, result->min_range, result->max_range, result->precision}; + shader_precisions->insert(std::make_pair(key, cached_result)); + }); util_.set_num_compressed_texture_formats( - static_state_.int_state.num_compressed_texture_formats); - util_.set_num_shader_binary_formats( - static_state_.int_state.num_shader_binary_formats); + capabilities_.num_compressed_texture_formats); + util_.set_num_shader_binary_formats(capabilities_.num_shader_binary_formats); texture_units_.reset( - new TextureUnit[ - static_state_.int_state.max_combined_texture_image_units]); + new TextureUnit[capabilities_.max_combined_texture_image_units]); query_tracker_.reset(new QueryTracker(mapped_memory_.get())); buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); @@ -196,14 +192,12 @@ bool GLES2Implementation::Initialize( } vertex_array_object_manager_.reset(new VertexArrayObjectManager( - static_state_.int_state.max_vertex_attribs, - reserved_ids_[0], - reserved_ids_[1], + capabilities_.max_vertex_attribs, reserved_ids_[0], reserved_ids_[1], support_client_side_arrays_)); // GL_BIND_GENERATES_RESOURCE_CHROMIUM state must be the same // on Client & Service. - if (static_state_.int_state.bind_generates_resource_chromium != + if (capabilities_.bind_generates_resource_chromium != (share_group_->bind_generates_resource() ? 1 : 0)) { SetGLError(GL_INVALID_OPERATION, "Initialize", @@ -214,80 +208,6 @@ bool GLES2Implementation::Initialize( return true; } -bool GLES2Implementation::QueryAndCacheStaticState() { - TRACE_EVENT0("gpu", "GLES2Implementation::QueryAndCacheStaticState"); - // Setup query for multiple GetIntegerv's - static const GLenum pnames[] = { - GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, - GL_MAX_CUBE_MAP_TEXTURE_SIZE, - GL_MAX_FRAGMENT_UNIFORM_VECTORS, - GL_MAX_RENDERBUFFER_SIZE, - GL_MAX_TEXTURE_IMAGE_UNITS, - GL_MAX_TEXTURE_SIZE, - GL_MAX_VARYING_VECTORS, - GL_MAX_VERTEX_ATTRIBS, - GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, - GL_MAX_VERTEX_UNIFORM_VECTORS, - GL_NUM_COMPRESSED_TEXTURE_FORMATS, - GL_NUM_SHADER_BINARY_FORMATS, - GL_BIND_GENERATES_RESOURCE_CHROMIUM, - }; - - GetMultipleIntegervState integerv_state( - pnames, arraysize(pnames), - &static_state_.int_state.max_combined_texture_image_units, - sizeof(static_state_.int_state)); - if (!GetMultipleIntegervSetup(&integerv_state)) { - return false; - } - - // Setup query for multiple GetShaderPrecisionFormat's - static const GLenum precision_params[][2] = { - { GL_VERTEX_SHADER, GL_LOW_INT }, - { GL_VERTEX_SHADER, GL_MEDIUM_INT }, - { GL_VERTEX_SHADER, GL_HIGH_INT }, - { GL_VERTEX_SHADER, GL_LOW_FLOAT }, - { GL_VERTEX_SHADER, GL_MEDIUM_FLOAT }, - { GL_VERTEX_SHADER, GL_HIGH_FLOAT }, - { GL_FRAGMENT_SHADER, GL_LOW_INT }, - { GL_FRAGMENT_SHADER, GL_MEDIUM_INT }, - { GL_FRAGMENT_SHADER, GL_HIGH_INT }, - { GL_FRAGMENT_SHADER, GL_LOW_FLOAT }, - { GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT }, - { GL_FRAGMENT_SHADER, GL_HIGH_FLOAT }, - }; - - GetAllShaderPrecisionFormatsState precision_state( - precision_params, arraysize(precision_params)); - GetAllShaderPrecisionFormatsSetup(&precision_state); - - // Allocate and partition transfer buffer for all requests - void* buffer = transfer_buffer_->Alloc( - integerv_state.transfer_buffer_size_needed + - precision_state.transfer_buffer_size_needed); - if (!buffer) { - SetGLError(GL_OUT_OF_MEMORY, "QueryAndCacheStaticState", - "Transfer buffer allocation failed."); - return false; - } - integerv_state.buffer = buffer; - precision_state.results_buffer = - static_cast<char*>(buffer) + integerv_state.transfer_buffer_size_needed; - - // Make all the requests and wait once for all the results. - GetMultipleIntegervRequest(&integerv_state); - GetAllShaderPrecisionFormatsRequest(&precision_state); - WaitForCmd(); - GetMultipleIntegervOnCompleted(&integerv_state); - GetAllShaderPrecisionFormatsOnCompleted(&precision_state); - - // TODO(gman): We should be able to free without a token. - transfer_buffer_->FreePendingToken(buffer, helper_->InsertToken()); - CheckGLError(); - - return true; -} - GLES2Implementation::~GLES2Implementation() { // Make sure the queries are finished otherwise we'll delete the // shared memory (mapped_memory_) which will free the memory used @@ -302,6 +222,10 @@ GLES2Implementation::~GLES2Implementation() { DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); } + // Release remaining BufferRange mem; This is when a MapBufferRange() is + // called but not the UnmapBuffer() pair. + ClearMappedBufferRangeMap(); + // Release any per-context data in share group. share_group_->FreeContext(this); @@ -685,102 +609,314 @@ GLboolean GLES2Implementation::IsEnabled(GLenum cap) { } bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { + // TODO(zmo): For all the BINDING points, there is a possibility where + // resources are shared among multiple contexts, that the cached points + // are invalid. It is not a problem for now, but once we allow resource + // sharing in WebGL, we need to implement a mechanism to allow correct + // client side binding points tracking. crbug.com/465562. + + // ES2 parameters. switch (pname) { + case GL_ACTIVE_TEXTURE: + *params = active_texture_unit_ + GL_TEXTURE0; + return true; + case GL_ARRAY_BUFFER_BINDING: + *params = bound_array_buffer_id_; + return true; + case GL_ELEMENT_ARRAY_BUFFER_BINDING: + *params = + vertex_array_object_manager_->bound_element_array_buffer(); + return true; + case GL_FRAMEBUFFER_BINDING: + *params = bound_framebuffer_; + return true; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: - *params = static_state_.int_state.max_combined_texture_image_units; + *params = capabilities_.max_combined_texture_image_units; return true; case GL_MAX_CUBE_MAP_TEXTURE_SIZE: - *params = static_state_.int_state.max_cube_map_texture_size; + *params = capabilities_.max_cube_map_texture_size; return true; case GL_MAX_FRAGMENT_UNIFORM_VECTORS: - *params = static_state_.int_state.max_fragment_uniform_vectors; + *params = capabilities_.max_fragment_uniform_vectors; return true; case GL_MAX_RENDERBUFFER_SIZE: - *params = static_state_.int_state.max_renderbuffer_size; + *params = capabilities_.max_renderbuffer_size; return true; case GL_MAX_TEXTURE_IMAGE_UNITS: - *params = static_state_.int_state.max_texture_image_units; + *params = capabilities_.max_texture_image_units; return true; case GL_MAX_TEXTURE_SIZE: - *params = static_state_.int_state.max_texture_size; + *params = capabilities_.max_texture_size; return true; case GL_MAX_VARYING_VECTORS: - *params = static_state_.int_state.max_varying_vectors; + *params = capabilities_.max_varying_vectors; return true; case GL_MAX_VERTEX_ATTRIBS: - *params = static_state_.int_state.max_vertex_attribs; + *params = capabilities_.max_vertex_attribs; return true; case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: - *params = static_state_.int_state.max_vertex_texture_image_units; + *params = capabilities_.max_vertex_texture_image_units; return true; case GL_MAX_VERTEX_UNIFORM_VECTORS: - *params = static_state_.int_state.max_vertex_uniform_vectors; + *params = capabilities_.max_vertex_uniform_vectors; return true; case GL_NUM_COMPRESSED_TEXTURE_FORMATS: - *params = static_state_.int_state.num_compressed_texture_formats; + *params = capabilities_.num_compressed_texture_formats; return true; case GL_NUM_SHADER_BINARY_FORMATS: - *params = static_state_.int_state.num_shader_binary_formats; + *params = capabilities_.num_shader_binary_formats; + return true; + case GL_RENDERBUFFER_BINDING: + *params = bound_renderbuffer_; + return true; + case GL_TEXTURE_BINDING_2D: + *params = texture_units_[active_texture_unit_].bound_texture_2d; + return true; + case GL_TEXTURE_BINDING_CUBE_MAP: + *params = texture_units_[active_texture_unit_].bound_texture_cube_map; + return true; + + // Non-standard parameters. + case GL_TEXTURE_BINDING_EXTERNAL_OES: + *params = + texture_units_[active_texture_unit_].bound_texture_external_oes; return true; - case GL_ARRAY_BUFFER_BINDING: - if (share_group_->bind_generates_resource()) { - *params = bound_array_buffer_id_; - return true; - } - return false; - case GL_ELEMENT_ARRAY_BUFFER_BINDING: - if (share_group_->bind_generates_resource()) { - *params = - vertex_array_object_manager_->bound_element_array_buffer(); - return true; - } - return false; case GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM: *params = bound_pixel_pack_transfer_buffer_id_; return true; case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: *params = bound_pixel_unpack_transfer_buffer_id_; return true; - case GL_ACTIVE_TEXTURE: - *params = active_texture_unit_ + GL_TEXTURE0; - return true; - case GL_TEXTURE_BINDING_2D: - if (share_group_->bind_generates_resource()) { - *params = texture_units_[active_texture_unit_].bound_texture_2d; - return true; - } - return false; - case GL_TEXTURE_BINDING_CUBE_MAP: - if (share_group_->bind_generates_resource()) { - *params = texture_units_[active_texture_unit_].bound_texture_cube_map; - return true; - } - return false; - case GL_TEXTURE_BINDING_EXTERNAL_OES: - if (share_group_->bind_generates_resource()) { - *params = - texture_units_[active_texture_unit_].bound_texture_external_oes; - return true; - } - return false; - case GL_FRAMEBUFFER_BINDING: - if (share_group_->bind_generates_resource()) { - *params = bound_framebuffer_; - return true; - } - return false; case GL_READ_FRAMEBUFFER_BINDING: - if (IsChromiumFramebufferMultisampleAvailable() && - share_group_->bind_generates_resource()) { + if (IsChromiumFramebufferMultisampleAvailable()) { *params = bound_read_framebuffer_; return true; } + break; + + // Non-cached parameters. + case GL_ALIASED_LINE_WIDTH_RANGE: + case GL_ALIASED_POINT_SIZE_RANGE: + case GL_ALPHA_BITS: + case GL_BLEND: + case GL_BLEND_COLOR: + case GL_BLEND_DST_ALPHA: + case GL_BLEND_DST_RGB: + case GL_BLEND_EQUATION_ALPHA: + case GL_BLEND_EQUATION_RGB: + case GL_BLEND_SRC_ALPHA: + case GL_BLEND_SRC_RGB: + case GL_BLUE_BITS: + case GL_COLOR_CLEAR_VALUE: + case GL_COLOR_WRITEMASK: + case GL_COMPRESSED_TEXTURE_FORMATS: + case GL_CULL_FACE: + case GL_CULL_FACE_MODE: + case GL_CURRENT_PROGRAM: + case GL_DEPTH_BITS: + case GL_DEPTH_CLEAR_VALUE: + case GL_DEPTH_FUNC: + case GL_DEPTH_RANGE: + case GL_DEPTH_TEST: + case GL_DEPTH_WRITEMASK: + case GL_DITHER: + case GL_FRONT_FACE: + case GL_GENERATE_MIPMAP_HINT: + case GL_GREEN_BITS: + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + case GL_LINE_WIDTH: + case GL_MAX_VIEWPORT_DIMS: + case GL_PACK_ALIGNMENT: + case GL_POLYGON_OFFSET_FACTOR: + case GL_POLYGON_OFFSET_FILL: + case GL_POLYGON_OFFSET_UNITS: + case GL_RED_BITS: + case GL_SAMPLE_ALPHA_TO_COVERAGE: + case GL_SAMPLE_BUFFERS: + case GL_SAMPLE_COVERAGE: + case GL_SAMPLE_COVERAGE_INVERT: + case GL_SAMPLE_COVERAGE_VALUE: + case GL_SAMPLES: + case GL_SCISSOR_BOX: + case GL_SCISSOR_TEST: + case GL_SHADER_BINARY_FORMATS: + case GL_SHADER_COMPILER: + case GL_STENCIL_BACK_FAIL: + case GL_STENCIL_BACK_FUNC: + case GL_STENCIL_BACK_PASS_DEPTH_FAIL: + case GL_STENCIL_BACK_PASS_DEPTH_PASS: + case GL_STENCIL_BACK_REF: + case GL_STENCIL_BACK_VALUE_MASK: + case GL_STENCIL_BACK_WRITEMASK: + case GL_STENCIL_BITS: + case GL_STENCIL_CLEAR_VALUE: + case GL_STENCIL_FAIL: + case GL_STENCIL_FUNC: + case GL_STENCIL_PASS_DEPTH_FAIL: + case GL_STENCIL_PASS_DEPTH_PASS: + case GL_STENCIL_REF: + case GL_STENCIL_TEST: + case GL_STENCIL_VALUE_MASK: + case GL_STENCIL_WRITEMASK: + case GL_SUBPIXEL_BITS: + case GL_UNPACK_ALIGNMENT: + case GL_VIEWPORT: return false; - case GL_RENDERBUFFER_BINDING: - if (share_group_->bind_generates_resource()) { - *params = bound_renderbuffer_; - return true; - } + default: + break; + } + + if (capabilities_.major_version < 3) { + return false; + } + + // ES3 parameters. + switch (pname) { + case GL_MAJOR_VERSION: + *params = capabilities_.major_version; + return true; + case GL_MAX_3D_TEXTURE_SIZE: + *params = capabilities_.max_3d_texture_size; + return true; + case GL_MAX_ARRAY_TEXTURE_LAYERS: + *params = capabilities_.max_array_texture_layers; + return true; + case GL_MAX_COLOR_ATTACHMENTS: + *params = capabilities_.max_color_attachments; + return true; + case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: + *params = capabilities_.max_combined_fragment_uniform_components; + return true; + case GL_MAX_COMBINED_UNIFORM_BLOCKS: + *params = capabilities_.max_combined_uniform_blocks; + return true; + case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: + *params = capabilities_.max_combined_vertex_uniform_components; + return true; + case GL_MAX_DRAW_BUFFERS: + *params = capabilities_.max_draw_buffers; + return true; + case GL_MAX_ELEMENT_INDEX: + *params = capabilities_.max_element_index; + return true; + case GL_MAX_ELEMENTS_INDICES: + *params = capabilities_.max_elements_indices; + return true; + case GL_MAX_ELEMENTS_VERTICES: + *params = capabilities_.max_elements_vertices; + return true; + case GL_MAX_FRAGMENT_INPUT_COMPONENTS: + *params = capabilities_.max_fragment_input_components; + return true; + case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: + *params = capabilities_.max_fragment_uniform_blocks; + return true; + case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: + *params = capabilities_.max_fragment_uniform_components; + return true; + case GL_MAX_PROGRAM_TEXEL_OFFSET: + *params = capabilities_.max_program_texel_offset; + return true; + case GL_MAX_SAMPLES: + *params = capabilities_.max_samples; + return true; + case GL_MAX_SERVER_WAIT_TIMEOUT: + *params = capabilities_.max_server_wait_timeout; + return true; + case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: + *params = capabilities_.max_transform_feedback_interleaved_components; + return true; + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: + *params = capabilities_.max_transform_feedback_separate_attribs; + return true; + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: + *params = capabilities_.max_transform_feedback_separate_components; + return true; + case GL_MAX_UNIFORM_BLOCK_SIZE: + *params = capabilities_.max_uniform_block_size; + return true; + case GL_MAX_UNIFORM_BUFFER_BINDINGS: + *params = capabilities_.max_uniform_buffer_bindings; + return true; + case GL_MAX_VARYING_COMPONENTS: + *params = capabilities_.max_varying_components; + return true; + case GL_MAX_VERTEX_OUTPUT_COMPONENTS: + *params = capabilities_.max_vertex_output_components; + return true; + case GL_MAX_VERTEX_UNIFORM_BLOCKS: + *params = capabilities_.max_vertex_uniform_blocks; + return true; + case GL_MAX_VERTEX_UNIFORM_COMPONENTS: + *params = capabilities_.max_vertex_uniform_components; + return true; + case GL_MIN_PROGRAM_TEXEL_OFFSET: + *params = capabilities_.min_program_texel_offset; + return true; + case GL_MINOR_VERSION: + *params = capabilities_.minor_version; + return true; + case GL_NUM_EXTENSIONS: + *params = capabilities_.num_extensions; + return true; + case GL_NUM_PROGRAM_BINARY_FORMATS: + *params = capabilities_.num_program_binary_formats; + return true; + case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + *params = capabilities_.uniform_buffer_offset_alignment; + return true; + + // Non-cached ES3 parameters. + case GL_COPY_READ_BUFFER_BINDING: + case GL_COPY_WRITE_BUFFER_BINDING: + case GL_DRAW_BUFFER0: + case GL_DRAW_BUFFER1: + case GL_DRAW_BUFFER2: + case GL_DRAW_BUFFER3: + case GL_DRAW_BUFFER4: + case GL_DRAW_BUFFER5: + case GL_DRAW_BUFFER6: + case GL_DRAW_BUFFER7: + case GL_DRAW_BUFFER8: + case GL_DRAW_BUFFER9: + case GL_DRAW_BUFFER10: + case GL_DRAW_BUFFER11: + case GL_DRAW_BUFFER12: + case GL_DRAW_BUFFER13: + case GL_DRAW_BUFFER14: + case GL_DRAW_BUFFER15: + case GL_DRAW_FRAMEBUFFER_BINDING: + case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: + case GL_MAX_TEXTURE_LOD_BIAS: + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_PIXELS: + case GL_PACK_SKIP_ROWS: + case GL_PIXEL_PACK_BUFFER_BINDING: + case GL_PIXEL_UNPACK_BUFFER_BINDING: + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + case GL_PROGRAM_BINARY_FORMATS: + case GL_RASTERIZER_DISCARD: + case GL_READ_BUFFER: + case GL_READ_FRAMEBUFFER_BINDING: + case GL_SAMPLER_BINDING: + case GL_TEXTURE_BINDING_2D_ARRAY: + case GL_TEXTURE_BINDING_3D: + case GL_TRANSFORM_FEEDBACK_BINDING: + case GL_TRANSFORM_FEEDBACK_ACTIVE: + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + case GL_TRANSFORM_FEEDBACK_PAUSED: + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + case GL_UNIFORM_BUFFER_BINDING: + case GL_UNIFORM_BUFFER_SIZE: + case GL_UNIFORM_BUFFER_START: + case GL_UNPACK_IMAGE_HEIGHT: + case GL_UNPACK_ROW_LENGTH: + case GL_UNPACK_SKIP_IMAGES: + case GL_UNPACK_SKIP_PIXELS: + case GL_UNPACK_SKIP_ROWS: + case GL_VERTEX_ARRAY_BINDING: return false; default: return false; @@ -807,10 +943,66 @@ bool GLES2Implementation::GetFloatvHelper(GLenum pname, GLfloat* params) { return true; } +bool GLES2Implementation::GetInteger64vHelper(GLenum pname, GLint64* params) { + // TODO(zmo): we limit values to 32-bit, which is OK for now. + GLint value; + if (!GetHelper(pname, &value)) { + return false; + } + *params = value; + return true; +} + bool GLES2Implementation::GetIntegervHelper(GLenum pname, GLint* params) { return GetHelper(pname, params); } +bool GLES2Implementation::GetIntegeri_vHelper( + GLenum pname, GLuint index, GLint* data) { + // TODO(zmo): Implement client side caching. + return false; +} + +bool GLES2Implementation::GetInteger64i_vHelper( + GLenum pname, GLuint index, GLint64* data) { + // TODO(zmo): Implement client side caching. + return false; +} + +bool GLES2Implementation::GetInternalformativHelper( + GLenum target, GLenum format, GLenum pname, GLsizei bufSize, + GLint* params) { + // TODO(zmo): Implement the client side caching. + return false; +} + +bool GLES2Implementation::GetSyncivHelper( + GLsync sync, GLenum pname, GLsizei bufsize, GLsizei* length, + GLint* values) { + GLint value = 0; + switch (pname) { + case GL_OBJECT_TYPE: + value = GL_SYNC_FENCE; + break; + case GL_SYNC_CONDITION: + value = GL_SYNC_GPU_COMMANDS_COMPLETE; + break; + case GL_SYNC_FLAGS: + value = 0; + break; + default: + return false; + } + if (bufsize > 0) { + DCHECK(values); + *values = value; + } + if (length) { + *length = 1; + } + return true; +} + GLuint GLES2Implementation::GetMaxValueInBufferCHROMIUMHelper( GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) { typedef cmds::GetMaxValueInBufferCHROMIUM::Result Result; @@ -865,23 +1057,44 @@ void GLES2Implementation::DrawElements( << count << ", " << GLES2Util::GetStringIndexType(type) << ", " << static_cast<const void*>(indices) << ")"); - if (count < 0) { - SetGLError(GL_INVALID_VALUE, "glDrawElements", "count less than 0."); - return; - } - if (count == 0) { + DrawElementsImpl(mode, count, type, indices, "glDrawRangeElements"); +} + +void GLES2Implementation::DrawRangeElements( + GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, const void* indices) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawRangeElements(" + << GLES2Util::GetStringDrawMode(mode) << ", " + << start << ", " << end << ", " << count << ", " + << GLES2Util::GetStringIndexType(type) << ", " + << static_cast<const void*>(indices) << ")"); + if (end < start) { + SetGLError(GL_INVALID_VALUE, "glDrawRangeElements", "end < start"); return; } - if (vertex_array_object_manager_->bound_element_array_buffer() != 0 && - !ValidateOffset("glDrawElements", reinterpret_cast<GLintptr>(indices))) { + DrawElementsImpl(mode, count, type, indices, "glDrawRangeElements"); +} + +void GLES2Implementation::DrawElementsImpl( + GLenum mode, GLsizei count, GLenum type, const void* indices, + const char* func_name) { + if (count < 0) { + SetGLError(GL_INVALID_VALUE, func_name, "count < 0"); return; } - GLuint offset = 0; bool simulated = false; - if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers( - "glDrawElements", this, helper_, count, type, 0, indices, - &offset, &simulated)) { - return; + GLuint offset = ToGLuint(indices); + if (count > 0) { + if (vertex_array_object_manager_->bound_element_array_buffer() != 0 && + !ValidateOffset(func_name, reinterpret_cast<GLintptr>(indices))) { + return; + } + if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers( + func_name, this, helper_, count, type, 0, indices, + &offset, &simulated)) { + return; + } } helper_->DrawElements(mode, count, type, offset); RestoreElementAndArrayBuffers(simulated); @@ -907,6 +1120,13 @@ void GLES2Implementation::ShallowFlushCHROMIUM() { // TODO(piman): Add the FreeEverything() logic here. } +void GLES2Implementation::OrderingBarrierCHROMIUM() { + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glOrderingBarrierCHROMIUM"); + // Flush command buffer at the GPU channel level. May be implemented as + // Flush(). + helper_->CommandBufferHelper::OrderingBarrier(); +} + void GLES2Implementation::Finish() { GPU_CLIENT_SINGLE_THREAD_CHECK(); FinishHelper(); @@ -952,6 +1172,13 @@ void GLES2Implementation::SwapBuffers() { } } +void GLES2Implementation::SwapInterval(int interval) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSwapInterval(" + << interval << ")"); + helper_->SwapInterval(interval); +} + void GLES2Implementation::BindAttribLocation( GLuint program, GLuint index, const char* name) { GPU_CLIENT_SINGLE_THREAD_CHECK(); @@ -1043,6 +1270,20 @@ void GLES2Implementation::DeleteShaderStub( helper_->DeleteShader(shaders[0]); } +void GLES2Implementation::DeleteSyncHelper(GLsync sync) { + GLuint sync_uint = ToGLuint(sync); + if (!GetIdHandler(id_namespaces::kSyncs)->FreeIds( + this, 1, &sync_uint, &GLES2Implementation::DeleteSyncStub)) { + SetGLError( + GL_INVALID_VALUE, + "glDeleteSync", "id not created by this context."); + } +} + +void GLES2Implementation::DeleteSyncStub(GLsizei n, const GLuint* syncs) { + DCHECK_EQ(1, n); + helper_->DeleteSync(syncs[0]); +} GLint GLES2Implementation::GetAttribLocationHelper( GLuint program, const char* name) { @@ -1102,6 +1343,52 @@ GLint GLES2Implementation::GetUniformLocation( return loc; } +bool GLES2Implementation::GetUniformIndicesHelper( + GLuint program, GLsizei count, const char* const* names, GLuint* indices) { + typedef cmds::GetUniformIndices::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return false; + } + result->SetNumResults(0); + if (!PackStringsToBucket(count, names, NULL, "glGetUniformIndices")) { + return false; + } + helper_->GetUniformIndices(program, kResultBucketId, + GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + if (result->GetNumResults() != count) { + return false; + } + result->CopyResult(indices); + return true; +} + +void GLES2Implementation::GetUniformIndices( + GLuint program, GLsizei count, const char* const* names, GLuint* indices) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetUniformIndices(" << program + << ", " << count << ", " << names << ", " << indices << ")"); + TRACE_EVENT0("gpu", "GLES2::GetUniformIndices"); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glGetUniformIndices", "count < 0"); + return; + } + if (count == 0) { + return; + } + bool success = share_group_->program_info_manager()->GetUniformIndices( + this, program, count, names, indices); + if (success) { + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei ii = 0; ii < count; ++ii) { + GPU_CLIENT_LOG(" " << ii << ": " << indices[ii]); + } + }); + } + CheckGLError(); +} + bool GLES2Implementation::GetProgramivHelper( GLuint program, GLenum pname, GLint* params) { bool got_value = share_group_->program_info_manager()->GetProgramiv( @@ -1114,6 +1401,64 @@ bool GLES2Implementation::GetProgramivHelper( return got_value; } +GLint GLES2Implementation::GetFragDataLocationHelper( + GLuint program, const char* name) { + typedef cmds::GetFragDataLocation::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return -1; + } + *result = -1; + SetBucketAsCString(kResultBucketId, name); + helper_->GetFragDataLocation( + program, kResultBucketId, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + helper_->SetBucketSize(kResultBucketId, 0); + return *result; +} + +GLint GLES2Implementation::GetFragDataLocation( + GLuint program, const char* name) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetFragDataLocation(" + << program << ", " << name << ")"); + TRACE_EVENT0("gpu", "GLES2::GetFragDataLocation"); + GLint loc = share_group_->program_info_manager()->GetFragDataLocation( + this, program, name); + GPU_CLIENT_LOG("returned " << loc); + CheckGLError(); + return loc; +} + +GLuint GLES2Implementation::GetUniformBlockIndexHelper( + GLuint program, const char* name) { + typedef cmds::GetUniformBlockIndex::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return GL_INVALID_INDEX; + } + *result = GL_INVALID_INDEX; + SetBucketAsCString(kResultBucketId, name); + helper_->GetUniformBlockIndex( + program, kResultBucketId, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + helper_->SetBucketSize(kResultBucketId, 0); + return *result; +} + +GLuint GLES2Implementation::GetUniformBlockIndex( + GLuint program, const char* name) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetUniformBlockIndex(" + << program << ", " << name << ")"); + TRACE_EVENT0("gpu", "GLES2::GetUniformBlockIndex"); + GLuint index = share_group_->program_info_manager()->GetUniformBlockIndex( + this, program, name); + GPU_CLIENT_LOG("returned " << index); + CheckGLError(); + return index; +} + void GLES2Implementation::LinkProgram(GLuint program) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glLinkProgram(" << program << ")"); @@ -1177,12 +1522,18 @@ void GLES2Implementation::PixelStorei(GLenum pname, GLint param) { case GL_UNPACK_ROW_LENGTH_EXT: unpack_row_length_ = param; return; + case GL_UNPACK_IMAGE_HEIGHT: + unpack_image_height_ = param; + return; case GL_UNPACK_SKIP_ROWS_EXT: unpack_skip_rows_ = param; return; case GL_UNPACK_SKIP_PIXELS_EXT: unpack_skip_pixels_ = param; return; + case GL_UNPACK_SKIP_IMAGES: + unpack_skip_images_ = param; + return; case GL_UNPACK_FLIP_Y_CHROMIUM: unpack_flip_y_ = (param != 0); break; @@ -1197,6 +1548,39 @@ void GLES2Implementation::PixelStorei(GLenum pname, GLint param) { CheckGLError(); } +void GLES2Implementation::VertexAttribIPointer( + GLuint index, GLint size, GLenum type, GLsizei stride, const void* ptr) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribIPointer(" + << index << ", " + << size << ", " + << GLES2Util::GetStringVertexAttribIType(type) << ", " + << stride << ", " + << ptr << ")"); + // Record the info on the client side. + if (!vertex_array_object_manager_->SetAttribPointer(bound_array_buffer_id_, + index, + size, + type, + GL_FALSE, + stride, + ptr, + GL_TRUE)) { + SetGLError(GL_INVALID_OPERATION, "glVertexAttribIPointer", + "client side arrays are not allowed in vertex array objects."); + return; + } + if (!support_client_side_arrays_ || bound_array_buffer_id_ != 0) { + // Only report NON client side buffers to the service. + if (!ValidateOffset("glVertexAttribIPointer", + reinterpret_cast<GLintptr>(ptr))) { + return; + } + helper_->VertexAttribIPointer(index, size, type, stride, ToGLuint(ptr)); + } + CheckGLError(); +} + void GLES2Implementation::VertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) { @@ -1207,10 +1591,16 @@ void GLES2Implementation::VertexAttribPointer( << GLES2Util::GetStringVertexAttribType(type) << ", " << GLES2Util::GetStringBool(normalized) << ", " << stride << ", " - << static_cast<const void*>(ptr) << ")"); + << ptr << ")"); // Record the info on the client side. - if (!vertex_array_object_manager_->SetAttribPointer( - bound_array_buffer_id_, index, size, type, normalized, stride, ptr)) { + if (!vertex_array_object_manager_->SetAttribPointer(bound_array_buffer_id_, + index, + size, + type, + normalized, + stride, + ptr, + GL_FALSE)) { SetGLError(GL_INVALID_OPERATION, "glVertexAttribPointer", "client side arrays are not allowed in vertex array objects."); return; @@ -1239,83 +1629,19 @@ void GLES2Implementation::VertexAttribDivisorANGLE( CheckGLError(); } -void GLES2Implementation::ShaderSource( - GLuint shader, - GLsizei count, - const GLchar* const* source, - const GLint* length) { - GPU_CLIENT_SINGLE_THREAD_CHECK(); - GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource(" - << shader << ", " << count << ", " - << static_cast<const void*>(source) << ", " - << static_cast<const void*>(length) << ")"); - GPU_CLIENT_LOG_CODE_BLOCK({ - for (GLsizei ii = 0; ii < count; ++ii) { - if (source[ii]) { - if (length && length[ii] >= 0) { - std::string str(source[ii], length[ii]); - GPU_CLIENT_LOG(" " << ii << ": ---\n" << str << "\n---"); - } else { - GPU_CLIENT_LOG(" " << ii << ": ---\n" << source[ii] << "\n---"); - } - } else { - GPU_CLIENT_LOG(" " << ii << ": NULL"); - } - } - }); - if (count < 0) { - SetGLError(GL_INVALID_VALUE, "glShaderSource", "count < 0"); - return; - } - if (shader == 0) { - SetGLError(GL_INVALID_VALUE, "glShaderSource", "shader == 0"); - return; - } - - // Compute the total size. - uint32 total_size = 1; - for (GLsizei ii = 0; ii < count; ++ii) { - if (source[ii]) { - total_size += (length && length[ii] >= 0) ? - static_cast<size_t>(length[ii]) : strlen(source[ii]); - } - } - - // Concatenate all the strings in to a bucket on the service. - helper_->SetBucketSize(kResultBucketId, total_size); - uint32 offset = 0; - for (GLsizei ii = 0; ii <= count; ++ii) { - const char* src = ii < count ? source[ii] : ""; - if (src) { - uint32 size = ii < count ? - (length ? static_cast<size_t>(length[ii]) : strlen(src)) : 1; - while (size) { - ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); - if (!buffer.valid()) { - return; - } - memcpy(buffer.address(), src, buffer.size()); - helper_->SetBucketData(kResultBucketId, offset, buffer.size(), - buffer.shm_id(), buffer.offset()); - offset += buffer.size(); - src += buffer.size(); - size -= buffer.size(); - } - } - } - - DCHECK_EQ(total_size, offset); - - helper_->ShaderSourceBucket(shader, kResultBucketId); - helper_->SetBucketSize(kResultBucketId, 0); - CheckGLError(); -} - void GLES2Implementation::BufferDataHelper( GLenum target, GLsizeiptr size, const void* data, GLenum usage) { if (!ValidateSize("glBufferData", size)) return; +#if defined(MEMORY_SANITIZER) && !defined(OS_NACL) + // Do not upload uninitialized data. Even if it's not a bug, it can cause a + // bogus MSan report during a readback later. This is because MSan doesn't + // understand shared memory and would assume we were reading back the same + // unintialized data. + if (data) __msan_check_mem_is_initialized(data, size); +#endif + GLuint buffer_id; if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) { if (!buffer_id) { @@ -1334,12 +1660,10 @@ void GLES2Implementation::BufferDataHelper( return; } - if (size == 0) { - return; - } + RemoveMappedBufferRangeByTarget(target); // If there is no data just send BufferData - if (!data) { + if (size == 0 || !data) { helper_->BufferData(target, size, 0, 0, usage); return; } @@ -1610,6 +1934,97 @@ void GLES2Implementation::CompressedTexSubImage2D( CheckGLError(); } +void GLES2Implementation::CompressedTexImage3D( + GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, GLsizei image_size, + const void* data) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexImage3D(" + << GLES2Util::GetStringTexture3DTarget(target) << ", " << level << ", " + << GLES2Util::GetStringCompressedTextureFormat(internalformat) << ", " + << width << ", " << height << ", " << depth << ", " << border << ", " + << image_size << ", " << static_cast<const void*>(data) << ")"); + if (width < 0 || height < 0 || depth < 0 || level < 0) { + SetGLError(GL_INVALID_VALUE, "glCompressedTexImage3D", "dimension < 0"); + return; + } + if (border != 0) { + SetGLError(GL_INVALID_VALUE, "glCompressedTexImage3D", "border != 0"); + return; + } + if (height == 0 || width == 0 || depth == 0) { + return; + } + // If there's a pixel unpack buffer bound use it when issuing + // CompressedTexImage3D. + if (bound_pixel_unpack_transfer_buffer_id_) { + GLuint offset = ToGLuint(data); + BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( + bound_pixel_unpack_transfer_buffer_id_, + "glCompressedTexImage3D", offset, image_size); + if (buffer && buffer->shm_id() != -1) { + helper_->CompressedTexImage3D( + target, level, internalformat, width, height, depth, image_size, + buffer->shm_id(), buffer->shm_offset() + offset); + buffer->set_last_usage_token(helper_->InsertToken()); + } + return; + } + SetBucketContents(kResultBucketId, data, image_size); + helper_->CompressedTexImage3DBucket( + target, level, internalformat, width, height, depth, kResultBucketId); + // Free the bucket. This is not required but it does free up the memory. + // and we don't have to wait for the result so from the client's perspective + // it's cheap. + helper_->SetBucketSize(kResultBucketId, 0); + CheckGLError(); +} + +void GLES2Implementation::CompressedTexSubImage3D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, + GLsizei image_size, const void* data) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexSubImage3D(" + << GLES2Util::GetStringTextureTarget(target) << ", " + << level << ", " + << xoffset << ", " << yoffset << ", " << zoffset << ", " + << width << ", " << height << ", " << depth << ", " + << GLES2Util::GetStringCompressedTextureFormat(format) << ", " + << image_size << ", " + << static_cast<const void*>(data) << ")"); + if (width < 0 || height < 0 || depth < 0 || level < 0) { + SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage3D", "dimension < 0"); + return; + } + // If there's a pixel unpack buffer bound use it when issuing + // CompressedTexSubImage3D. + if (bound_pixel_unpack_transfer_buffer_id_) { + GLuint offset = ToGLuint(data); + BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( + bound_pixel_unpack_transfer_buffer_id_, + "glCompressedTexSubImage3D", offset, image_size); + if (buffer && buffer->shm_id() != -1) { + helper_->CompressedTexSubImage3D( + target, level, xoffset, yoffset, zoffset, + width, height, depth, format, image_size, + buffer->shm_id(), buffer->shm_offset() + offset); + buffer->set_last_usage_token(helper_->InsertToken()); + CheckGLError(); + } + return; + } + SetBucketContents(kResultBucketId, data, image_size); + helper_->CompressedTexSubImage3DBucket( + target, level, xoffset, yoffset, zoffset, width, height, depth, format, + kResultBucketId); + // Free the bucket. This is not required but it does free up the memory. + // and we don't have to wait for the result so from the client's perspective + // it's cheap. + helper_->SetBucketSize(kResultBucketId, 0); + CheckGLError(); +} + namespace { void CopyRectToBuffer( @@ -1670,7 +2085,7 @@ void GLES2Implementation::TexImage2D( uint32 unpadded_row_size; uint32 padded_row_size; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, unpack_alignment_, &size, + width, height, 1, format, type, unpack_alignment_, &size, &unpadded_row_size, &padded_row_size)) { SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); return; @@ -1751,6 +2166,126 @@ void GLES2Implementation::TexImage2D( CheckGLError(); } +void GLES2Implementation::TexImage3D( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, + const void* pixels) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage3D(" + << GLES2Util::GetStringTextureTarget(target) << ", " + << level << ", " + << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " + << width << ", " << height << ", " << depth << ", " << border << ", " + << GLES2Util::GetStringTextureFormat(format) << ", " + << GLES2Util::GetStringPixelType(type) << ", " + << static_cast<const void*>(pixels) << ")"); + if (level < 0 || height < 0 || width < 0 || depth < 0) { + SetGLError(GL_INVALID_VALUE, "glTexImage3D", "dimension < 0"); + return; + } + if (border != 0) { + SetGLError(GL_INVALID_VALUE, "glTexImage3D", "border != 0"); + return; + } + uint32 size; + uint32 unpadded_row_size; + uint32 padded_row_size; + if (!GLES2Util::ComputeImageDataSizes( + width, height, depth, format, type, unpack_alignment_, &size, + &unpadded_row_size, &padded_row_size)) { + SetGLError(GL_INVALID_VALUE, "glTexImage3D", "image size too large"); + return; + } + + // If there's a pixel unpack buffer bound use it when issuing TexImage3D. + if (bound_pixel_unpack_transfer_buffer_id_) { + GLuint offset = ToGLuint(pixels); + BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( + bound_pixel_unpack_transfer_buffer_id_, + "glTexImage3D", offset, size); + if (buffer && buffer->shm_id() != -1) { + helper_->TexImage3D( + target, level, internalformat, width, height, depth, format, type, + buffer->shm_id(), buffer->shm_offset() + offset); + buffer->set_last_usage_token(helper_->InsertToken()); + CheckGLError(); + } + return; + } + + // If there's no data just issue TexImage3D + if (!pixels) { + helper_->TexImage3D( + target, level, internalformat, width, height, depth, format, type, + 0, 0); + CheckGLError(); + return; + } + + // compute the advance bytes per row for the src pixels + uint32 src_padded_row_size; + if (unpack_row_length_ > 0) { + if (!GLES2Util::ComputeImagePaddedRowSize( + unpack_row_length_, format, type, unpack_alignment_, + &src_padded_row_size)) { + SetGLError( + GL_INVALID_VALUE, "glTexImage3D", "unpack row length too large"); + return; + } + } else { + src_padded_row_size = padded_row_size; + } + uint32 src_height = unpack_image_height_ > 0 ? unpack_image_height_ : height; + + // advance pixels pointer past the skip images/rows/pixels + pixels = reinterpret_cast<const int8*>(pixels) + + unpack_skip_images_ * src_padded_row_size * src_height + + unpack_skip_rows_ * src_padded_row_size; + if (unpack_skip_pixels_) { + uint32 group_size = GLES2Util::ComputeImageGroupSize(format, type); + pixels = reinterpret_cast<const int8*>(pixels) + + unpack_skip_pixels_ * group_size; + } + + // Check if we can send it all at once. + ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); + if (!buffer.valid()) { + return; + } + + if (buffer.size() >= size) { + void* buffer_pointer = buffer.address(); + for (GLsizei z = 0; z < depth; ++z) { + // Only the last row of the last image is unpadded. + uint32 src_unpadded_row_size = + (z == depth - 1) ? unpadded_row_size : src_padded_row_size; + // TODO(zmo): Ignore flip_y flag for now. + CopyRectToBuffer( + pixels, height, src_unpadded_row_size, src_padded_row_size, false, + buffer_pointer, padded_row_size); + pixels = reinterpret_cast<const int8*>(pixels) + + src_padded_row_size * src_height; + buffer_pointer = reinterpret_cast<int8*>(buffer_pointer) + + padded_row_size * height; + } + helper_->TexImage3D( + target, level, internalformat, width, height, depth, format, type, + buffer.shm_id(), buffer.offset()); + CheckGLError(); + return; + } + + // No, so send it using TexSubImage3D. + helper_->TexImage3D( + target, level, internalformat, width, height, depth, format, type, + 0, 0); + TexSubImage3DImpl( + target, level, 0, 0, 0, width, height, depth, format, type, + unpadded_row_size, pixels, src_padded_row_size, GL_TRUE, &buffer, + padded_row_size); + CheckGLError(); +} + void GLES2Implementation::TexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) { @@ -1776,7 +2311,7 @@ void GLES2Implementation::TexSubImage2D( uint32 unpadded_row_size; uint32 padded_row_size; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, unpack_alignment_, &temp_size, + width, height, 1, format, type, unpack_alignment_, &temp_size, &unpadded_row_size, &padded_row_size)) { SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); return; @@ -1829,15 +2364,100 @@ void GLES2Implementation::TexSubImage2D( CheckGLError(); } +void GLES2Implementation::TexSubImage3D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + const void* pixels) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexSubImage3D(" + << GLES2Util::GetStringTextureTarget(target) << ", " + << level << ", " + << xoffset << ", " << yoffset << ", " << zoffset << ", " + << width << ", " << height << ", " << depth << ", " + << GLES2Util::GetStringTextureFormat(format) << ", " + << GLES2Util::GetStringPixelType(type) << ", " + << static_cast<const void*>(pixels) << ")"); + + if (level < 0 || height < 0 || width < 0 || depth < 0) { + SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "dimension < 0"); + return; + } + if (height == 0 || width == 0 || depth == 0) { + return; + } + + uint32 temp_size; + uint32 unpadded_row_size; + uint32 padded_row_size; + if (!GLES2Util::ComputeImageDataSizes( + width, height, depth, format, type, unpack_alignment_, &temp_size, + &unpadded_row_size, &padded_row_size)) { + SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "size to large"); + return; + } + + // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. + if (bound_pixel_unpack_transfer_buffer_id_) { + GLuint offset = ToGLuint(pixels); + BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( + bound_pixel_unpack_transfer_buffer_id_, + "glTexSubImage3D", offset, temp_size); + if (buffer && buffer->shm_id() != -1) { + helper_->TexSubImage3D( + target, level, xoffset, yoffset, zoffset, width, height, depth, + format, type, buffer->shm_id(), buffer->shm_offset() + offset, false); + buffer->set_last_usage_token(helper_->InsertToken()); + CheckGLError(); + } + return; + } + + // compute the advance bytes per row for the src pixels + uint32 src_padded_row_size; + if (unpack_row_length_ > 0) { + if (!GLES2Util::ComputeImagePaddedRowSize( + unpack_row_length_, format, type, unpack_alignment_, + &src_padded_row_size)) { + SetGLError( + GL_INVALID_VALUE, "glTexImage3D", "unpack row length too large"); + return; + } + } else { + src_padded_row_size = padded_row_size; + } + uint32 src_height = unpack_image_height_ > 0 ? unpack_image_height_ : height; + + // advance pixels pointer past the skip images/rows/pixels + pixels = reinterpret_cast<const int8*>(pixels) + + unpack_skip_images_ * src_padded_row_size * src_height + + unpack_skip_rows_ * src_padded_row_size; + if (unpack_skip_pixels_) { + uint32 group_size = GLES2Util::ComputeImageGroupSize(format, type); + pixels = reinterpret_cast<const int8*>(pixels) + + unpack_skip_pixels_ * group_size; + } + + ScopedTransferBufferPtr buffer(temp_size, helper_, transfer_buffer_); + TexSubImage3DImpl( + target, level, xoffset, yoffset, zoffset, width, height, depth, + format, type, unpadded_row_size, pixels, src_padded_row_size, GL_FALSE, + &buffer, padded_row_size); + CheckGLError(); +} + static GLint ComputeNumRowsThatFitInBuffer( uint32 padded_row_size, uint32 unpadded_row_size, - unsigned int size) { + unsigned int size, GLsizei remaining_rows) { DCHECK_GE(unpadded_row_size, 0u); if (padded_row_size == 0) { return 1; } GLint num_rows = size / padded_row_size; - return num_rows + (size - num_rows * padded_row_size) / unpadded_row_size; + if (num_rows + 1 == remaining_rows && + size - num_rows * padded_row_size >= unpadded_row_size) { + num_rows++; + } + return num_rows; } void GLES2Implementation::TexSubImage2DImpl( @@ -1864,7 +2484,7 @@ void GLES2Implementation::TexSubImage2DImpl( } GLint num_rows = ComputeNumRowsThatFitInBuffer( - buffer_padded_row_size, unpadded_row_size, buffer->size()); + buffer_padded_row_size, unpadded_row_size, buffer->size(), height); num_rows = std::min(num_rows, height); CopyRectToBuffer( source, num_rows, unpadded_row_size, pixels_padded_row_size, @@ -1880,6 +2500,119 @@ void GLES2Implementation::TexSubImage2DImpl( } } +void GLES2Implementation::TexSubImage3DImpl( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + uint32 unpadded_row_size, const void* pixels, uint32 pixels_padded_row_size, + GLboolean internal, ScopedTransferBufferPtr* buffer, + uint32 buffer_padded_row_size) { + DCHECK(buffer); + DCHECK_GE(level, 0); + DCHECK_GT(height, 0); + DCHECK_GT(width, 0); + DCHECK_GT(depth, 0); + const int8* source = reinterpret_cast<const int8*>(pixels); + GLsizei total_rows = height * depth; + GLint row_index = 0, depth_index = 0; + while (total_rows) { + // Each time, we either copy one or more images, or copy one or more rows + // within a single image, depending on the buffer size limit. + GLsizei max_rows; + unsigned int desired_size; + if (row_index > 0) { + // We are in the middle of an image. Send the remaining of the image. + max_rows = height - row_index; + if (total_rows <= height) { + // Last image, so last row is unpadded. + desired_size = buffer_padded_row_size * (max_rows - 1) + + unpadded_row_size; + } else { + desired_size = buffer_padded_row_size * max_rows; + } + } else { + // Send all the remaining data if possible. + max_rows = total_rows; + desired_size = + buffer_padded_row_size * (max_rows - 1) + unpadded_row_size; + } + if (!buffer->valid() || buffer->size() == 0) { + buffer->Reset(desired_size); + if (!buffer->valid()) { + return; + } + } + GLint num_rows = ComputeNumRowsThatFitInBuffer( + buffer_padded_row_size, unpadded_row_size, buffer->size(), total_rows); + num_rows = std::min(num_rows, max_rows); + GLint num_images = num_rows / height; + GLsizei my_height, my_depth; + if (num_images > 0) { + num_rows = num_images * height; + my_height = height; + my_depth = num_images; + } else { + my_height = num_rows; + my_depth = 1; + } + + // TODO(zmo): Ignore flip_y flag for now. + if (num_images > 0) { + int8* buffer_pointer = reinterpret_cast<int8*>(buffer->address()); + uint32 src_height = + unpack_image_height_ > 0 ? unpack_image_height_ : height; + uint32 image_size_dst = buffer_padded_row_size * height; + uint32 image_size_src = pixels_padded_row_size * src_height; + for (GLint ii = 0; ii < num_images; ++ii) { + uint32 my_unpadded_row_size; + if (total_rows == num_rows && ii + 1 == num_images) + my_unpadded_row_size = unpadded_row_size; + else + my_unpadded_row_size = pixels_padded_row_size; + CopyRectToBuffer( + source + ii * image_size_src, my_height, my_unpadded_row_size, + pixels_padded_row_size, false, buffer_pointer + ii * image_size_dst, + buffer_padded_row_size); + } + } else { + uint32 my_unpadded_row_size; + if (total_rows == num_rows) + my_unpadded_row_size = unpadded_row_size; + else + my_unpadded_row_size = pixels_padded_row_size; + CopyRectToBuffer( + source, my_height, my_unpadded_row_size, pixels_padded_row_size, + false, buffer->address(), buffer_padded_row_size); + } + helper_->TexSubImage3D( + target, level, xoffset, yoffset + row_index, zoffset + depth_index, + width, my_height, my_depth, + format, type, buffer->shm_id(), buffer->offset(), internal); + buffer->Release(); + + total_rows -= num_rows; + if (total_rows > 0) { + GLint num_image_paddings; + if (num_images > 0) { + DCHECK_EQ(row_index, 0); + depth_index += num_images; + num_image_paddings = num_images; + } else { + row_index = (row_index + my_height) % height; + num_image_paddings = 0; + if (my_height > 0 && row_index == 0) { + depth_index++; + num_image_paddings++; + } + } + source += num_rows * pixels_padded_row_size; + if (unpack_image_height_ > height && num_image_paddings > 0) { + source += num_image_paddings * (unpack_image_height_ - height) * + pixels_padded_row_size; + } + } + } +} + bool GLES2Implementation::GetActiveAttribHelper( GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { @@ -2022,6 +2755,177 @@ void GLES2Implementation::GetActiveUniform( CheckGLError(); } +bool GLES2Implementation::GetActiveUniformBlockNameHelper( + GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, char* name) { + DCHECK_LE(0, bufsize); + // Clear the bucket so if the command fails nothing will be in it. + helper_->SetBucketSize(kResultBucketId, 0); + typedef cmds::GetActiveUniformBlockName::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return false; + } + // Set as failed so if the command fails we'll recover. + *result = 0; + helper_->GetActiveUniformBlockName(program, index, kResultBucketId, + GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + if (*result) { + if (bufsize == 0) { + if (length) { + *length = 0; + } + } else if (length || name) { + std::vector<int8> str; + GetBucketContents(kResultBucketId, &str); + DCHECK_GT(str.size(), 0u); + GLsizei max_size = + std::min(bufsize, static_cast<GLsizei>(str.size())) - 1; + if (length) { + *length = max_size; + } + if (name) { + memcpy(name, &str[0], max_size); + name[max_size] = '\0'; + } + } + } + return *result != 0; +} + +void GLES2Implementation::GetActiveUniformBlockName( + GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, char* name) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetActiveUniformBlockName(" + << program << ", " << index << ", " << bufsize << ", " + << static_cast<const void*>(length) << ", " + << static_cast<const void*>(name) << ")"); + if (bufsize < 0) { + SetGLError(GL_INVALID_VALUE, "glGetActiveUniformBlockName", "bufsize < 0"); + return; + } + TRACE_EVENT0("gpu", "GLES2::GetActiveUniformBlockName"); + bool success = + share_group_->program_info_manager()->GetActiveUniformBlockName( + this, program, index, bufsize, length, name); + if (success) { + if (name) { + GPU_CLIENT_LOG(" name: " << name); + } + } + CheckGLError(); +} + +bool GLES2Implementation::GetActiveUniformBlockivHelper( + GLuint program, GLuint index, GLenum pname, GLint* params) { + typedef cmds::GetActiveUniformBlockiv::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return false; + } + result->SetNumResults(0); + helper_->GetActiveUniformBlockiv( + program, index, pname, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + if (result->GetNumResults() > 0) { + if (params) { + result->CopyResult(params); + } + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32_t i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + return true; + } + return false; +} + +void GLES2Implementation::GetActiveUniformBlockiv( + GLuint program, GLuint index, GLenum pname, GLint* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetActiveUniformBlockiv(" + << program << ", " << index << ", " + << GLES2Util::GetStringUniformBlockParameter(pname) << ", " + << static_cast<const void*>(params) << ")"); + TRACE_EVENT0("gpu", "GLES2::GetActiveUniformBlockiv"); + bool success = + share_group_->program_info_manager()->GetActiveUniformBlockiv( + this, program, index, pname, params); + if (success) { + if (params) { + // TODO(zmo): For GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, there will + // be more than one value returned in params. + GPU_CLIENT_LOG(" params: " << params[0]); + } + } + CheckGLError(); +} + +bool GLES2Implementation::GetActiveUniformsivHelper( + GLuint program, GLsizei count, const GLuint* indices, + GLenum pname, GLint* params) { + typedef cmds::GetActiveUniformsiv::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return false; + } + result->SetNumResults(0); + base::CheckedNumeric<size_t> bytes = static_cast<size_t>(count); + bytes *= sizeof(GLuint); + if (!bytes.IsValid()) { + SetGLError(GL_INVALID_VALUE, "glGetActiveUniformsiv", "count overflow"); + return false; + } + SetBucketContents(kResultBucketId, indices, bytes.ValueOrDefault(0)); + helper_->GetActiveUniformsiv( + program, kResultBucketId, pname, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + bool success = result->GetNumResults() == count; + if (success) { + if (params) { + result->CopyResult(params); + } + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32_t i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + } + helper_->SetBucketSize(kResultBucketId, 0); + return success; +} + +void GLES2Implementation::GetActiveUniformsiv( + GLuint program, GLsizei count, const GLuint* indices, + GLenum pname, GLint* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetActiveUniformsiv(" + << program << ", " << count << ", " + << static_cast<const void*>(indices) << ", " + << GLES2Util::GetStringUniformParameter(pname) << ", " + << static_cast<const void*>(params) << ")"); + TRACE_EVENT0("gpu", "GLES2::GetActiveUniformsiv"); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glGetActiveUniformsiv", "count < 0"); + return; + } + bool success = share_group_->program_info_manager()->GetActiveUniformsiv( + this, program, count, indices, pname, params); + if (success) { + if (params) { + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei ii = 0; ii < count; ++ii) { + GPU_CLIENT_LOG(" " << ii << ": " << params[ii]); + } + }); + } + } + CheckGLError(); +} + void GLES2Implementation::GetAttachedShaders( GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { GPU_CLIENT_SINGLE_THREAD_CHECK(); @@ -2164,6 +3068,84 @@ const GLubyte* GLES2Implementation::GetString(GLenum name) { return result; } +bool GLES2Implementation::GetTransformFeedbackVaryingHelper( + GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, + GLenum* type, char* name) { + // Clear the bucket so if the command fails nothing will be in it. + helper_->SetBucketSize(kResultBucketId, 0); + typedef cmds::GetTransformFeedbackVarying::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return false; + } + // Set as failed so if the command fails we'll recover. + result->success = false; + helper_->GetTransformFeedbackVarying( + program, index, kResultBucketId, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + if (result->success) { + if (size) { + *size = result->size; + } + if (type) { + *type = result->type; + } + if (length || name) { + std::vector<int8> str; + GetBucketContents(kResultBucketId, &str); + GLsizei max_size = std::min(bufsize, static_cast<GLsizei>(str.size())); + if (max_size > 0) { + --max_size; + } + if (length) { + *length = max_size; + } + if (name) { + if (max_size > 0) { + memcpy(name, &str[0], max_size); + name[max_size] = '\0'; + } else if (bufsize > 0) { + name[0] = '\0'; + } + } + } + } + return result->success != 0; +} + +void GLES2Implementation::GetTransformFeedbackVarying( + GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, + GLenum* type, char* name) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetTransformFeedbackVarying(" + << program << ", " << index << ", " << bufsize << ", " + << static_cast<const void*>(length) << ", " + << static_cast<const void*>(size) << ", " + << static_cast<const void*>(type) << ", " + << static_cast<const void*>(name) << ", "); + if (bufsize < 0) { + SetGLError(GL_INVALID_VALUE, "glGetTransformFeedbackVarying", + "bufsize < 0"); + return; + } + TRACE_EVENT0("gpu", "GLES2::GetTransformFeedbackVarying"); + bool success = + share_group_->program_info_manager()->GetTransformFeedbackVarying( + this, program, index, bufsize, length, size, type, name); + if (success) { + if (size) { + GPU_CLIENT_LOG(" size: " << *size); + } + if (type) { + GPU_CLIENT_LOG(" type: " << GLES2Util::GetStringEnum(*type)); + } + if (name) { + GPU_CLIENT_LOG(" name: " << name); + } + } + CheckGLError(); +} + void GLES2Implementation::GetUniformfv( GLuint program, GLint location, GLfloat* params) { GPU_CLIENT_SINGLE_THREAD_CHECK(); @@ -2205,7 +3187,32 @@ void GLES2Implementation::GetUniformiv( helper_->GetUniformiv( program, location, GetResultShmId(), GetResultShmOffset()); WaitForCmd(); - GetResultAs<cmds::GetUniformfv::Result*>()->CopyResult(params); + GetResultAs<cmds::GetUniformiv::Result*>()->CopyResult(params); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32 i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + CheckGLError(); +} + +void GLES2Implementation::GetUniformuiv( + GLuint program, GLint location, GLuint* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetUniformuiv(" + << program << ", " << location << ", " + << static_cast<const void*>(params) << ")"); + TRACE_EVENT0("gpu", "GLES2::GetUniformuiv"); + typedef cmds::GetUniformuiv::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return; + } + result->SetNumResults(0); + helper_->GetUniformuiv( + program, location, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + GetResultAs<cmds::GetUniformuiv::Result*>()->CopyResult(params); GPU_CLIENT_LOG_CODE_BLOCK({ for (int32 i = 0; i < result->GetNumResults(); ++i) { GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); @@ -2246,8 +3253,8 @@ void GLES2Implementation::ReadPixels( uint32 unpadded_row_size; uint32 padded_row_size; if (!GLES2Util::ComputeImageDataSizes( - width, 2, format, type, pack_alignment_, &temp_size, &unpadded_row_size, - &padded_row_size)) { + width, 2, 1, format, type, pack_alignment_, &temp_size, + &unpadded_row_size, &padded_row_size)) { SetGLError(GL_INVALID_VALUE, "glReadPixels", "size too large."); return; } @@ -2274,13 +3281,13 @@ void GLES2Implementation::ReadPixels( // Transfer by rows. // The max rows we can transfer. while (height) { - GLsizei desired_size = padded_row_size * height - 1 + unpadded_row_size; + GLsizei desired_size = padded_row_size * (height - 1) + unpadded_row_size; ScopedTransferBufferPtr buffer(desired_size, helper_, transfer_buffer_); if (!buffer.valid()) { return; } GLint num_rows = ComputeNumRowsThatFitInBuffer( - padded_row_size, unpadded_row_size, buffer.size()); + padded_row_size, unpadded_row_size, buffer.size(), height); num_rows = std::min(num_rows, height); // NOTE: We must look up the address of the result area AFTER allocation // of the transfer buffer since the transfer buffer may be reallocated. @@ -2331,8 +3338,8 @@ void GLES2Implementation::ActiveTexture(GLenum texture) { GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glActiveTexture(" << GLES2Util::GetStringEnum(texture) << ")"); GLuint texture_index = texture - GL_TEXTURE0; - if (texture_index >= static_cast<GLuint>( - static_state_.int_state.max_combined_texture_image_units)) { + if (texture_index >= + static_cast<GLuint>(capabilities_.max_combined_texture_image_units)) { SetGLErrorInvalidEnum( "glActiveTexture", texture, "texture"); return; @@ -2373,6 +3380,14 @@ void GLES2Implementation::GenValuebuffersCHROMIUMHelper( const GLuint* /* valuebuffers */) { } +void GLES2Implementation::GenSamplersHelper( + GLsizei /* n */, const GLuint* /* samplers */) { +} + +void GLES2Implementation::GenTransformFeedbacksHelper( + GLsizei /* n */, const GLuint* /* transformfeedbacks */) { +} + // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id // generates a new resource. On newer versions of OpenGL they don't. The code // related to binding below will need to change if we switch to the new OpenGL @@ -2380,7 +3395,11 @@ void GLES2Implementation::GenValuebuffersCHROMIUMHelper( // the old model but possibly not true in the new model if another context has // deleted the resource. -bool GLES2Implementation::BindBufferHelper( +// NOTE #2: There is a bug in some BindXXXHelpers, that IDs might be marked as +// used even when Bind has failed. However, the bug is minor compared to the +// overhead & duplicated checking in client side. + +void GLES2Implementation::BindBufferHelper( GLenum target, GLuint buffer_id) { // TODO(gman): See note #1 above. bool changed = false; @@ -2404,13 +3423,53 @@ bool GLES2Implementation::BindBufferHelper( changed = true; break; } - // TODO(gman): There's a bug here. If the target is invalid the ID will not be - // used even though it's marked it as used here. - GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer_id); - return changed; + // TODO(gman): See note #2 above. + if (changed) { + GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( + this, target, buffer_id, &GLES2Implementation::BindBufferStub); + } +} + +void GLES2Implementation::BindBufferStub(GLenum target, GLuint buffer) { + helper_->BindBuffer(target, buffer); + if (share_group_->bind_generates_resource()) + helper_->CommandBufferHelper::Flush(); +} + +void GLES2Implementation::BindBufferBaseHelper( + GLenum target, GLuint index, GLuint buffer_id) { + // TODO(zmo): See note #1 above. + // TODO(zmo): See note #2 above. + GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( + this, target, index, buffer_id, &GLES2Implementation::BindBufferBaseStub); +} + +void GLES2Implementation::BindBufferBaseStub( + GLenum target, GLuint index, GLuint buffer) { + helper_->BindBufferBase(target, index, buffer); + if (share_group_->bind_generates_resource()) + helper_->CommandBufferHelper::Flush(); } -bool GLES2Implementation::BindFramebufferHelper( +void GLES2Implementation::BindBufferRangeHelper( + GLenum target, GLuint index, GLuint buffer_id, + GLintptr offset, GLsizeiptr size) { + // TODO(zmo): See note #1 above. + // TODO(zmo): See note #2 above. + GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( + this, target, index, buffer_id, offset, size, + &GLES2Implementation::BindBufferRangeStub); +} + +void GLES2Implementation::BindBufferRangeStub( + GLenum target, GLuint index, GLuint buffer, + GLintptr offset, GLsizeiptr size) { + helper_->BindBufferRange(target, index, buffer, offset, size); + if (share_group_->bind_generates_resource()) + helper_->CommandBufferHelper::Flush(); +} + +void GLES2Implementation::BindFramebufferHelper( GLenum target, GLuint framebuffer) { // TODO(gman): See note #1 above. bool changed = false; @@ -2426,7 +3485,7 @@ bool GLES2Implementation::BindFramebufferHelper( case GL_READ_FRAMEBUFFER: if (!IsChromiumFramebufferMultisampleAvailable()) { SetGLErrorInvalidEnum("glBindFramebuffer", target, "target"); - return false; + return; } if (bound_read_framebuffer_ != framebuffer) { bound_read_framebuffer_ = framebuffer; @@ -2436,7 +3495,7 @@ bool GLES2Implementation::BindFramebufferHelper( case GL_DRAW_FRAMEBUFFER: if (!IsChromiumFramebufferMultisampleAvailable()) { SetGLErrorInvalidEnum("glBindFramebuffer", target, "target"); - return false; + return; } if (bound_framebuffer_ != framebuffer) { bound_framebuffer_ = framebuffer; @@ -2445,13 +3504,23 @@ bool GLES2Implementation::BindFramebufferHelper( break; default: SetGLErrorInvalidEnum("glBindFramebuffer", target, "target"); - return false; + return; } - GetIdHandler(id_namespaces::kFramebuffers)->MarkAsUsedForBind(framebuffer); - return changed; + + if (changed) { + GetIdHandler(id_namespaces::kFramebuffers)->MarkAsUsedForBind( + this, target, framebuffer, &GLES2Implementation::BindFramebufferStub); + } +} + +void GLES2Implementation::BindFramebufferStub(GLenum target, + GLuint framebuffer) { + helper_->BindFramebuffer(target, framebuffer); + if (share_group_->bind_generates_resource()) + helper_->CommandBufferHelper::Flush(); } -bool GLES2Implementation::BindRenderbufferHelper( +void GLES2Implementation::BindRenderbufferHelper( GLenum target, GLuint renderbuffer) { // TODO(gman): See note #1 above. bool changed = false; @@ -2466,13 +3535,27 @@ bool GLES2Implementation::BindRenderbufferHelper( changed = true; break; } - // TODO(gman): There's a bug here. If the target is invalid the ID will not be - // used even though it's marked it as used here. - GetIdHandler(id_namespaces::kRenderbuffers)->MarkAsUsedForBind(renderbuffer); - return changed; + // TODO(zmo): See note #2 above. + if (changed) { + GetIdHandler(id_namespaces::kRenderbuffers)->MarkAsUsedForBind( + this, target, renderbuffer, + &GLES2Implementation::BindRenderbufferStub); + } +} + +void GLES2Implementation::BindRenderbufferStub(GLenum target, + GLuint renderbuffer) { + helper_->BindRenderbuffer(target, renderbuffer); + if (share_group_->bind_generates_resource()) + helper_->CommandBufferHelper::Flush(); +} + +void GLES2Implementation::BindSamplerHelper(GLuint unit, + GLuint sampler) { + helper_->BindSampler(unit, sampler); } -bool GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) { +void GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) { // TODO(gman): See note #1 above. // TODO(gman): Change this to false once we figure out why it's failing // on daisy. @@ -2501,28 +3584,42 @@ bool GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) { changed = true; break; } - // TODO(gman): There's a bug here. If the target is invalid the ID will not be - // used. even though it's marked it as used here. - GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind(texture); - return changed; + // TODO(gman): See note #2 above. + if (changed) { + GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind( + this, target, texture, &GLES2Implementation::BindTextureStub); + } } -bool GLES2Implementation::BindVertexArrayOESHelper(GLuint array) { - // TODO(gman): See note #1 above. +void GLES2Implementation::BindTextureStub(GLenum target, GLuint texture) { + helper_->BindTexture(target, texture); + if (share_group_->bind_generates_resource()) + helper_->CommandBufferHelper::Flush(); +} + +void GLES2Implementation::BindTransformFeedbackHelper( + GLenum target, GLuint transformfeedback) { + helper_->BindTransformFeedback(target, transformfeedback); +} + +void GLES2Implementation::BindVertexArrayOESHelper(GLuint array) { bool changed = false; - if (!vertex_array_object_manager_->BindVertexArray(array, &changed)) { + if (vertex_array_object_manager_->BindVertexArray(array, &changed)) { + if (changed) { + // Unlike other BindXXXHelpers we don't call MarkAsUsedForBind + // because unlike other resources VertexArrayObject ids must + // be generated by GenVertexArrays. A random id to Bind will not + // generate a new object. + helper_->BindVertexArrayOES(array); + } + } else { SetGLError( GL_INVALID_OPERATION, "glBindVertexArrayOES", "id was not generated with glGenVertexArrayOES"); } - // Unlike other BindXXXHelpers we don't call MarkAsUsedForBind - // because unlike other resources VertexArrayObject ids must - // be generated by GenVertexArrays. A random id to Bind will not - // generate a new object. - return changed; } -bool GLES2Implementation::BindValuebufferCHROMIUMHelper(GLenum target, +void GLES2Implementation::BindValuebufferCHROMIUMHelper(GLenum target, GLuint valuebuffer) { bool changed = false; switch (target) { @@ -2536,19 +3633,26 @@ bool GLES2Implementation::BindValuebufferCHROMIUMHelper(GLenum target, changed = true; break; } - // TODO(gman): There's a bug here. If the target is invalid the ID will not be - // used even though it's marked it as used here. - GetIdHandler(id_namespaces::kValuebuffers)->MarkAsUsedForBind(valuebuffer); - return changed; + // TODO(gman): See note #2 above. + if (changed) { + GetIdHandler(id_namespaces::kValuebuffers)->MarkAsUsedForBind( + this, target, valuebuffer, + &GLES2Implementation::BindValuebufferCHROMIUMStub); + } } -bool GLES2Implementation::UseProgramHelper(GLuint program) { - bool changed = false; +void GLES2Implementation::BindValuebufferCHROMIUMStub(GLenum target, + GLuint valuebuffer) { + helper_->BindValuebufferCHROMIUM(target, valuebuffer); + if (share_group_->bind_generates_resource()) + helper_->CommandBufferHelper::Flush(); +} + +void GLES2Implementation::UseProgramHelper(GLuint program) { if (current_program_ != program) { current_program_ = program; - changed = true; + helper_->UseProgram(program); } - return changed; } bool GLES2Implementation::IsBufferReservedId(GLuint id) { @@ -2577,6 +3681,8 @@ void GLES2Implementation::DeleteBuffersHelper( if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { bound_pixel_unpack_transfer_buffer_id_ = 0; } + + RemoveMappedBufferRangeById(buffers[ii]); } } @@ -2641,8 +3747,7 @@ void GLES2Implementation::DeleteTexturesHelper( return; } for (GLsizei ii = 0; ii < n; ++ii) { - for (GLint tt = 0; - tt < static_state_.int_state.max_combined_texture_image_units; + for (GLint tt = 0; tt < capabilities_.max_combined_texture_image_units; ++tt) { TextureUnit& unit = texture_units_[tt]; if (textures[ii] == unit.bound_texture_2d) { @@ -2697,6 +3802,39 @@ void GLES2Implementation::DeleteValuebuffersCHROMIUMHelper( } } +void GLES2Implementation::DeleteSamplersStub( + GLsizei n, const GLuint* samplers) { + helper_->DeleteSamplersImmediate(n, samplers); +} + +void GLES2Implementation::DeleteSamplersHelper( + GLsizei n, const GLuint* samplers) { + if (!GetIdHandler(id_namespaces::kSamplers)->FreeIds( + this, n, samplers, &GLES2Implementation::DeleteSamplersStub)) { + SetGLError( + GL_INVALID_VALUE, + "glDeleteSamplers", "id not created by this context."); + return; + } +} + +void GLES2Implementation::DeleteTransformFeedbacksStub( + GLsizei n, const GLuint* transformfeedbacks) { + helper_->DeleteTransformFeedbacksImmediate(n, transformfeedbacks); +} + +void GLES2Implementation::DeleteTransformFeedbacksHelper( + GLsizei n, const GLuint* transformfeedbacks) { + if (!GetIdHandler(id_namespaces::kTransformFeedbacks)->FreeIds( + this, n, transformfeedbacks, + &GLES2Implementation::DeleteTransformFeedbacksStub)) { + SetGLError( + GL_INVALID_VALUE, + "glDeleteTransformFeedbacks", "id not created by this context."); + return; + } +} + void GLES2Implementation::DeleteValuebuffersCHROMIUMStub( GLsizei n, const GLuint* valuebuffers) { @@ -2749,7 +3887,7 @@ void GLES2Implementation::GetVertexAttribfv( << static_cast<const void*>(params) << ")"); uint32 value = 0; if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) { - *params = static_cast<float>(value); + *params = static_cast<GLfloat>(value); return; } TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv"); @@ -2780,7 +3918,7 @@ void GLES2Implementation::GetVertexAttribiv( << static_cast<const void*>(params) << ")"); uint32 value = 0; if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) { - *params = value; + *params = static_cast<GLint>(value); return; } TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv"); @@ -2802,6 +3940,68 @@ void GLES2Implementation::GetVertexAttribiv( CheckGLError(); } +void GLES2Implementation::GetVertexAttribIiv( + GLuint index, GLenum pname, GLint* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribIiv(" + << index << ", " + << GLES2Util::GetStringVertexAttribute(pname) << ", " + << static_cast<const void*>(params) << ")"); + uint32 value = 0; + if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) { + *params = static_cast<GLint>(value); + return; + } + TRACE_EVENT0("gpu", "GLES2::GetVertexAttribIiv"); + typedef cmds::GetVertexAttribiv::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return; + } + result->SetNumResults(0); + helper_->GetVertexAttribIiv( + index, pname, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + result->CopyResult(params); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32 i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + CheckGLError(); +} + +void GLES2Implementation::GetVertexAttribIuiv( + GLuint index, GLenum pname, GLuint* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribIuiv(" + << index << ", " + << GLES2Util::GetStringVertexAttribute(pname) << ", " + << static_cast<const void*>(params) << ")"); + uint32 value = 0; + if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) { + *params = static_cast<GLuint>(value); + return; + } + TRACE_EVENT0("gpu", "GLES2::GetVertexAttribIuiv"); + typedef cmds::GetVertexAttribiv::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return; + } + result->SetNumResults(0); + helper_->GetVertexAttribIuiv( + index, pname, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + result->CopyResult(params); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32 i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + CheckGLError(); +} + void GLES2Implementation::Swap() { SwapBuffers(); } @@ -2926,6 +4126,133 @@ void GLES2Implementation::UnmapBufferSubDataCHROMIUM(const void* mem) { CheckGLError(); } +GLuint GLES2Implementation::GetBoundBufferHelper(GLenum target) { + GLenum binding = GLES2Util::MapBufferTargetToBindingEnum(target); + GLint id = 0; + bool cached = GetHelper(binding, &id); + DCHECK(cached); + return static_cast<GLuint>(id); +} + +void GLES2Implementation::RemoveMappedBufferRangeByTarget(GLenum target) { + GLuint buffer = GetBoundBufferHelper(target); + RemoveMappedBufferRangeById(buffer); +} + +void GLES2Implementation::RemoveMappedBufferRangeById(GLuint buffer) { + if (buffer > 0) { + auto iter = mapped_buffer_range_map_.find(buffer); + if (iter != mapped_buffer_range_map_.end() && iter->second.shm_memory) { + mapped_memory_->FreePendingToken( + iter->second.shm_memory, helper_->InsertToken()); + mapped_buffer_range_map_.erase(iter); + } + } +} + +void GLES2Implementation::ClearMappedBufferRangeMap() { + for (auto& buffer_range : mapped_buffer_range_map_) { + if (buffer_range.second.shm_memory) { + mapped_memory_->FreePendingToken( + buffer_range.second.shm_memory, helper_->InsertToken()); + } + } + mapped_buffer_range_map_.clear(); +} + +void* GLES2Implementation::MapBufferRange( + GLenum target, GLintptr offset, GLsizeiptr size, GLbitfield access) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferRange(" + << GLES2Util::GetStringEnum(target) << ", " << offset << ", " + << size << ", " << access << ")"); + if (!ValidateSize("glMapBufferRange", size) || + !ValidateOffset("glMapBufferRange", offset)) { + return nullptr; + } + + int32 shm_id; + unsigned int shm_offset; + void* mem = mapped_memory_->Alloc(size, &shm_id, &shm_offset); + if (!mem) { + SetGLError(GL_OUT_OF_MEMORY, "glMapBufferRange", "out of memory"); + return nullptr; + } + + typedef cmds::MapBufferRange::Result Result; + Result* result = GetResultAs<Result*>(); + *result = 0; + helper_->MapBufferRange(target, offset, size, access, shm_id, shm_offset, + GetResultShmId(), GetResultShmOffset()); + // TODO(zmo): For write only mode with MAP_INVALID_*_BIT, we should + // consider an early return without WaitForCmd(). crbug.com/465804. + WaitForCmd(); + if (*result) { + const GLbitfield kInvalidateBits = + GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT; + if ((access & kInvalidateBits) != 0) { + // We do not read back from the buffer, therefore, we set the client + // side memory to zero to avoid uninitialized data. + memset(mem, 0, size); + } + GLuint buffer = GetBoundBufferHelper(target); + DCHECK_NE(0u, buffer); + // glMapBufferRange fails on an already mapped buffer. + DCHECK(mapped_buffer_range_map_.find(buffer) == + mapped_buffer_range_map_.end()); + auto iter = mapped_buffer_range_map_.insert(std::make_pair( + buffer, + MappedBuffer(access, shm_id, mem, shm_offset, target, offset, size))); + DCHECK(iter.second); + } else { + mapped_memory_->Free(mem); + mem = nullptr; + } + + GPU_CLIENT_LOG(" returned " << mem); + CheckGLError(); + return mem; +} + +GLboolean GLES2Implementation::UnmapBuffer(GLenum target) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUnmapBuffer(" + << GLES2Util::GetStringEnum(target) << ")"); + switch (target) { + case GL_ARRAY_BUFFER: + case GL_ELEMENT_ARRAY_BUFFER: + case GL_COPY_READ_BUFFER: + case GL_COPY_WRITE_BUFFER: + case GL_PIXEL_PACK_BUFFER: + case GL_PIXEL_UNPACK_BUFFER: + case GL_TRANSFORM_FEEDBACK_BUFFER: + case GL_UNIFORM_BUFFER: + break; + default: + SetGLError(GL_INVALID_ENUM, "glUnmapBuffer", "invalid target"); + return GL_FALSE; + } + GLuint buffer = GetBoundBufferHelper(target); + if (buffer == 0) { + SetGLError(GL_INVALID_OPERATION, "glUnmapBuffer", "no buffer bound"); + return GL_FALSE; + } + auto iter = mapped_buffer_range_map_.find(buffer); + if (iter == mapped_buffer_range_map_.end()) { + SetGLError(GL_INVALID_OPERATION, "glUnmapBuffer", "buffer is unmapped"); + return GL_FALSE; + } + + helper_->UnmapBuffer(target); + RemoveMappedBufferRangeById(buffer); + // TODO(zmo): There is a rare situation that data might be corrupted and + // GL_FALSE should be returned. We lose context on that sitatuon, so we + // don't have to WaitForCmd(). + GPU_CLIENT_LOG(" returned " << GL_TRUE); + CheckGLError(); + return GL_TRUE; +} + void* GLES2Implementation::MapTexSubImage2DCHROMIUM( GLenum target, GLint level, @@ -2958,7 +4285,7 @@ void* GLES2Implementation::MapTexSubImage2DCHROMIUM( } uint32 size; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, unpack_alignment_, &size, NULL, NULL)) { + width, height, 1, format, type, unpack_alignment_, &size, NULL, NULL)) { SetGLError( GL_INVALID_VALUE, "glMapTexSubImage2DCHROMIUM", "image size too large"); return NULL; @@ -3086,160 +4413,156 @@ void GLES2Implementation::RateLimitOffscreenContextCHROMIUM() { rate_limit_tokens_.push(helper_->InsertToken()); } -void GLES2Implementation::GetMultipleIntegervCHROMIUM( - const GLenum* pnames, GLuint count, GLint* results, GLsizeiptr size) { - GPU_CLIENT_SINGLE_THREAD_CHECK(); - GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetMultipleIntegervCHROMIUM(" - << static_cast<const void*>(pnames) << ", " - << count << ", " << results << ", " - << size << ")"); - GPU_CLIENT_LOG_CODE_BLOCK({ - for (GLuint i = 0; i < count; ++i) { - GPU_CLIENT_LOG( - " " << i << ": " << GLES2Util::GetStringGLState(pnames[i])); - } - }); - DCHECK(size >= 0 && FitInt32NonNegative<GLsizeiptr>(size)); +void GLES2Implementation::GetProgramInfoCHROMIUMHelper( + GLuint program, std::vector<int8>* result) { + DCHECK(result); + // Clear the bucket so if the command fails nothing will be in it. + helper_->SetBucketSize(kResultBucketId, 0); + helper_->GetProgramInfoCHROMIUM(program, kResultBucketId); + GetBucketContents(kResultBucketId, result); +} - GetMultipleIntegervState state(pnames, count, results, size); - if (!GetMultipleIntegervSetup(&state)) { +void GLES2Implementation::GetProgramInfoCHROMIUM( + GLuint program, GLsizei bufsize, GLsizei* size, void* info) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + if (bufsize < 0) { + SetGLError( + GL_INVALID_VALUE, "glProgramInfoCHROMIUM", "bufsize less than 0."); return; } - state.buffer = transfer_buffer_->Alloc(state.transfer_buffer_size_needed); - if (!state.buffer) { - SetGLError(GL_OUT_OF_MEMORY, "glGetMultipleIntegervCHROMIUM", - "Transfer buffer allocation failed."); + if (size == NULL) { + SetGLError(GL_INVALID_VALUE, "glProgramInfoCHROMIUM", "size is null."); return; } - GetMultipleIntegervRequest(&state); - WaitForCmd(); - GetMultipleIntegervOnCompleted(&state); - - GPU_CLIENT_LOG(" returned"); - GPU_CLIENT_LOG_CODE_BLOCK({ - for (int i = 0; i < state.num_results; ++i) { - GPU_CLIENT_LOG(" " << i << ": " << (results[i])); - } - }); - - // TODO(gman): We should be able to free without a token. - transfer_buffer_->FreePendingToken(state.buffer, helper_->InsertToken()); - CheckGLError(); -} - -bool GLES2Implementation::GetMultipleIntegervSetup( - GetMultipleIntegervState* state) { - state->num_results = 0; - for (GLuint ii = 0; ii < state->pnames_count; ++ii) { - int num = util_.GLGetNumValuesReturned(state->pnames[ii]); - if (!num) { - SetGLErrorInvalidEnum( - "glGetMultipleIntegervCHROMIUM", state->pnames[ii], "pname"); - return false; - } - state->num_results += num; + // Make sure they've set size to 0 else the value will be undefined on + // lost context. + DCHECK_EQ(0, *size); + std::vector<int8> result; + GetProgramInfoCHROMIUMHelper(program, &result); + if (result.empty()) { + return; } - if (static_cast<size_t>(state->results_size) != - state->num_results * sizeof(GLint)) { - SetGLError(GL_INVALID_VALUE, "glGetMultipleIntegervCHROMIUM", "bad size"); - return false; + *size = result.size(); + if (!info) { + return; } - for (int ii = 0; ii < state->num_results; ++ii) { - if (state->results[ii] != 0) { - SetGLError(GL_INVALID_VALUE, - "glGetMultipleIntegervCHROMIUM", "results not set to zero."); - return false; - } + if (static_cast<size_t>(bufsize) < result.size()) { + SetGLError(GL_INVALID_OPERATION, + "glProgramInfoCHROMIUM", "bufsize is too small for result."); + return; } - state->transfer_buffer_size_needed = - state->pnames_count * sizeof(state->pnames[0]) + - state->num_results * sizeof(state->results[0]); - return true; + memcpy(info, &result[0], result.size()); } -void GLES2Implementation::GetMultipleIntegervRequest( - GetMultipleIntegervState* state) { - GLenum* pnames_buffer = static_cast<GLenum*>(state->buffer); - state->results_buffer = pnames_buffer + state->pnames_count; - memcpy(pnames_buffer, state->pnames, state->pnames_count * sizeof(GLenum)); - memset(state->results_buffer, 0, state->num_results * sizeof(GLint)); - helper_->GetMultipleIntegervCHROMIUM( - transfer_buffer_->GetShmId(), - transfer_buffer_->GetOffset(pnames_buffer), - state->pnames_count, - transfer_buffer_->GetShmId(), - transfer_buffer_->GetOffset(state->results_buffer), - state->results_size); +void GLES2Implementation::GetUniformBlocksCHROMIUMHelper( + GLuint program, std::vector<int8>* result) { + DCHECK(result); + // Clear the bucket so if the command fails nothing will be in it. + helper_->SetBucketSize(kResultBucketId, 0); + helper_->GetUniformBlocksCHROMIUM(program, kResultBucketId); + GetBucketContents(kResultBucketId, result); } -void GLES2Implementation::GetMultipleIntegervOnCompleted( - GetMultipleIntegervState* state) { - memcpy(state->results, state->results_buffer, state->results_size);; +void GLES2Implementation::GetUniformBlocksCHROMIUM( + GLuint program, GLsizei bufsize, GLsizei* size, void* info) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + if (bufsize < 0) { + SetGLError( + GL_INVALID_VALUE, "glGetUniformBlocksCHROMIUM", "bufsize less than 0."); + return; + } + if (size == NULL) { + SetGLError(GL_INVALID_VALUE, "glGetUniformBlocksCHROMIUM", "size is null."); + return; + } + // Make sure they've set size to 0 else the value will be undefined on + // lost context. + DCHECK_EQ(0, *size); + std::vector<int8> result; + GetUniformBlocksCHROMIUMHelper(program, &result); + if (result.empty()) { + return; + } + *size = result.size(); + if (!info) { + return; + } + if (static_cast<size_t>(bufsize) < result.size()) { + SetGLError(GL_INVALID_OPERATION, "glGetUniformBlocksCHROMIUM", + "bufsize is too small for result."); + return; + } + memcpy(info, &result[0], result.size()); } -void GLES2Implementation::GetAllShaderPrecisionFormatsSetup( - GetAllShaderPrecisionFormatsState* state) { - state->transfer_buffer_size_needed = - state->precision_params_count * - sizeof(cmds::GetShaderPrecisionFormat::Result); +void GLES2Implementation::GetUniformsES3CHROMIUMHelper( + GLuint program, std::vector<int8>* result) { + DCHECK(result); + // Clear the bucket so if the command fails nothing will be in it. + helper_->SetBucketSize(kResultBucketId, 0); + helper_->GetUniformsES3CHROMIUM(program, kResultBucketId); + GetBucketContents(kResultBucketId, result); } -void GLES2Implementation::GetAllShaderPrecisionFormatsRequest( - GetAllShaderPrecisionFormatsState* state) { - typedef cmds::GetShaderPrecisionFormat::Result Result; - Result* result = static_cast<Result*>(state->results_buffer); - - for (int i = 0; i < state->precision_params_count; i++) { - result->success = false; - helper_->GetShaderPrecisionFormat(state->precision_params[i][0], - state->precision_params[i][1], - transfer_buffer_->GetShmId(), - transfer_buffer_->GetOffset(result)); - result++; +void GLES2Implementation::GetUniformsES3CHROMIUM( + GLuint program, GLsizei bufsize, GLsizei* size, void* info) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + if (bufsize < 0) { + SetGLError( + GL_INVALID_VALUE, "glGetUniformsES3CHROMIUM", "bufsize less than 0."); + return; } -} - -void GLES2Implementation::GetAllShaderPrecisionFormatsOnCompleted( - GetAllShaderPrecisionFormatsState* state) { - typedef cmds::GetShaderPrecisionFormat::Result Result; - Result* result = static_cast<Result*>(state->results_buffer); - - for (int i = 0; i < state->precision_params_count; i++) { - if (result->success) { - const GLStaticState::ShaderPrecisionKey key( - state->precision_params[i][0], state->precision_params[i][1]); - static_state_.shader_precisions[key] = *result; - } - result++; + if (size == NULL) { + SetGLError(GL_INVALID_VALUE, "glGetUniformsES3CHROMIUM", "size is null."); + return; + } + // Make sure they've set size to 0 else the value will be undefined on + // lost context. + DCHECK_EQ(0, *size); + std::vector<int8> result; + GetUniformsES3CHROMIUMHelper(program, &result); + if (result.empty()) { + return; + } + *size = result.size(); + if (!info) { + return; + } + if (static_cast<size_t>(bufsize) < result.size()) { + SetGLError(GL_INVALID_OPERATION, + "glGetUniformsES3CHROMIUM", "bufsize is too small for result."); + return; } + memcpy(info, &result[0], result.size()); } -void GLES2Implementation::GetProgramInfoCHROMIUMHelper( +void GLES2Implementation::GetTransformFeedbackVaryingsCHROMIUMHelper( GLuint program, std::vector<int8>* result) { DCHECK(result); // Clear the bucket so if the command fails nothing will be in it. helper_->SetBucketSize(kResultBucketId, 0); - helper_->GetProgramInfoCHROMIUM(program, kResultBucketId); + helper_->GetTransformFeedbackVaryingsCHROMIUM(program, kResultBucketId); GetBucketContents(kResultBucketId, result); } -void GLES2Implementation::GetProgramInfoCHROMIUM( +void GLES2Implementation::GetTransformFeedbackVaryingsCHROMIUM( GLuint program, GLsizei bufsize, GLsizei* size, void* info) { GPU_CLIENT_SINGLE_THREAD_CHECK(); if (bufsize < 0) { - SetGLError( - GL_INVALID_VALUE, "glProgramInfoCHROMIUM", "bufsize less than 0."); + SetGLError(GL_INVALID_VALUE, "glGetTransformFeedbackVaryingsCHROMIUM", + "bufsize less than 0."); return; } if (size == NULL) { - SetGLError(GL_INVALID_VALUE, "glProgramInfoCHROMIUM", "size is null."); + SetGLError(GL_INVALID_VALUE, "glGetTransformFeedbackVaryingsCHROMIUM", + "size is null."); return; } // Make sure they've set size to 0 else the value will be undefined on // lost context. DCHECK_EQ(0, *size); std::vector<int8> result; - GetProgramInfoCHROMIUMHelper(program, &result); + GetTransformFeedbackVaryingsCHROMIUMHelper(program, &result); if (result.empty()) { return; } @@ -3248,8 +4571,8 @@ void GLES2Implementation::GetProgramInfoCHROMIUM( return; } if (static_cast<size_t>(bufsize) < result.size()) { - SetGLError(GL_INVALID_OPERATION, - "glProgramInfoCHROMIUM", "bufsize is too small for result."); + SetGLError(GL_INVALID_OPERATION, "glGetTransformFeedbackVaryingsCHROMIUM", + "bufsize is too small for result."); return; } memcpy(info, &result[0], result.size()); @@ -3625,33 +4948,29 @@ void GLES2Implementation::PopGroupMarkerEXT() { debug_marker_manager_.PopGroup(); } -void GLES2Implementation::TraceBeginCHROMIUM(const char* name) { +void GLES2Implementation::TraceBeginCHROMIUM( + const char* category_name, const char* trace_name) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTraceBeginCHROMIUM(" - << name << ")"); - if (current_trace_name_.get()) { - SetGLError(GL_INVALID_OPERATION, "glTraceBeginCHROMIUM", - "trace already running"); - return; - } - TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", name, this); - SetBucketAsCString(kResultBucketId, name); - helper_->TraceBeginCHROMIUM(kResultBucketId); + << category_name << ", " << trace_name << ")"); + SetBucketAsCString(kResultBucketId, category_name); + SetBucketAsCString(kResultBucketId + 1, trace_name); + helper_->TraceBeginCHROMIUM(kResultBucketId, kResultBucketId + 1); helper_->SetBucketSize(kResultBucketId, 0); - current_trace_name_.reset(new std::string(name)); + helper_->SetBucketSize(kResultBucketId + 1, 0); + current_trace_stack_++; } void GLES2Implementation::TraceEndCHROMIUM() { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTraceEndCHROMIUM(" << ")"); - if (!current_trace_name_.get()) { + if (current_trace_stack_ == 0) { SetGLError(GL_INVALID_OPERATION, "glTraceEndCHROMIUM", "missing begin trace"); return; } helper_->TraceEndCHROMIUM(); - TRACE_EVENT_COPY_ASYNC_END0("gpu", current_trace_name_->c_str(), this); - current_trace_name_.reset(); + current_trace_stack_--; } void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) { @@ -3821,7 +5140,7 @@ void GLES2Implementation::AsyncTexImage2DCHROMIUM( uint32 unpadded_row_size; uint32 padded_row_size; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, unpack_alignment_, &size, + width, height, 1, format, type, unpack_alignment_, &size, &unpadded_row_size, &padded_row_size)) { SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); return; @@ -3881,7 +5200,7 @@ void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( uint32 unpadded_row_size; uint32 padded_row_size; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, unpack_alignment_, &size, + width, height, 1, format, type, unpack_alignment_, &size, &unpadded_row_size, &padded_row_size)) { SetGLError( GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); @@ -3955,8 +5274,10 @@ namespace { bool ValidImageFormat(GLenum internalformat) { switch (internalformat) { + case GL_R8: case GL_RGB: case GL_RGBA: + case GL_BGRA_EXT: return true; default: return false; @@ -4101,7 +5422,7 @@ bool GLES2Implementation::ValidateSize(const char* func, GLsizeiptr size) { SetGLError(GL_INVALID_VALUE, func, "size < 0"); return false; } - if (!FitInt32NonNegative<GLsizeiptr>(size)) { + if (!base::IsValueInRangeForNumericType<int32_t>(size)) { SetGLError(GL_INVALID_OPERATION, func, "size more than 32-bit"); return false; } @@ -4113,13 +5434,146 @@ bool GLES2Implementation::ValidateOffset(const char* func, GLintptr offset) { SetGLError(GL_INVALID_VALUE, func, "offset < 0"); return false; } - if (!FitInt32NonNegative<GLintptr>(offset)) { + if (!base::IsValueInRangeForNumericType<int32_t>(offset)) { SetGLError(GL_INVALID_OPERATION, func, "offset more than 32-bit"); return false; } return true; } +bool GLES2Implementation::GetSamplerParameterfvHelper( + GLuint /* sampler */, GLenum /* pname */, GLfloat* /* params */) { + // TODO(zmo): Implement client side caching. + return false; +} + +bool GLES2Implementation::GetSamplerParameterivHelper( + GLuint /* sampler */, GLenum /* pname */, GLint* /* params */) { + // TODO(zmo): Implement client side caching. + return false; +} + +bool GLES2Implementation::PackStringsToBucket(GLsizei count, + const char* const* str, + const GLint* length, + const char* func_name) { + DCHECK_LE(0, count); + // Compute the total size. + base::CheckedNumeric<size_t> total_size = count; + total_size += 1; + total_size *= sizeof(GLint); + if (!total_size.IsValid()) { + SetGLError(GL_INVALID_VALUE, func_name, "overflow"); + return false; + } + size_t header_size = total_size.ValueOrDefault(0); + std::vector<GLint> header(count + 1); + header[0] = static_cast<GLint>(count); + for (GLsizei ii = 0; ii < count; ++ii) { + GLint len = 0; + if (str[ii]) { + len = (length && length[ii] >= 0) + ? length[ii] + : base::checked_cast<GLint>(strlen(str[ii])); + } + total_size += len; + total_size += 1; // NULL at the end of each char array. + if (!total_size.IsValid()) { + SetGLError(GL_INVALID_VALUE, func_name, "overflow"); + return false; + } + header[ii + 1] = len; + } + // Pack data into a bucket on the service. + helper_->SetBucketSize(kResultBucketId, total_size.ValueOrDefault(0)); + size_t offset = 0; + for (GLsizei ii = 0; ii <= count; ++ii) { + const char* src = + (ii == 0) ? reinterpret_cast<const char*>(&header[0]) : str[ii - 1]; + base::CheckedNumeric<size_t> checked_size = + (ii == 0) ? header_size : static_cast<size_t>(header[ii]); + if (ii > 0) { + checked_size += 1; // NULL in the end. + } + if (!checked_size.IsValid()) { + SetGLError(GL_INVALID_VALUE, func_name, "overflow"); + return false; + } + size_t size = checked_size.ValueOrDefault(0); + while (size) { + ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); + if (!buffer.valid() || buffer.size() == 0) { + SetGLError(GL_OUT_OF_MEMORY, func_name, "too large"); + return false; + } + size_t copy_size = buffer.size(); + if (ii > 0 && buffer.size() == size) + --copy_size; + if (copy_size) + memcpy(buffer.address(), src, copy_size); + if (copy_size < buffer.size()) { + // Append NULL in the end. + DCHECK(copy_size + 1 == buffer.size()); + char* str = reinterpret_cast<char*>(buffer.address()); + str[copy_size] = 0; + } + helper_->SetBucketData(kResultBucketId, offset, buffer.size(), + buffer.shm_id(), buffer.offset()); + offset += buffer.size(); + src += buffer.size(); + size -= buffer.size(); + } + } + DCHECK_EQ(total_size.ValueOrDefault(0), offset); + return true; +} + +void GLES2Implementation::UniformBlockBinding(GLuint program, + GLuint index, + GLuint binding) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformBlockBinding(" << program + << ", " << index << ", " << binding << ")"); + share_group_->program_info_manager()->UniformBlockBinding( + this, program, index, binding); + helper_->UniformBlockBinding(program, index, binding); + CheckGLError(); +} + +GLenum GLES2Implementation::ClientWaitSync( + GLsync sync, GLbitfield flags, GLuint64 timeout) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClientWaitSync(" << sync + << ", " << flags << ", " << timeout << ")"); + typedef cmds::ClientWaitSync::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + SetGLError(GL_OUT_OF_MEMORY, "ClientWaitSync", ""); + return GL_WAIT_FAILED; + } + *result = GL_WAIT_FAILED; + uint32_t v32_0 = 0, v32_1 = 0; + GLES2Util::MapUint64ToTwoUint32(timeout, &v32_0, &v32_1); + helper_->ClientWaitSync( + ToGLuint(sync), flags, v32_0, v32_1, + GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + GPU_CLIENT_LOG("returned " << *result); + CheckGLError(); + return *result; +} + +void GLES2Implementation::WaitSync( + GLsync sync, GLbitfield flags, GLuint64 timeout) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitSync(" << sync << ", " + << flags << ", " << timeout << ")"); + uint32_t v32_0 = 0, v32_1 = 0; + GLES2Util::MapUint64ToTwoUint32(timeout, &v32_0, &v32_1); + helper_->WaitSync(ToGLuint(sync), flags, v32_0, v32_1); + CheckGLError(); +} + // Include the auto-generated part of this file. We split this because it means // we can easily edit the non-auto generated parts right here in this file // instead of having to edit some template or the code generator. diff --git a/chromium/gpu/command_buffer/client/gles2_implementation.h b/chromium/gpu/command_buffer/client/gles2_implementation.h index c2e9edb3e74..9c1a2fa9c95 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation.h @@ -137,24 +137,6 @@ class GLES2_IMPL_EXPORT GLES2Implementation GLStaticState(); ~GLStaticState(); - struct GLES2_IMPL_EXPORT IntState { - IntState(); - GLint max_combined_texture_image_units; - GLint max_cube_map_texture_size; - GLint max_fragment_uniform_vectors; - GLint max_renderbuffer_size; - GLint max_texture_image_units; - GLint max_texture_size; - GLint max_varying_vectors; - GLint max_vertex_attribs; - GLint max_vertex_texture_image_units; - GLint max_vertex_uniform_vectors; - GLint num_compressed_texture_formats; - GLint num_shader_binary_formats; - GLint bind_generates_resource_chromium; - }; - IntState int_state; - typedef std::pair<GLenum, GLenum> ShaderPrecisionKey; typedef std::map<ShaderPrecisionKey, cmds::GetShaderPrecisionFormat::Result> @@ -216,6 +198,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation void EnableVertexAttribArray(GLuint index) override; void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) override; void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) override; + void GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) override; + void GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) override; // ContextSupport implementation. void Swap() override; @@ -231,12 +215,36 @@ class GLES2_IMPL_EXPORT GLES2Implementation void GetProgramInfoCHROMIUMHelper(GLuint program, std::vector<int8>* result); GLint GetAttribLocationHelper(GLuint program, const char* name); GLint GetUniformLocationHelper(GLuint program, const char* name); + GLint GetFragDataLocationHelper(GLuint program, const char* name); bool GetActiveAttribHelper( GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); bool GetActiveUniformHelper( GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); + void GetUniformBlocksCHROMIUMHelper( + GLuint program, std::vector<int8>* result); + void GetUniformsES3CHROMIUMHelper( + GLuint program, std::vector<int8>* result); + GLuint GetUniformBlockIndexHelper(GLuint program, const char* name); + bool GetActiveUniformBlockNameHelper( + GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, char* name); + bool GetActiveUniformBlockivHelper( + GLuint program, GLuint index, GLenum pname, GLint* params); + void GetTransformFeedbackVaryingsCHROMIUMHelper( + GLuint program, std::vector<int8>* result); + bool GetTransformFeedbackVaryingHelper( + GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, + GLint* size, GLenum* type, char* name); + bool GetUniformIndicesHelper( + GLuint program, GLsizei count, const char* const* names, GLuint* indices); + bool GetActiveUniformsivHelper( + GLuint program, GLsizei count, const GLuint* indices, + GLenum pname, GLint* params); + bool GetSyncivHelper( + GLsync sync, GLenum pname, GLsizei bufsize, GLsizei* length, + GLint* values); void FreeUnusedSharedMemory(); void FreeEverything(); @@ -398,58 +406,6 @@ class GLES2_IMPL_EXPORT GLES2Implementation int32 GetResultShmId(); uint32 GetResultShmOffset(); - bool QueryAndCacheStaticState(); - - // Helpers used to batch synchronous GetIntergerv calls with other - // synchronous calls. - struct GetMultipleIntegervState { - GetMultipleIntegervState(const GLenum* pnames, GLuint pnames_count, - GLint* results, GLsizeiptr results_size) - : pnames(pnames), - pnames_count(pnames_count), - results(results), - results_size(results_size) - { } - // inputs - const GLenum* pnames; - GLuint pnames_count; - // outputs - GLint* results; - GLsizeiptr results_size; - // transfer buffer - int num_results; - int transfer_buffer_size_needed; - void* buffer; - void* results_buffer; - }; - bool GetMultipleIntegervSetup( - GetMultipleIntegervState* state); - void GetMultipleIntegervRequest( - GetMultipleIntegervState* state); - void GetMultipleIntegervOnCompleted( - GetMultipleIntegervState* state); - - // Helpers used to batch synchronous GetShaderPrecision calls with other - // synchronous calls. - struct GetAllShaderPrecisionFormatsState { - GetAllShaderPrecisionFormatsState( - const GLenum (*precision_params)[2], - int precision_params_count) - : precision_params(precision_params), - precision_params_count(precision_params_count) - { } - const GLenum (*precision_params)[2]; - int precision_params_count; - int transfer_buffer_size_needed; - void* results_buffer; - }; - void GetAllShaderPrecisionFormatsSetup( - GetAllShaderPrecisionFormatsState* state); - void GetAllShaderPrecisionFormatsRequest( - GetAllShaderPrecisionFormatsState* state); - void GetAllShaderPrecisionFormatsOnCompleted( - GetAllShaderPrecisionFormatsState* state); - // Lazily determines if GL_ANGLE_pack_reverse_row_order is available bool IsAnglePackReverseRowOrderAvailable(); bool IsChromiumFramebufferMultisampleAvailable(); @@ -501,14 +457,30 @@ class GLES2_IMPL_EXPORT GLES2Implementation bool IsVertexArrayReservedId(GLuint id) { return false; } bool IsProgramReservedId(GLuint id) { return false; } bool IsValuebufferReservedId(GLuint id) { return false; } - - bool BindBufferHelper(GLenum target, GLuint texture); - bool BindFramebufferHelper(GLenum target, GLuint texture); - bool BindRenderbufferHelper(GLenum target, GLuint texture); - bool BindTextureHelper(GLenum target, GLuint texture); - bool BindVertexArrayOESHelper(GLuint array); - bool BindValuebufferCHROMIUMHelper(GLenum target, GLuint valuebuffer); - bool UseProgramHelper(GLuint program); + bool IsSamplerReservedId(GLuint id) { return false; } + bool IsTransformFeedbackReservedId(GLuint id) { return false; } + + void BindBufferHelper(GLenum target, GLuint buffer); + void BindBufferBaseHelper(GLenum target, GLuint index, GLuint buffer); + void BindBufferRangeHelper(GLenum target, GLuint index, GLuint buffer, + GLintptr offset, GLsizeiptr size); + void BindFramebufferHelper(GLenum target, GLuint framebuffer); + void BindRenderbufferHelper(GLenum target, GLuint renderbuffer); + void BindSamplerHelper(GLuint unit, GLuint sampler); + void BindTextureHelper(GLenum target, GLuint texture); + void BindTransformFeedbackHelper(GLenum target, GLuint transformfeedback); + void BindVertexArrayOESHelper(GLuint array); + void BindValuebufferCHROMIUMHelper(GLenum target, GLuint valuebuffer); + void UseProgramHelper(GLuint program); + + void BindBufferStub(GLenum target, GLuint buffer); + void BindBufferBaseStub(GLenum target, GLuint index, GLuint buffer); + void BindBufferRangeStub(GLenum target, GLuint index, GLuint buffer, + GLintptr offset, GLsizeiptr size); + void BindFramebufferStub(GLenum target, GLuint framebuffer); + void BindRenderbufferStub(GLenum target, GLuint renderbuffer); + void BindTextureStub(GLenum target, GLuint texture); + void BindValuebufferCHROMIUMStub(GLenum target, GLuint valuebuffer); void GenBuffersHelper(GLsizei n, const GLuint* buffers); void GenFramebuffersHelper(GLsizei n, const GLuint* framebuffers); @@ -517,6 +489,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation void GenVertexArraysOESHelper(GLsizei n, const GLuint* arrays); void GenQueriesEXTHelper(GLsizei n, const GLuint* queries); void GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* valuebuffers); + void GenSamplersHelper(GLsizei n, const GLuint* samplers); + void GenTransformFeedbacksHelper(GLsizei n, const GLuint* transformfeedbacks); void DeleteBuffersHelper(GLsizei n, const GLuint* buffers); void DeleteFramebuffersHelper(GLsizei n, const GLuint* framebuffers); @@ -527,6 +501,10 @@ class GLES2_IMPL_EXPORT GLES2Implementation void DeleteQueriesEXTHelper(GLsizei n, const GLuint* queries); void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* arrays); void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* valuebuffers); + void DeleteSamplersHelper(GLsizei n, const GLuint* samplers); + void DeleteTransformFeedbacksHelper( + GLsizei n, const GLuint* transformfeedbacks); + void DeleteSyncHelper(GLsync sync); void DeleteBuffersStub(GLsizei n, const GLuint* buffers); void DeleteFramebuffersStub(GLsizei n, const GLuint* framebuffers); @@ -536,6 +514,10 @@ class GLES2_IMPL_EXPORT GLES2Implementation void DeleteShaderStub(GLsizei n, const GLuint* shaders); void DeleteVertexArraysOESStub(GLsizei n, const GLuint* arrays); void DeleteValuebuffersCHROMIUMStub(GLsizei n, const GLuint* valuebuffers); + void DeleteSamplersStub(GLsizei n, const GLuint* samplers); + void DeleteTransformFeedbacksStub( + GLsizei n, const GLuint* transformfeedbacks); + void DeleteSyncStub(GLsizei n, const GLuint* syncs); void BufferDataHelper( GLenum target, GLsizeiptr size, const void* data, GLenum usage); @@ -564,23 +546,40 @@ class GLES2_IMPL_EXPORT GLES2Implementation void RestoreElementAndArrayBuffers(bool restore); void RestoreArrayBuffer(bool restrore); - // The pixels pointer should already account for unpack skip rows and skip - // pixels. + // The pixels pointer should already account for unpack skip + // images/rows/pixels. void TexSubImage2DImpl( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, uint32 unpadded_row_size, const void* pixels, uint32 pixels_padded_row_size, GLboolean internal, ScopedTransferBufferPtr* buffer, uint32 buffer_padded_row_size); + void TexSubImage3DImpl( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + uint32 unpadded_row_size, const void* pixels, + uint32 pixels_padded_row_size, GLboolean internal, + ScopedTransferBufferPtr* buffer, uint32 buffer_padded_row_size); // Helpers for query functions. bool GetHelper(GLenum pname, GLint* params); + GLuint GetBoundBufferHelper(GLenum target); bool GetBooleanvHelper(GLenum pname, GLboolean* params); bool GetBufferParameterivHelper(GLenum target, GLenum pname, GLint* params); bool GetFloatvHelper(GLenum pname, GLfloat* params); bool GetFramebufferAttachmentParameterivHelper( GLenum target, GLenum attachment, GLenum pname, GLint* params); + bool GetInteger64vHelper(GLenum pname, GLint64* params); bool GetIntegervHelper(GLenum pname, GLint* params); + bool GetIntegeri_vHelper(GLenum pname, GLuint index, GLint* data); + bool GetInteger64i_vHelper(GLenum pname, GLuint index, GLint64* data); + bool GetInternalformativHelper( + GLenum target, GLenum format, GLenum pname, GLsizei bufSize, + GLint* params); bool GetProgramivHelper(GLuint program, GLenum pname, GLint* params); + bool GetSamplerParameterfvHelper( + GLuint sampler, GLenum pname, GLfloat* params); + bool GetSamplerParameterivHelper( + GLuint sampler, GLenum pname, GLint* params); bool GetRenderbufferParameterivHelper( GLenum target, GLenum pname, GLint* params); bool GetShaderivHelper(GLuint shader, GLenum pname, GLint* params); @@ -649,6 +648,13 @@ class GLES2_IMPL_EXPORT GLES2Implementation GLuint buffer_id, const char* function_name, GLuint offset, GLsizei size); + // Pack 2D arrays of char into a bucket. + // Helper function for ShaderSource(), TransformFeedbackVaryings(), etc. + bool PackStringsToBucket(GLsizei count, + const char* const* str, + const GLint* length, + const char* func_name); + const std::string& GetLogPrefix() const; #if defined(GL_CLIENT_FAIL_GL_ERRORS) @@ -659,6 +665,13 @@ class GLES2_IMPL_EXPORT GLES2Implementation void FailGLError(GLenum /* error */) { } #endif + void RemoveMappedBufferRangeByTarget(GLenum target); + void RemoveMappedBufferRangeById(GLuint buffer); + void ClearMappedBufferRangeMap(); + + void DrawElementsImpl(GLenum mode, GLsizei count, GLenum type, + const void* indices, const char* func_name); + GLES2Util util_; GLES2CmdHelper* helper_; TransferBufferInterface* transfer_buffer_; @@ -687,12 +700,18 @@ class GLES2_IMPL_EXPORT GLES2Implementation // unpack row length as last set by glPixelStorei GLint unpack_row_length_; + // unpack image height as last set by glPixelStorei + GLint unpack_image_height_; + // unpack skip rows as last set by glPixelStorei GLint unpack_skip_rows_; // unpack skip pixels as last set by glPixelStorei GLint unpack_skip_pixels_; + // unpack skip images as last set by glPixelStorei + GLint unpack_skip_images_; + // pack reverse row order as last set by glPixelstorei bool pack_reverse_row_order_; @@ -741,10 +760,10 @@ class GLES2_IMPL_EXPORT GLES2Implementation bool debug_; // When true, the context is lost when a GL_OUT_OF_MEMORY error occurs. - bool lose_context_when_out_of_memory_; + const bool lose_context_when_out_of_memory_; // Whether or not to support client side arrays. - bool support_client_side_arrays_; + const bool support_client_side_arrays_; // Used to check for single threaded access. int use_count_; @@ -761,6 +780,10 @@ class GLES2_IMPL_EXPORT GLES2Implementation typedef std::map<const void*, MappedBuffer> MappedBufferMap; MappedBufferMap mapped_buffers_; + // TODO(zmo): Consolidate |mapped_buffers_| and |mapped_buffer_range_map_|. + typedef base::hash_map<GLuint, MappedBuffer> MappedBufferRangeMap; + MappedBufferRangeMap mapped_buffer_range_map_; + typedef std::map<const void*, MappedTexture> MappedTextureMap; MappedTextureMap mapped_textures_; @@ -778,7 +801,7 @@ class GLES2_IMPL_EXPORT GLES2Implementation GLES2ImplementationErrorMessageCallback* error_message_callback_; - scoped_ptr<std::string> current_trace_name_; + int current_trace_stack_; GpuControl* gpu_control_; diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h b/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h index 3a11f10564e..af6ce6f80b0 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -23,12 +23,24 @@ void BindAttribLocation(GLuint program, void BindBuffer(GLenum target, GLuint buffer) override; +void BindBufferBase(GLenum target, GLuint index, GLuint buffer) override; + +void BindBufferRange(GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) override; + void BindFramebuffer(GLenum target, GLuint framebuffer) override; void BindRenderbuffer(GLenum target, GLuint renderbuffer) override; +void BindSampler(GLuint unit, GLuint sampler) override; + void BindTexture(GLenum target, GLuint texture) override; +void BindTransformFeedback(GLenum target, GLuint transformfeedback) override; + void BlendColor(GLclampf red, GLclampf green, GLclampf blue, @@ -59,6 +71,23 @@ GLenum CheckFramebufferStatus(GLenum target) override; void Clear(GLbitfield mask) override; +void ClearBufferfi(GLenum buffer, + GLint drawbuffers, + GLfloat depth, + GLint stencil) override; + +void ClearBufferfv(GLenum buffer, + GLint drawbuffers, + const GLfloat* value) override; + +void ClearBufferiv(GLenum buffer, + GLint drawbuffers, + const GLint* value) override; + +void ClearBufferuiv(GLenum buffer, + GLint drawbuffers, + const GLuint* value) override; + void ClearColor(GLclampf red, GLclampf green, GLclampf blue, @@ -68,6 +97,8 @@ void ClearDepthf(GLclampf depth) override; void ClearStencil(GLint s) override; +GLenum ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override; + void ColorMask(GLboolean red, GLboolean green, GLboolean blue, @@ -94,6 +125,34 @@ void CompressedTexSubImage2D(GLenum target, GLsizei imageSize, const void* data) override; +void CompressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void* data) override; + +void CompressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void* data) override; + +void CopyBufferSubData(GLenum readtarget, + GLenum writetarget, + GLintptr readoffset, + GLintptr writeoffset, + GLsizeiptr size) override; + void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, @@ -112,6 +171,16 @@ void CopyTexSubImage2D(GLenum target, GLsizei width, GLsizei height) override; +void CopyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) override; + GLuint CreateProgram() override; GLuint CreateShader(GLenum type) override; @@ -126,10 +195,16 @@ void DeleteProgram(GLuint program) override; void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override; +void DeleteSamplers(GLsizei n, const GLuint* samplers) override; + +void DeleteSync(GLsync sync) override; + void DeleteShader(GLuint shader) override; void DeleteTextures(GLsizei n, const GLuint* textures) override; +void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) override; + void DepthFunc(GLenum func) override; void DepthMask(GLboolean flag) override; @@ -147,8 +222,17 @@ void DrawElements(GLenum mode, GLenum type, const void* indices) override; +void DrawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void* indices) override; + void Enable(GLenum cap) override; +GLsync FenceSync(GLenum condition, GLbitfield flags) override; + void Finish() override; void Flush() override; @@ -164,6 +248,12 @@ void FramebufferTexture2D(GLenum target, GLuint texture, GLint level) override; +void FramebufferTextureLayer(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) override; + void FrontFace(GLenum mode) override; void GenBuffers(GLsizei n, GLuint* buffers) override; @@ -174,8 +264,12 @@ void GenFramebuffers(GLsizei n, GLuint* framebuffers) override; void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override; +void GenSamplers(GLsizei n, GLuint* samplers) override; + void GenTextures(GLsizei n, GLuint* textures) override; +void GenTransformFeedbacks(GLsizei n, GLuint* ids) override; + void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, @@ -192,6 +286,23 @@ void GetActiveUniform(GLuint program, GLenum* type, char* name) override; +void GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) override; + +void GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) override; + +void GetActiveUniformsiv(GLuint program, + GLsizei count, + const GLuint* indices, + GLenum pname, + GLint* params) override; + void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -207,13 +318,27 @@ GLenum GetError() override; void GetFloatv(GLenum pname, GLfloat* params) override; +GLint GetFragDataLocation(GLuint program, const char* name) override; + void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) override; +void GetInteger64v(GLenum pname, GLint64* params) override; + +void GetIntegeri_v(GLenum pname, GLuint index, GLint* data) override; + +void GetInteger64i_v(GLenum pname, GLuint index, GLint64* data) override; + void GetIntegerv(GLenum pname, GLint* params) override; +void GetInternalformativ(GLenum target, + GLenum format, + GLenum pname, + GLsizei bufSize, + GLint* params) override; + void GetProgramiv(GLuint program, GLenum pname, GLint* params) override; void GetProgramInfoLog(GLuint program, @@ -225,6 +350,14 @@ void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) override; +void GetSamplerParameterfv(GLuint sampler, + GLenum pname, + GLfloat* params) override; + +void GetSamplerParameteriv(GLuint sampler, + GLenum pname, + GLint* params) override; + void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override; void GetShaderInfoLog(GLuint shader, @@ -244,14 +377,37 @@ void GetShaderSource(GLuint shader, const GLubyte* GetString(GLenum name) override; +void GetSynciv(GLsync sync, + GLenum pname, + GLsizei bufsize, + GLsizei* length, + GLint* values) override; + void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) override; void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) override; +void GetTransformFeedbackVarying(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + GLsizei* size, + GLenum* type, + char* name) override; + +GLuint GetUniformBlockIndex(GLuint program, const char* name) override; + void GetUniformfv(GLuint program, GLint location, GLfloat* params) override; void GetUniformiv(GLuint program, GLint location, GLint* params) override; +void GetUniformuiv(GLuint program, GLint location, GLuint* params) override; + +void GetUniformIndices(GLuint program, + GLsizei count, + const char* const* names, + GLuint* indices) override; + GLint GetUniformLocation(GLuint program, const char* name) override; void GetVertexAttribPointerv(GLuint index, @@ -260,6 +416,18 @@ void GetVertexAttribPointerv(GLuint index, void Hint(GLenum target, GLenum mode) override; +void InvalidateFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments) override; + +void InvalidateSubFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) override; + GLboolean IsBuffer(GLuint buffer) override; GLboolean IsEnabled(GLenum cap) override; @@ -270,18 +438,28 @@ GLboolean IsProgram(GLuint program) override; GLboolean IsRenderbuffer(GLuint renderbuffer) override; +GLboolean IsSampler(GLuint sampler) override; + GLboolean IsShader(GLuint shader) override; +GLboolean IsSync(GLsync sync) override; + GLboolean IsTexture(GLuint texture) override; +GLboolean IsTransformFeedback(GLuint transformfeedback) override; + void LineWidth(GLfloat width) override; void LinkProgram(GLuint program) override; +void PauseTransformFeedback() override; + void PixelStorei(GLenum pname, GLint param) override; void PolygonOffset(GLfloat factor, GLfloat units) override; +void ReadBuffer(GLenum src) override; + void ReadPixels(GLint x, GLint y, GLsizei width, @@ -297,8 +475,22 @@ void RenderbufferStorage(GLenum target, GLsizei width, GLsizei height) override; +void ResumeTransformFeedback() override; + void SampleCoverage(GLclampf value, GLboolean invert) override; +void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) override; + +void SamplerParameterfv(GLuint sampler, + GLenum pname, + const GLfloat* params) override; + +void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) override; + +void SamplerParameteriv(GLuint sampler, + GLenum pname, + const GLint* params) override; + void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override; void ShaderBinary(GLsizei n, @@ -316,6 +508,8 @@ void ShallowFinishCHROMIUM() override; void ShallowFlushCHROMIUM() override; +void OrderingBarrierCHROMIUM() override; + void StencilFunc(GLenum func, GLint ref, GLuint mask) override; void StencilFuncSeparate(GLenum face, @@ -344,6 +538,17 @@ void TexImage2D(GLenum target, GLenum type, const void* pixels) override; +void TexImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void* pixels) override; + void TexParameterf(GLenum target, GLenum pname, GLfloat param) override; void TexParameterfv(GLenum target, @@ -354,6 +559,13 @@ void TexParameteri(GLenum target, GLenum pname, GLint param) override; void TexParameteriv(GLenum target, GLenum pname, const GLint* params) override; +void TexStorage3D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth) override; + void TexSubImage2D(GLenum target, GLint level, GLint xoffset, @@ -364,6 +576,23 @@ void TexSubImage2D(GLenum target, GLenum type, const void* pixels) override; +void TexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void* pixels) override; + +void TransformFeedbackVaryings(GLuint program, + GLsizei count, + const char* const* varyings, + GLenum buffermode) override; + void Uniform1f(GLint location, GLfloat x) override; void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) override; @@ -372,6 +601,10 @@ void Uniform1i(GLint location, GLint x) override; void Uniform1iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform1ui(GLint location, GLuint x) override; + +void Uniform1uiv(GLint location, GLsizei count, const GLuint* v) override; + void Uniform2f(GLint location, GLfloat x, GLfloat y) override; void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) override; @@ -380,6 +613,10 @@ void Uniform2i(GLint location, GLint x, GLint y) override; void Uniform2iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform2ui(GLint location, GLuint x, GLuint y) override; + +void Uniform2uiv(GLint location, GLsizei count, const GLuint* v) override; + void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) override; void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) override; @@ -388,6 +625,10 @@ void Uniform3i(GLint location, GLint x, GLint y, GLint z) override; void Uniform3iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform3ui(GLint location, GLuint x, GLuint y, GLuint z) override; + +void Uniform3uiv(GLint location, GLsizei count, const GLuint* v) override; + void Uniform4f(GLint location, GLfloat x, GLfloat y, @@ -400,21 +641,61 @@ void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) override; void Uniform4iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform4ui(GLint location, + GLuint x, + GLuint y, + GLuint z, + GLuint w) override; + +void Uniform4uiv(GLint location, GLsizei count, const GLuint* v) override; + +void UniformBlockBinding(GLuint program, GLuint index, GLuint binding) override; + void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override; +void UniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; + +void UniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; + void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override; +void UniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; + +void UniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; + void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override; +void UniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; + +void UniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; + void UseProgram(GLuint program) override; void ValidateProgram(GLuint program) override; @@ -439,6 +720,24 @@ void VertexAttrib4f(GLuint indx, void VertexAttrib4fv(GLuint indx, const GLfloat* values) override; +void VertexAttribI4i(GLuint indx, GLint x, GLint y, GLint z, GLint w) override; + +void VertexAttribI4iv(GLuint indx, const GLint* values) override; + +void VertexAttribI4ui(GLuint indx, + GLuint x, + GLuint y, + GLuint z, + GLuint w) override; + +void VertexAttribI4uiv(GLuint indx, const GLuint* values) override; + +void VertexAttribIPointer(GLuint indx, + GLint size, + GLenum type, + GLsizei stride, + const void* ptr) override; + void VertexAttribPointer(GLuint indx, GLint size, GLenum type, @@ -448,6 +747,8 @@ void VertexAttribPointer(GLuint indx, void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override; +void WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override; + void BlitFramebufferCHROMIUM(GLint srcX0, GLint srcY0, GLint srcX1, @@ -492,8 +793,12 @@ GLboolean IsQueryEXT(GLuint id) override; void BeginQueryEXT(GLenum target, GLuint id) override; +void BeginTransformFeedback(GLenum primitivemode) override; + void EndQueryEXT(GLenum target) override; +void EndTransformFeedback() override; + void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override; void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) override; @@ -532,6 +837,13 @@ void* MapBufferSubDataCHROMIUM(GLuint target, void UnmapBufferSubDataCHROMIUM(const void* mem) override; +void* MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) override; + +GLboolean UnmapBuffer(GLenum target) override; + void* MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, @@ -552,16 +864,26 @@ void RequestExtensionCHROMIUM(const char* extension) override; void RateLimitOffscreenContextCHROMIUM() override; -void GetMultipleIntegervCHROMIUM(const GLenum* pnames, - GLuint count, - GLint* results, - GLsizeiptr size) override; - void GetProgramInfoCHROMIUM(GLuint program, GLsizei bufsize, GLsizei* size, void* info) override; +void GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; + +void GetTransformFeedbackVaryingsCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; + +void GetUniformsES3CHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; + GLuint CreateStreamTextureCHROMIUM(GLuint texture) override; GLuint CreateImageCHROMIUM(ClientBuffer buffer, @@ -595,10 +917,15 @@ void TexImageIOSurface2DCHROMIUM(GLenum target, void CopyTextureCHROMIUM(GLenum target, GLenum source_id, GLenum dest_id, - GLint level, GLint internalformat, GLenum dest_type) override; +void CopySubTextureCHROMIUM(GLenum target, + GLenum source_id, + GLenum dest_id, + GLint xoffset, + GLint yoffset) override; + void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, @@ -649,7 +976,8 @@ void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override; void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override; -void TraceBeginCHROMIUM(const char* name) override; +void TraceBeginCHROMIUM(const char* category_name, + const char* trace_name) override; void TraceEndCHROMIUM() override; @@ -703,6 +1031,8 @@ void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order, GLfloat uv_width, GLfloat uv_height) override; +void SwapInterval(GLint interval) override; + void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override; void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override; diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 8541e777423..55cafb99d78 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h @@ -30,9 +30,48 @@ void GLES2Implementation::BindBuffer(GLenum target, GLuint buffer) { SetGLError(GL_INVALID_OPERATION, "BindBuffer", "buffer reserved id"); return; } - if (BindBufferHelper(target, buffer)) { - helper_->BindBuffer(target, buffer); + BindBufferHelper(target, buffer); + CheckGLError(); +} + +void GLES2Implementation::BindBufferBase(GLenum target, + GLuint index, + GLuint buffer) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindBufferBase(" + << GLES2Util::GetStringIndexedBufferTarget(target) << ", " + << index << ", " << buffer << ")"); + if (IsBufferReservedId(buffer)) { + SetGLError(GL_INVALID_OPERATION, "BindBufferBase", "buffer reserved id"); + return; } + BindBufferBaseHelper(target, index, buffer); + CheckGLError(); +} + +void GLES2Implementation::BindBufferRange(GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindBufferRange(" + << GLES2Util::GetStringIndexedBufferTarget(target) << ", " + << index << ", " << buffer << ", " << offset << ", " + << size << ")"); + if (offset < 0) { + SetGLError(GL_INVALID_VALUE, "glBindBufferRange", "offset < 0"); + return; + } + if (size < 0) { + SetGLError(GL_INVALID_VALUE, "glBindBufferRange", "size < 0"); + return; + } + if (IsBufferReservedId(buffer)) { + SetGLError(GL_INVALID_OPERATION, "BindBufferRange", "buffer reserved id"); + return; + } + BindBufferRangeHelper(target, index, buffer, offset, size); CheckGLError(); } @@ -46,9 +85,7 @@ void GLES2Implementation::BindFramebuffer(GLenum target, GLuint framebuffer) { "framebuffer reserved id"); return; } - if (BindFramebufferHelper(target, framebuffer)) { - helper_->BindFramebuffer(target, framebuffer); - } + BindFramebufferHelper(target, framebuffer); CheckGLError(); } @@ -62,9 +99,19 @@ void GLES2Implementation::BindRenderbuffer(GLenum target, GLuint renderbuffer) { "renderbuffer reserved id"); return; } - if (BindRenderbufferHelper(target, renderbuffer)) { - helper_->BindRenderbuffer(target, renderbuffer); + BindRenderbufferHelper(target, renderbuffer); + CheckGLError(); +} + +void GLES2Implementation::BindSampler(GLuint unit, GLuint sampler) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindSampler(" << unit << ", " + << sampler << ")"); + if (IsSamplerReservedId(sampler)) { + SetGLError(GL_INVALID_OPERATION, "BindSampler", "sampler reserved id"); + return; } + BindSamplerHelper(unit, sampler); CheckGLError(); } @@ -77,9 +124,22 @@ void GLES2Implementation::BindTexture(GLenum target, GLuint texture) { SetGLError(GL_INVALID_OPERATION, "BindTexture", "texture reserved id"); return; } - if (BindTextureHelper(target, texture)) { - helper_->BindTexture(target, texture); + BindTextureHelper(target, texture); + CheckGLError(); +} + +void GLES2Implementation::BindTransformFeedback(GLenum target, + GLuint transformfeedback) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindTransformFeedback(" + << GLES2Util::GetStringTransformFeedbackBindTarget(target) + << ", " << transformfeedback << ")"); + if (IsTransformFeedbackReservedId(transformfeedback)) { + SetGLError(GL_INVALID_OPERATION, "BindTransformFeedback", + "transformfeedback reserved id"); + return; } + BindTransformFeedbackHelper(target, transformfeedback); CheckGLError(); } @@ -162,6 +222,65 @@ void GLES2Implementation::Clear(GLbitfield mask) { CheckGLError(); } +void GLES2Implementation::ClearBufferfi(GLenum buffer, + GLint drawbuffers, + GLfloat depth, + GLint stencil) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClearBufferfi(" + << GLES2Util::GetStringBufferfv(buffer) << ", " + << drawbuffers << ", " << depth << ", " << stencil << ")"); + helper_->ClearBufferfi(buffer, drawbuffers, depth, stencil); + CheckGLError(); +} + +void GLES2Implementation::ClearBufferfv(GLenum buffer, + GLint drawbuffers, + const GLfloat* value) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClearBufferfv(" + << GLES2Util::GetStringBufferfv(buffer) << ", " + << drawbuffers << ", " << static_cast<const void*>(value) + << ")"); + size_t count = GLES2Util::CalcClearBufferfvDataCount(buffer); + DCHECK_LE(count, 4u); + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << value[ii]); + helper_->ClearBufferfvImmediate(buffer, drawbuffers, value); + CheckGLError(); +} + +void GLES2Implementation::ClearBufferiv(GLenum buffer, + GLint drawbuffers, + const GLint* value) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClearBufferiv(" + << GLES2Util::GetStringBufferiv(buffer) << ", " + << drawbuffers << ", " << static_cast<const void*>(value) + << ")"); + size_t count = GLES2Util::CalcClearBufferivDataCount(buffer); + DCHECK_LE(count, 4u); + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << value[ii]); + helper_->ClearBufferivImmediate(buffer, drawbuffers, value); + CheckGLError(); +} + +void GLES2Implementation::ClearBufferuiv(GLenum buffer, + GLint drawbuffers, + const GLuint* value) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClearBufferuiv(" + << GLES2Util::GetStringBufferuiv(buffer) << ", " + << drawbuffers << ", " << static_cast<const void*>(value) + << ")"); + size_t count = 4; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << value[ii]); + helper_->ClearBufferuivImmediate(buffer, drawbuffers, value); + CheckGLError(); +} + void GLES2Implementation::ClearColor(GLclampf red, GLclampf green, GLclampf blue, @@ -209,6 +328,34 @@ void GLES2Implementation::CompileShader(GLuint shader) { CheckGLError(); } +void GLES2Implementation::CopyBufferSubData(GLenum readtarget, + GLenum writetarget, + GLintptr readoffset, + GLintptr writeoffset, + GLsizeiptr size) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopyBufferSubData(" + << GLES2Util::GetStringBufferTarget(readtarget) << ", " + << GLES2Util::GetStringBufferTarget(writetarget) << ", " + << readoffset << ", " << writeoffset << ", " << size + << ")"); + if (readoffset < 0) { + SetGLError(GL_INVALID_VALUE, "glCopyBufferSubData", "readoffset < 0"); + return; + } + if (writeoffset < 0) { + SetGLError(GL_INVALID_VALUE, "glCopyBufferSubData", "writeoffset < 0"); + return; + } + if (size < 0) { + SetGLError(GL_INVALID_VALUE, "glCopyBufferSubData", "size < 0"); + return; + } + helper_->CopyBufferSubData(readtarget, writetarget, readoffset, writeoffset, + size); + CheckGLError(); +} + void GLES2Implementation::CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, @@ -266,6 +413,34 @@ void GLES2Implementation::CopyTexSubImage2D(GLenum target, CheckGLError(); } +void GLES2Implementation::CopyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopyTexSubImage3D(" + << GLES2Util::GetStringTexture3DTarget(target) << ", " + << level << ", " << xoffset << ", " << yoffset << ", " + << zoffset << ", " << x << ", " << y << ", " << width + << ", " << height << ")"); + if (width < 0) { + SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage3D", "width < 0"); + return; + } + if (height < 0) { + SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage3D", "height < 0"); + return; + } + helper_->CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, + width, height); + CheckGLError(); +} + GLuint GLES2Implementation::CreateProgram() { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateProgram(" @@ -377,6 +552,36 @@ void GLES2Implementation::DeleteRenderbuffers(GLsizei n, CheckGLError(); } +void GLES2Implementation::DeleteSamplers(GLsizei n, const GLuint* samplers) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteSamplers(" << n << ", " + << static_cast<const void*>(samplers) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < n; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << samplers[i]); + } + }); + GPU_CLIENT_DCHECK_CODE_BLOCK({ + for (GLsizei i = 0; i < n; ++i) { + DCHECK(samplers[i] != 0); + } + }); + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glDeleteSamplers", "n < 0"); + return; + } + DeleteSamplersHelper(n, samplers); + CheckGLError(); +} + +void GLES2Implementation::DeleteSync(GLsync sync) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteSync(" << sync << ")"); + GPU_CLIENT_DCHECK(sync != 0); + DeleteSyncHelper(sync); + CheckGLError(); +} + void GLES2Implementation::DeleteShader(GLuint shader) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteShader(" << shader << ")"); @@ -407,6 +612,29 @@ void GLES2Implementation::DeleteTextures(GLsizei n, const GLuint* textures) { CheckGLError(); } +void GLES2Implementation::DeleteTransformFeedbacks(GLsizei n, + const GLuint* ids) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteTransformFeedbacks(" << n + << ", " << static_cast<const void*>(ids) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < n; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << ids[i]); + } + }); + GPU_CLIENT_DCHECK_CODE_BLOCK({ + for (GLsizei i = 0; i < n; ++i) { + DCHECK(ids[i] != 0); + } + }); + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glDeleteTransformFeedbacks", "n < 0"); + return; + } + DeleteTransformFeedbacksHelper(n, ids); + CheckGLError(); +} + void GLES2Implementation::DepthFunc(GLenum func) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDepthFunc(" @@ -439,6 +667,27 @@ void GLES2Implementation::DetachShader(GLuint program, GLuint shader) { CheckGLError(); } +GLsync GLES2Implementation::FenceSync(GLenum condition, GLbitfield flags) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFenceSync(" + << GLES2Util::GetStringSyncCondition(condition) << ", " + << flags << ")"); + if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE) { + SetGLError(GL_INVALID_ENUM, "glFenceSync", "condition GL_INVALID_ENUM"); + return 0; + } + if (flags != 0) { + SetGLError(GL_INVALID_VALUE, "glFenceSync", "flags GL_INVALID_VALUE"); + return 0; + } + GLuint client_id; + GetIdHandler(id_namespaces::kSyncs)->MakeIds(this, 0, 1, &client_id); + helper_->FenceSync(client_id); + GPU_CLIENT_LOG("returned " << client_id); + CheckGLError(); + return reinterpret_cast<GLsync>(client_id); +} + void GLES2Implementation::FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, @@ -474,6 +723,20 @@ void GLES2Implementation::FramebufferTexture2D(GLenum target, CheckGLError(); } +void GLES2Implementation::FramebufferTextureLayer(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFramebufferTextureLayer(" + << GLES2Util::GetStringFrameBufferTarget(target) << ", " + << GLES2Util::GetStringAttachment(attachment) << ", " + << texture << ", " << level << ", " << layer << ")"); + helper_->FramebufferTextureLayer(target, attachment, texture, level, layer); + CheckGLError(); +} + void GLES2Implementation::FrontFace(GLenum mode) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFrontFace(" @@ -554,6 +817,27 @@ void GLES2Implementation::GenRenderbuffers(GLsizei n, GLuint* renderbuffers) { CheckGLError(); } +void GLES2Implementation::GenSamplers(GLsizei n, GLuint* samplers) { + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenSamplers(" << n << ", " + << static_cast<const void*>(samplers) << ")"); + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glGenSamplers", "n < 0"); + return; + } + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GetIdHandler(id_namespaces::kSamplers)->MakeIds(this, 0, n, samplers); + GenSamplersHelper(n, samplers); + helper_->GenSamplersImmediate(n, samplers); + if (share_group_->bind_generates_resource()) + helper_->CommandBufferHelper::Flush(); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < n; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << samplers[i]); + } + }); + CheckGLError(); +} + void GLES2Implementation::GenTextures(GLsizei n, GLuint* textures) { GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenTextures(" << n << ", " << static_cast<const void*>(textures) << ")"); @@ -575,6 +859,27 @@ void GLES2Implementation::GenTextures(GLsizei n, GLuint* textures) { CheckGLError(); } +void GLES2Implementation::GenTransformFeedbacks(GLsizei n, GLuint* ids) { + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenTransformFeedbacks(" << n + << ", " << static_cast<const void*>(ids) << ")"); + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glGenTransformFeedbacks", "n < 0"); + return; + } + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GetIdHandler(id_namespaces::kTransformFeedbacks)->MakeIds(this, 0, n, ids); + GenTransformFeedbacksHelper(n, ids); + helper_->GenTransformFeedbacksImmediate(n, ids); + if (share_group_->bind_generates_resource()) + helper_->CommandBufferHelper::Flush(); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < n; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << ids[i]); + } + }); + CheckGLError(); +} + void GLES2Implementation::GetBooleanv(GLenum pname, GLboolean* params) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLboolean, params); @@ -691,6 +996,87 @@ void GLES2Implementation::GetFramebufferAttachmentParameteriv(GLenum target, }); CheckGLError(); } +void GLES2Implementation::GetInteger64v(GLenum pname, GLint64* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetInteger64v(" + << GLES2Util::GetStringGLState(pname) << ", " + << static_cast<const void*>(params) << ")"); + TRACE_EVENT0("gpu", "GLES2Implementation::GetInteger64v"); + if (GetInteger64vHelper(pname, params)) { + return; + } + typedef cmds::GetInteger64v::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return; + } + result->SetNumResults(0); + helper_->GetInteger64v(pname, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + result->CopyResult(params); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32_t i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + CheckGLError(); +} +void GLES2Implementation::GetIntegeri_v(GLenum pname, + GLuint index, + GLint* data) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, data); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetIntegeri_v(" + << GLES2Util::GetStringIndexedGLState(pname) << ", " + << index << ", " << static_cast<const void*>(data) << ")"); + TRACE_EVENT0("gpu", "GLES2Implementation::GetIntegeri_v"); + if (GetIntegeri_vHelper(pname, index, data)) { + return; + } + typedef cmds::GetIntegeri_v::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return; + } + result->SetNumResults(0); + helper_->GetIntegeri_v(pname, index, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + result->CopyResult(data); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32_t i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + CheckGLError(); +} +void GLES2Implementation::GetInteger64i_v(GLenum pname, + GLuint index, + GLint64* data) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetInteger64i_v(" + << GLES2Util::GetStringIndexedGLState(pname) << ", " + << index << ", " << static_cast<const void*>(data) << ")"); + TRACE_EVENT0("gpu", "GLES2Implementation::GetInteger64i_v"); + if (GetInteger64i_vHelper(pname, index, data)) { + return; + } + typedef cmds::GetInteger64i_v::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return; + } + result->SetNumResults(0); + helper_->GetInteger64i_v(pname, index, GetResultShmId(), + GetResultShmOffset()); + WaitForCmd(); + result->CopyResult(data); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32_t i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + CheckGLError(); +} void GLES2Implementation::GetIntegerv(GLenum pname, GLint* params) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params); @@ -717,6 +1103,44 @@ void GLES2Implementation::GetIntegerv(GLenum pname, GLint* params) { }); CheckGLError(); } +void GLES2Implementation::GetInternalformativ(GLenum target, + GLenum format, + GLenum pname, + GLsizei bufSize, + GLint* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetInternalformativ(" + << GLES2Util::GetStringRenderBufferTarget(target) << ", " + << GLES2Util::GetStringRenderBufferFormat(format) << ", " + << GLES2Util::GetStringInternalFormatParameter(pname) + << ", " << bufSize << ", " + << static_cast<const void*>(params) << ")"); + if (bufSize < 0) { + SetGLError(GL_INVALID_VALUE, "glGetInternalformativ", "bufSize < 0"); + return; + } + TRACE_EVENT0("gpu", "GLES2Implementation::GetInternalformativ"); + if (GetInternalformativHelper(target, format, pname, bufSize, params)) { + return; + } + typedef cmds::GetInternalformativ::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return; + } + result->SetNumResults(0); + helper_->GetInternalformativ(target, format, pname, bufSize, GetResultShmId(), + GetResultShmOffset()); + WaitForCmd(); + result->CopyResult(params); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32_t i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + CheckGLError(); +} void GLES2Implementation::GetProgramiv(GLuint program, GLenum pname, GLint* params) { @@ -802,6 +1226,65 @@ void GLES2Implementation::GetRenderbufferParameteriv(GLenum target, }); CheckGLError(); } +void GLES2Implementation::GetSamplerParameterfv(GLuint sampler, + GLenum pname, + GLfloat* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetSamplerParameterfv(" + << sampler << ", " + << GLES2Util::GetStringSamplerParameter(pname) << ", " + << static_cast<const void*>(params) << ")"); + TRACE_EVENT0("gpu", "GLES2Implementation::GetSamplerParameterfv"); + if (GetSamplerParameterfvHelper(sampler, pname, params)) { + return; + } + typedef cmds::GetSamplerParameterfv::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return; + } + result->SetNumResults(0); + helper_->GetSamplerParameterfv(sampler, pname, GetResultShmId(), + GetResultShmOffset()); + WaitForCmd(); + result->CopyResult(params); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32_t i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + CheckGLError(); +} +void GLES2Implementation::GetSamplerParameteriv(GLuint sampler, + GLenum pname, + GLint* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetSamplerParameteriv(" + << sampler << ", " + << GLES2Util::GetStringSamplerParameter(pname) << ", " + << static_cast<const void*>(params) << ")"); + TRACE_EVENT0("gpu", "GLES2Implementation::GetSamplerParameteriv"); + if (GetSamplerParameterivHelper(sampler, pname, params)) { + return; + } + typedef cmds::GetSamplerParameteriv::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return; + } + result->SetNumResults(0); + helper_->GetSamplerParameteriv(sampler, pname, GetResultShmId(), + GetResultShmOffset()); + WaitForCmd(); + result->CopyResult(params); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32_t i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + CheckGLError(); +} void GLES2Implementation::GetShaderiv(GLuint shader, GLenum pname, GLint* params) { @@ -884,6 +1367,46 @@ void GLES2Implementation::GetShaderSource(GLuint shader, } CheckGLError(); } +void GLES2Implementation::GetSynciv(GLsync sync, + GLenum pname, + GLsizei bufsize, + GLsizei* length, + GLint* values) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(GLsizei, length); + GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, values); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetSynciv(" << sync << ", " + << GLES2Util::GetStringSyncParameter(pname) << ", " + << bufsize << ", " << static_cast<const void*>(length) + << ", " << static_cast<const void*>(values) << ")"); + if (bufsize < 0) { + SetGLError(GL_INVALID_VALUE, "glGetSynciv", "bufsize < 0"); + return; + } + TRACE_EVENT0("gpu", "GLES2Implementation::GetSynciv"); + if (GetSyncivHelper(sync, pname, bufsize, length, values)) { + return; + } + typedef cmds::GetSynciv::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return; + } + result->SetNumResults(0); + helper_->GetSynciv(ToGLuint(sync), pname, GetResultShmId(), + GetResultShmOffset()); + WaitForCmd(); + result->CopyResult(values); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int32_t i = 0; i < result->GetNumResults(); ++i) { + GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); + } + }); + if (length) { + *length = result->GetNumResults(); + } + CheckGLError(); +} void GLES2Implementation::GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { @@ -952,6 +1475,62 @@ void GLES2Implementation::Hint(GLenum target, GLenum mode) { CheckGLError(); } +void GLES2Implementation::InvalidateFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInvalidateFramebuffer(" + << GLES2Util::GetStringInvalidateFrameBufferTarget(target) + << ", " << count << ", " + << static_cast<const void*>(attachments) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << attachments[0 + i * 1]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glInvalidateFramebuffer", "count < 0"); + return; + } + helper_->InvalidateFramebufferImmediate(target, count, attachments); + CheckGLError(); +} + +void GLES2Implementation::InvalidateSubFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInvalidateSubFramebuffer(" + << GLES2Util::GetStringInvalidateFrameBufferTarget(target) + << ", " << count << ", " + << static_cast<const void*>(attachments) << ", " << x + << ", " << y << ", " << width << ", " << height << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << attachments[0 + i * 1]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glInvalidateSubFramebuffer", "count < 0"); + return; + } + if (width < 0) { + SetGLError(GL_INVALID_VALUE, "glInvalidateSubFramebuffer", "width < 0"); + return; + } + if (height < 0) { + SetGLError(GL_INVALID_VALUE, "glInvalidateSubFramebuffer", "height < 0"); + return; + } + helper_->InvalidateSubFramebufferImmediate(target, count, attachments, x, y, + width, height); + CheckGLError(); +} + GLboolean GLES2Implementation::IsBuffer(GLuint buffer) { GPU_CLIENT_SINGLE_THREAD_CHECK(); TRACE_EVENT0("gpu", "GLES2Implementation::IsBuffer"); @@ -1026,6 +1605,24 @@ GLboolean GLES2Implementation::IsRenderbuffer(GLuint renderbuffer) { return result_value; } +GLboolean GLES2Implementation::IsSampler(GLuint sampler) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + TRACE_EVENT0("gpu", "GLES2Implementation::IsSampler"); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsSampler(" << sampler << ")"); + typedef cmds::IsSampler::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return GL_FALSE; + } + *result = 0; + helper_->IsSampler(sampler, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + GLboolean result_value = *result != 0; + GPU_CLIENT_LOG("returned " << result_value); + CheckGLError(); + return result_value; +} + GLboolean GLES2Implementation::IsShader(GLuint shader) { GPU_CLIENT_SINGLE_THREAD_CHECK(); TRACE_EVENT0("gpu", "GLES2Implementation::IsShader"); @@ -1044,6 +1641,24 @@ GLboolean GLES2Implementation::IsShader(GLuint shader) { return result_value; } +GLboolean GLES2Implementation::IsSync(GLsync sync) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + TRACE_EVENT0("gpu", "GLES2Implementation::IsSync"); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsSync(" << sync << ")"); + typedef cmds::IsSync::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return GL_FALSE; + } + *result = 0; + helper_->IsSync(ToGLuint(sync), GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + GLboolean result_value = *result != 0; + GPU_CLIENT_LOG("returned " << result_value); + CheckGLError(); + return result_value; +} + GLboolean GLES2Implementation::IsTexture(GLuint texture) { GPU_CLIENT_SINGLE_THREAD_CHECK(); TRACE_EVENT0("gpu", "GLES2Implementation::IsTexture"); @@ -1062,6 +1677,26 @@ GLboolean GLES2Implementation::IsTexture(GLuint texture) { return result_value; } +GLboolean GLES2Implementation::IsTransformFeedback(GLuint transformfeedback) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + TRACE_EVENT0("gpu", "GLES2Implementation::IsTransformFeedback"); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsTransformFeedback(" + << transformfeedback << ")"); + typedef cmds::IsTransformFeedback::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return GL_FALSE; + } + *result = 0; + helper_->IsTransformFeedback(transformfeedback, GetResultShmId(), + GetResultShmOffset()); + WaitForCmd(); + GLboolean result_value = *result != 0; + GPU_CLIENT_LOG("returned " << result_value); + CheckGLError(); + return result_value; +} + void GLES2Implementation::LineWidth(GLfloat width) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glLineWidth(" << width << ")"); @@ -1069,6 +1704,14 @@ void GLES2Implementation::LineWidth(GLfloat width) { CheckGLError(); } +void GLES2Implementation::PauseTransformFeedback() { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPauseTransformFeedback(" + << ")"); + helper_->PauseTransformFeedback(); + CheckGLError(); +} + void GLES2Implementation::PolygonOffset(GLfloat factor, GLfloat units) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPolygonOffset(" << factor << ", " @@ -1077,6 +1720,14 @@ void GLES2Implementation::PolygonOffset(GLfloat factor, GLfloat units) { CheckGLError(); } +void GLES2Implementation::ReadBuffer(GLenum src) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glReadBuffer(" + << GLES2Util::GetStringEnum(src) << ")"); + helper_->ReadBuffer(src); + CheckGLError(); +} + void GLES2Implementation::ReleaseShaderCompiler() { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glReleaseShaderCompiler(" @@ -1106,6 +1757,14 @@ void GLES2Implementation::RenderbufferStorage(GLenum target, CheckGLError(); } +void GLES2Implementation::ResumeTransformFeedback() { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glResumeTransformFeedback(" + << ")"); + helper_->ResumeTransformFeedback(); + CheckGLError(); +} + void GLES2Implementation::SampleCoverage(GLclampf value, GLboolean invert) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSampleCoverage(" << value << ", " @@ -1114,6 +1773,56 @@ void GLES2Implementation::SampleCoverage(GLclampf value, GLboolean invert) { CheckGLError(); } +void GLES2Implementation::SamplerParameterf(GLuint sampler, + GLenum pname, + GLfloat param) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSamplerParameterf(" << sampler + << ", " << GLES2Util::GetStringSamplerParameter(pname) + << ", " << param << ")"); + helper_->SamplerParameterf(sampler, pname, param); + CheckGLError(); +} + +void GLES2Implementation::SamplerParameterfv(GLuint sampler, + GLenum pname, + const GLfloat* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSamplerParameterfv(" << sampler + << ", " << GLES2Util::GetStringSamplerParameter(pname) + << ", " << static_cast<const void*>(params) << ")"); + size_t count = 1; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << params[ii]); + helper_->SamplerParameterfvImmediate(sampler, pname, params); + CheckGLError(); +} + +void GLES2Implementation::SamplerParameteri(GLuint sampler, + GLenum pname, + GLint param) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSamplerParameteri(" << sampler + << ", " << GLES2Util::GetStringSamplerParameter(pname) + << ", " << param << ")"); + helper_->SamplerParameteri(sampler, pname, param); + CheckGLError(); +} + +void GLES2Implementation::SamplerParameteriv(GLuint sampler, + GLenum pname, + const GLint* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSamplerParameteriv(" << sampler + << ", " << GLES2Util::GetStringSamplerParameter(pname) + << ", " << static_cast<const void*>(params) << ")"); + size_t count = 1; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << params[ii]); + helper_->SamplerParameterivImmediate(sampler, pname, params); + CheckGLError(); +} + void GLES2Implementation::Scissor(GLint x, GLint y, GLsizei width, @@ -1133,6 +1842,41 @@ void GLES2Implementation::Scissor(GLint x, CheckGLError(); } +void GLES2Implementation::ShaderSource(GLuint shader, + GLsizei count, + const GLchar* const* str, + const GLint* length) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource(" << shader << ", " + << count << ", " << static_cast<const void*>(str) << ", " + << static_cast<const void*>(length) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei ii = 0; ii < count; ++ii) { + if (str[ii]) { + if (length && length[ii] >= 0) { + const std::string my_str(str[ii], length[ii]); + GPU_CLIENT_LOG(" " << ii << ": ---\n" << my_str << "\n---"); + } else { + GPU_CLIENT_LOG(" " << ii << ": ---\n" << str[ii] << "\n---"); + } + } else { + GPU_CLIENT_LOG(" " << ii << ": NULL"); + } + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glShaderSource", "count < 0"); + return; + } + + if (!PackStringsToBucket(count, str, length, "glShaderSource")) { + return; + } + helper_->ShaderSourceBucket(shader, kResultBucketId); + helper_->SetBucketSize(kResultBucketId, 0); + CheckGLError(); +} + void GLES2Implementation::StencilFunc(GLenum func, GLint ref, GLuint mask) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilFunc(" @@ -1215,7 +1959,9 @@ void GLES2Implementation::TexParameterfv(GLenum target, << GLES2Util::GetStringTextureBindTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << static_cast<const void*>(params) << ")"); - GPU_CLIENT_LOG("values: " << params[0]); + size_t count = 1; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << params[ii]); helper_->TexParameterfvImmediate(target, pname, params); CheckGLError(); } @@ -1240,11 +1986,79 @@ void GLES2Implementation::TexParameteriv(GLenum target, << GLES2Util::GetStringTextureBindTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << static_cast<const void*>(params) << ")"); - GPU_CLIENT_LOG("values: " << params[0]); + size_t count = 1; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << params[ii]); helper_->TexParameterivImmediate(target, pname, params); CheckGLError(); } +void GLES2Implementation::TexStorage3D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG( + "[" << GetLogPrefix() << "] glTexStorage3D(" + << GLES2Util::GetStringTexture3DTarget(target) << ", " << levels + << ", " + << GLES2Util::GetStringTextureInternalFormatStorage(internalFormat) + << ", " << width << ", " << height << ", " << depth << ")"); + if (levels < 0) { + SetGLError(GL_INVALID_VALUE, "glTexStorage3D", "levels < 0"); + return; + } + if (width < 0) { + SetGLError(GL_INVALID_VALUE, "glTexStorage3D", "width < 0"); + return; + } + if (height < 0) { + SetGLError(GL_INVALID_VALUE, "glTexStorage3D", "height < 0"); + return; + } + if (depth < 0) { + SetGLError(GL_INVALID_VALUE, "glTexStorage3D", "depth < 0"); + return; + } + helper_->TexStorage3D(target, levels, internalFormat, width, height, depth); + CheckGLError(); +} + +void GLES2Implementation::TransformFeedbackVaryings(GLuint program, + GLsizei count, + const char* const* varyings, + GLenum buffermode) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTransformFeedbackVaryings(" + << program << ", " << count << ", " + << static_cast<const void*>(varyings) << ", " + << GLES2Util::GetStringBufferMode(buffermode) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei ii = 0; ii < count; ++ii) { + if (varyings[ii]) { + GPU_CLIENT_LOG(" " << ii << ": ---\n" << varyings[ii] << "\n---"); + } else { + GPU_CLIENT_LOG(" " << ii << ": NULL"); + } + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glTransformFeedbackVaryings", "count < 0"); + return; + } + + if (!PackStringsToBucket(count, varyings, NULL, + "glTransformFeedbackVaryings")) { + return; + } + helper_->TransformFeedbackVaryingsBucket(program, kResultBucketId, + buffermode); + helper_->SetBucketSize(kResultBucketId, 0); + CheckGLError(); +} + void GLES2Implementation::Uniform1f(GLint location, GLfloat x) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform1f(" << location << ", " @@ -1299,6 +2113,33 @@ void GLES2Implementation::Uniform1iv(GLint location, CheckGLError(); } +void GLES2Implementation::Uniform1ui(GLint location, GLuint x) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform1ui(" << location << ", " + << x << ")"); + helper_->Uniform1ui(location, x); + CheckGLError(); +} + +void GLES2Implementation::Uniform1uiv(GLint location, + GLsizei count, + const GLuint* v) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform1uiv(" << location << ", " + << count << ", " << static_cast<const void*>(v) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << v[0 + i * 1]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glUniform1uiv", "count < 0"); + return; + } + helper_->Uniform1uivImmediate(location, count, v); + CheckGLError(); +} + void GLES2Implementation::Uniform2f(GLint location, GLfloat x, GLfloat y) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform2f(" << location << ", " @@ -1353,6 +2194,33 @@ void GLES2Implementation::Uniform2iv(GLint location, CheckGLError(); } +void GLES2Implementation::Uniform2ui(GLint location, GLuint x, GLuint y) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform2ui(" << location << ", " + << x << ", " << y << ")"); + helper_->Uniform2ui(location, x, y); + CheckGLError(); +} + +void GLES2Implementation::Uniform2uiv(GLint location, + GLsizei count, + const GLuint* v) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform2uiv(" << location << ", " + << count << ", " << static_cast<const void*>(v) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << v[0 + i * 2] << ", " << v[1 + i * 2]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glUniform2uiv", "count < 0"); + return; + } + helper_->Uniform2uivImmediate(location, count, v); + CheckGLError(); +} + void GLES2Implementation::Uniform3f(GLint location, GLfloat x, GLfloat y, @@ -1412,6 +2280,37 @@ void GLES2Implementation::Uniform3iv(GLint location, CheckGLError(); } +void GLES2Implementation::Uniform3ui(GLint location, + GLuint x, + GLuint y, + GLuint z) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform3ui(" << location << ", " + << x << ", " << y << ", " << z << ")"); + helper_->Uniform3ui(location, x, y, z); + CheckGLError(); +} + +void GLES2Implementation::Uniform3uiv(GLint location, + GLsizei count, + const GLuint* v) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform3uiv(" << location << ", " + << count << ", " << static_cast<const void*>(v) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << v[0 + i * 3] << ", " << v[1 + i * 3] + << ", " << v[2 + i * 3]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glUniform3uiv", "count < 0"); + return; + } + helper_->Uniform3uivImmediate(location, count, v); + CheckGLError(); +} + void GLES2Implementation::Uniform4f(GLint location, GLfloat x, GLfloat y, @@ -1476,6 +2375,38 @@ void GLES2Implementation::Uniform4iv(GLint location, CheckGLError(); } +void GLES2Implementation::Uniform4ui(GLint location, + GLuint x, + GLuint y, + GLuint z, + GLuint w) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform4ui(" << location << ", " + << x << ", " << y << ", " << z << ", " << w << ")"); + helper_->Uniform4ui(location, x, y, z, w); + CheckGLError(); +} + +void GLES2Implementation::Uniform4uiv(GLint location, + GLsizei count, + const GLuint* v) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform4uiv(" << location << ", " + << count << ", " << static_cast<const void*>(v) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << v[0 + i * 4] << ", " << v[1 + i * 4] + << ", " << v[2 + i * 4] << ", " << v[3 + i * 4]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glUniform4uiv", "count < 0"); + return; + } + helper_->Uniform4uivImmediate(location, count, v); + CheckGLError(); +} + void GLES2Implementation::UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, @@ -1505,6 +2436,67 @@ void GLES2Implementation::UniformMatrix2fv(GLint location, CheckGLError(); } +void GLES2Implementation::UniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix2x3fv(" << location + << ", " << count << ", " + << GLES2Util::GetStringBool(transpose) << ", " + << static_cast<const void*>(value) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << value[0 + i * 6] << ", " + << value[1 + i * 6] << ", " << value[2 + i * 6] + << ", " << value[3 + i * 6] << ", " + << value[4 + i * 6] << ", " << value[5 + i * 6]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix2x3fv", "count < 0"); + return; + } + if (transpose != false) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix2x3fv", + "transpose GL_INVALID_VALUE"); + return; + } + helper_->UniformMatrix2x3fvImmediate(location, count, value); + CheckGLError(); +} + +void GLES2Implementation::UniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix2x4fv(" << location + << ", " << count << ", " + << GLES2Util::GetStringBool(transpose) << ", " + << static_cast<const void*>(value) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG( + " " << i << ": " << value[0 + i * 8] << ", " << value[1 + i * 8] + << ", " << value[2 + i * 8] << ", " << value[3 + i * 8] << ", " + << value[4 + i * 8] << ", " << value[5 + i * 8] << ", " + << value[6 + i * 8] << ", " << value[7 + i * 8]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix2x4fv", "count < 0"); + return; + } + if (transpose != false) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix2x4fv", + "transpose GL_INVALID_VALUE"); + return; + } + helper_->UniformMatrix2x4fvImmediate(location, count, value); + CheckGLError(); +} + void GLES2Implementation::UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, @@ -1537,6 +2529,69 @@ void GLES2Implementation::UniformMatrix3fv(GLint location, CheckGLError(); } +void GLES2Implementation::UniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix3x2fv(" << location + << ", " << count << ", " + << GLES2Util::GetStringBool(transpose) << ", " + << static_cast<const void*>(value) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << value[0 + i * 6] << ", " + << value[1 + i * 6] << ", " << value[2 + i * 6] + << ", " << value[3 + i * 6] << ", " + << value[4 + i * 6] << ", " << value[5 + i * 6]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix3x2fv", "count < 0"); + return; + } + if (transpose != false) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix3x2fv", + "transpose GL_INVALID_VALUE"); + return; + } + helper_->UniformMatrix3x2fvImmediate(location, count, value); + CheckGLError(); +} + +void GLES2Implementation::UniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix3x4fv(" << location + << ", " << count << ", " + << GLES2Util::GetStringBool(transpose) << ", " + << static_cast<const void*>(value) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG( + " " << i << ": " << value[0 + i * 12] << ", " << value[1 + i * 12] + << ", " << value[2 + i * 12] << ", " << value[3 + i * 12] << ", " + << value[4 + i * 12] << ", " << value[5 + i * 12] << ", " + << value[6 + i * 12] << ", " << value[7 + i * 12] << ", " + << value[8 + i * 12] << ", " << value[9 + i * 12] << ", " + << value[10 + i * 12] << ", " << value[11 + i * 12]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix3x4fv", "count < 0"); + return; + } + if (transpose != false) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix3x4fv", + "transpose GL_INVALID_VALUE"); + return; + } + helper_->UniformMatrix3x4fvImmediate(location, count, value); + CheckGLError(); +} + void GLES2Implementation::UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, @@ -1572,6 +2627,70 @@ void GLES2Implementation::UniformMatrix4fv(GLint location, CheckGLError(); } +void GLES2Implementation::UniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix4x2fv(" << location + << ", " << count << ", " + << GLES2Util::GetStringBool(transpose) << ", " + << static_cast<const void*>(value) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG( + " " << i << ": " << value[0 + i * 8] << ", " << value[1 + i * 8] + << ", " << value[2 + i * 8] << ", " << value[3 + i * 8] << ", " + << value[4 + i * 8] << ", " << value[5 + i * 8] << ", " + << value[6 + i * 8] << ", " << value[7 + i * 8]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix4x2fv", "count < 0"); + return; + } + if (transpose != false) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix4x2fv", + "transpose GL_INVALID_VALUE"); + return; + } + helper_->UniformMatrix4x2fvImmediate(location, count, value); + CheckGLError(); +} + +void GLES2Implementation::UniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix4x3fv(" << location + << ", " << count << ", " + << GLES2Util::GetStringBool(transpose) << ", " + << static_cast<const void*>(value) << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < count; ++i) { + GPU_CLIENT_LOG( + " " << i << ": " << value[0 + i * 12] << ", " << value[1 + i * 12] + << ", " << value[2 + i * 12] << ", " << value[3 + i * 12] << ", " + << value[4 + i * 12] << ", " << value[5 + i * 12] << ", " + << value[6 + i * 12] << ", " << value[7 + i * 12] << ", " + << value[8 + i * 12] << ", " << value[9 + i * 12] << ", " + << value[10 + i * 12] << ", " << value[11 + i * 12]); + } + }); + if (count < 0) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix4x3fv", "count < 0"); + return; + } + if (transpose != false) { + SetGLError(GL_INVALID_VALUE, "glUniformMatrix4x3fv", + "transpose GL_INVALID_VALUE"); + return; + } + helper_->UniformMatrix4x3fvImmediate(location, count, value); + CheckGLError(); +} + void GLES2Implementation::UseProgram(GLuint program) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUseProgram(" << program << ")"); @@ -1579,9 +2698,7 @@ void GLES2Implementation::UseProgram(GLuint program) { SetGLError(GL_INVALID_OPERATION, "UseProgram", "program reserved id"); return; } - if (UseProgramHelper(program)) { - helper_->UseProgram(program); - } + UseProgramHelper(program); CheckGLError(); } @@ -1605,7 +2722,9 @@ void GLES2Implementation::VertexAttrib1fv(GLuint indx, const GLfloat* values) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib1fv(" << indx << ", " << static_cast<const void*>(values) << ")"); - GPU_CLIENT_LOG("values: " << values[0]); + size_t count = 1; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << values[ii]); helper_->VertexAttrib1fvImmediate(indx, values); CheckGLError(); } @@ -1622,7 +2741,9 @@ void GLES2Implementation::VertexAttrib2fv(GLuint indx, const GLfloat* values) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib2fv(" << indx << ", " << static_cast<const void*>(values) << ")"); - GPU_CLIENT_LOG("values: " << values[0] << ", " << values[1]); + size_t count = 2; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << values[ii]); helper_->VertexAttrib2fvImmediate(indx, values); CheckGLError(); } @@ -1642,8 +2763,9 @@ void GLES2Implementation::VertexAttrib3fv(GLuint indx, const GLfloat* values) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib3fv(" << indx << ", " << static_cast<const void*>(values) << ")"); - GPU_CLIENT_LOG("values: " << values[0] << ", " << values[1] << ", " - << values[2]); + size_t count = 3; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << values[ii]); helper_->VertexAttrib3fvImmediate(indx, values); CheckGLError(); } @@ -1664,12 +2786,60 @@ void GLES2Implementation::VertexAttrib4fv(GLuint indx, const GLfloat* values) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib4fv(" << indx << ", " << static_cast<const void*>(values) << ")"); - GPU_CLIENT_LOG("values: " << values[0] << ", " << values[1] << ", " - << values[2] << ", " << values[3]); + size_t count = 4; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << values[ii]); helper_->VertexAttrib4fvImmediate(indx, values); CheckGLError(); } +void GLES2Implementation::VertexAttribI4i(GLuint indx, + GLint x, + GLint y, + GLint z, + GLint w) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribI4i(" << indx << ", " + << x << ", " << y << ", " << z << ", " << w << ")"); + helper_->VertexAttribI4i(indx, x, y, z, w); + CheckGLError(); +} + +void GLES2Implementation::VertexAttribI4iv(GLuint indx, const GLint* values) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribI4iv(" << indx + << ", " << static_cast<const void*>(values) << ")"); + size_t count = 4; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << values[ii]); + helper_->VertexAttribI4ivImmediate(indx, values); + CheckGLError(); +} + +void GLES2Implementation::VertexAttribI4ui(GLuint indx, + GLuint x, + GLuint y, + GLuint z, + GLuint w) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribI4ui(" << indx + << ", " << x << ", " << y << ", " << z << ", " << w + << ")"); + helper_->VertexAttribI4ui(indx, x, y, z, w); + CheckGLError(); +} + +void GLES2Implementation::VertexAttribI4uiv(GLuint indx, const GLuint* values) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribI4uiv(" << indx + << ", " << static_cast<const void*>(values) << ")"); + size_t count = 4; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << values[ii]); + helper_->VertexAttribI4uivImmediate(indx, values); + CheckGLError(); +} + void GLES2Implementation::Viewport(GLint x, GLint y, GLsizei width, @@ -1874,6 +3044,23 @@ void GLES2Implementation::DeleteQueriesEXT(GLsizei n, const GLuint* queries) { CheckGLError(); } +void GLES2Implementation::BeginTransformFeedback(GLenum primitivemode) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBeginTransformFeedback(" + << GLES2Util::GetStringTransformFeedbackPrimitiveMode( + primitivemode) << ")"); + helper_->BeginTransformFeedback(primitivemode); + CheckGLError(); +} + +void GLES2Implementation::EndTransformFeedback() { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEndTransformFeedback(" + << ")"); + helper_->EndTransformFeedback(); + CheckGLError(); +} + void GLES2Implementation::GenVertexArraysOES(GLsizei n, GLuint* arrays) { GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenVertexArraysOES(" << n << ", " << static_cast<const void*>(arrays) << ")"); @@ -1945,9 +3132,7 @@ void GLES2Implementation::BindVertexArrayOES(GLuint array) { SetGLError(GL_INVALID_OPERATION, "BindVertexArrayOES", "array reserved id"); return; } - if (BindVertexArrayOESHelper(array)) { - helper_->BindVertexArrayOES(array); - } + BindVertexArrayOESHelper(array); CheckGLError(); } @@ -2004,18 +3189,32 @@ void GLES2Implementation::TexImageIOSurface2DCHROMIUM(GLenum target, void GLES2Implementation::CopyTextureCHROMIUM(GLenum target, GLenum source_id, GLenum dest_id, - GLint level, GLint internalformat, GLenum dest_type) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopyTextureCHROMIUM(" << GLES2Util::GetStringEnum(target) << ", " << GLES2Util::GetStringEnum(source_id) << ", " - << GLES2Util::GetStringEnum(dest_id) << ", " << level - << ", " << internalformat << ", " + << GLES2Util::GetStringEnum(dest_id) << ", " + << internalformat << ", " << GLES2Util::GetStringPixelType(dest_type) << ")"); - helper_->CopyTextureCHROMIUM(target, source_id, dest_id, level, - internalformat, dest_type); + helper_->CopyTextureCHROMIUM(target, source_id, dest_id, internalformat, + dest_type); + CheckGLError(); +} + +void GLES2Implementation::CopySubTextureCHROMIUM(GLenum target, + GLenum source_id, + GLenum dest_id, + GLint xoffset, + GLint yoffset) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopySubTextureCHROMIUM(" + << GLES2Util::GetStringEnum(target) << ", " + << GLES2Util::GetStringEnum(source_id) << ", " + << GLES2Util::GetStringEnum(dest_id) << ", " << xoffset + << ", " << yoffset << ")"); + helper_->CopySubTextureCHROMIUM(target, source_id, dest_id, xoffset, yoffset); CheckGLError(); } @@ -2095,9 +3294,7 @@ void GLES2Implementation::BindValuebufferCHROMIUM(GLenum target, "valuebuffer reserved id"); return; } - if (BindValuebufferCHROMIUMHelper(target, valuebuffer)) { - helper_->BindValuebufferCHROMIUM(target, valuebuffer); - } + BindValuebufferCHROMIUMHelper(target, valuebuffer); CheckGLError(); } @@ -2245,12 +3442,9 @@ void GLES2Implementation::MatrixLoadfCHROMIUM(GLenum matrixMode, GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMatrixLoadfCHROMIUM(" << GLES2Util::GetStringMatrixMode(matrixMode) << ", " << static_cast<const void*>(m) << ")"); - GPU_CLIENT_LOG("values: " << m[0] << ", " << m[1] << ", " << m[2] << ", " - << m[3] << ", " << m[4] << ", " << m[5] << ", " - << m[6] << ", " << m[7] << ", " << m[8] << ", " - << m[9] << ", " << m[10] << ", " << m[11] << ", " - << m[12] << ", " << m[13] << ", " << m[14] << ", " - << m[15]); + size_t count = 16; + for (size_t ii = 0; ii < count; ++ii) + GPU_CLIENT_LOG("value[" << ii << "]: " << m[ii]); helper_->MatrixLoadfCHROMIUMImmediate(matrixMode, m); CheckGLError(); } diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc b/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc index a004e3873fd..0b02f94897a 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -10,6 +10,7 @@ #include <GLES2/gl2ext.h> #include <GLES2/gl2extchromium.h> +#include <GLES3/gl3.h> #include "base/compiler_specific.h" #include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/client/program_info_manager.h" @@ -50,13 +51,13 @@ template <typename T> class SizedResultHelper { public: explicit SizedResultHelper(T result) - : size_(sizeof(result)), - result_(result) { + : size_(sizeof(result)) { + memcpy(result_, &result, sizeof(T)); } private: uint32 size_; - T result_; + char result_[sizeof(T)]; }; // Struct to make it easy to pass a vec4 worth of floats. @@ -377,13 +378,16 @@ class GLES2ImplementationTest : public testing::Test { static const GLint kMaxVertexUniformVectors = 128; static const GLint kNumCompressedTextureFormats = 0; static const GLint kNumShaderBinaryFormats = 0; + static const GLuint kMaxTransformFeedbackSeparateAttribs = 4; + static const GLuint kMaxUniformBufferBindings = 36; static const GLuint kStartId = 1024; - static const GLuint kBuffersStartId = - GLES2Implementation::kClientSideArrayId + 2 * kNumTestContexts; + static const GLuint kBuffersStartId = 1; static const GLuint kFramebuffersStartId = 1; static const GLuint kProgramsAndShadersStartId = 1; static const GLuint kRenderbuffersStartId = 1; + static const GLuint kSamplersStartId = 1; static const GLuint kTexturesStartId = 1; + static const GLuint kTransformFeedbacksStartId = 1; static const GLuint kQueriesStartId = 1; static const GLuint kVertexArraysStartId = 1; static const GLuint kValuebuffersStartId = 1; @@ -414,43 +418,39 @@ class GLES2ImplementationTest : public testing::Test { helper_->Initialize(kCommandBufferSizeBytes); gpu_control_.reset(new StrictMock<MockClientGpuControl>()); - EXPECT_CALL(*gpu_control_, GetCapabilities()) - .WillOnce(testing::Return(Capabilities())); - - GLES2Implementation::GLStaticState state; - GLES2Implementation::GLStaticState::IntState& int_state = state.int_state; - int_state.max_combined_texture_image_units = + Capabilities capabilities; + capabilities.VisitPrecisions( + [](GLenum shader, GLenum type, + Capabilities::ShaderPrecision* precision) { + precision->min_range = 3; + precision->max_range = 5; + precision->precision = 7; + }); + capabilities.max_combined_texture_image_units = kMaxCombinedTextureImageUnits; - int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize; - int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors; - int_state.max_renderbuffer_size = kMaxRenderbufferSize; - int_state.max_texture_image_units = kMaxTextureImageUnits; - int_state.max_texture_size = kMaxTextureSize; - int_state.max_varying_vectors = kMaxVaryingVectors; - int_state.max_vertex_attribs = kMaxVertexAttribs; - int_state.max_vertex_texture_image_units = kMaxVertexTextureImageUnits; - int_state.max_vertex_uniform_vectors = kMaxVertexUniformVectors; - int_state.num_compressed_texture_formats = kNumCompressedTextureFormats; - int_state.num_shader_binary_formats = kNumShaderBinaryFormats; - int_state.bind_generates_resource_chromium = + capabilities.max_cube_map_texture_size = kMaxCubeMapTextureSize; + capabilities.max_fragment_uniform_vectors = kMaxFragmentUniformVectors; + capabilities.max_renderbuffer_size = kMaxRenderbufferSize; + capabilities.max_texture_image_units = kMaxTextureImageUnits; + capabilities.max_texture_size = kMaxTextureSize; + capabilities.max_varying_vectors = kMaxVaryingVectors; + capabilities.max_vertex_attribs = kMaxVertexAttribs; + capabilities.max_vertex_texture_image_units = kMaxVertexTextureImageUnits; + capabilities.max_vertex_uniform_vectors = kMaxVertexUniformVectors; + capabilities.num_compressed_texture_formats = + kNumCompressedTextureFormats; + capabilities.num_shader_binary_formats = kNumShaderBinaryFormats; + capabilities.max_transform_feedback_separate_attribs = + kMaxTransformFeedbackSeparateAttribs; + capabilities.max_uniform_buffer_bindings = kMaxUniformBufferBindings; + capabilities.bind_generates_resource_chromium = bind_generates_resource_service ? 1 : 0; - - // This just happens to work for now because IntState has 1 GLint per - // state. - // If IntState gets more complicated this code will need to get more - // complicated. - ExpectedMemoryInfo mem1 = transfer_buffer_->GetExpectedMemory( - sizeof(GLES2Implementation::GLStaticState::IntState) * 2 + - sizeof(cmds::GetShaderPrecisionFormat::Result) * 12); + EXPECT_CALL(*gpu_control_, GetCapabilities()) + .WillOnce(testing::Return(capabilities)); { InSequence sequence; - EXPECT_CALL(*command_buffer_, OnFlush()) - .WillOnce(SetMemory(mem1.ptr + sizeof(int_state), int_state)) - .RetiresOnSaturation(); - GetNextToken(); // eat the token that starting up will use. - const bool support_client_side_arrays = true; gl_.reset(new GLES2Implementation(helper_.get(), share_group, @@ -467,7 +467,6 @@ class GLES2ImplementationTest : public testing::Test { return false; } - EXPECT_CALL(*command_buffer_, OnFlush()).Times(1).RetiresOnSaturation(); helper_->CommandBufferHelper::Finish(); ::testing::Mock::VerifyAndClearExpectations(gl_.get()); @@ -761,7 +760,9 @@ const GLuint GLES2ImplementationTest::kBuffersStartId; const GLuint GLES2ImplementationTest::kFramebuffersStartId; const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId; const GLuint GLES2ImplementationTest::kRenderbuffersStartId; +const GLuint GLES2ImplementationTest::kSamplersStartId; const GLuint GLES2ImplementationTest::kTexturesStartId; +const GLuint GLES2ImplementationTest::kTransformFeedbacksStartId; const GLuint GLES2ImplementationTest::kQueriesStartId; const GLuint GLES2ImplementationTest::kVertexArraysStartId; const GLuint GLES2ImplementationTest::kValuebuffersStartId; @@ -827,20 +828,22 @@ TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) { cmds::GetShaderPrecisionFormat cmd; }; typedef cmds::GetShaderPrecisionFormat::Result Result; + const unsigned kDummyType1 = 3; + const unsigned kDummyType2 = 4; - // The first call for mediump should trigger a command buffer request. + // The first call for dummy type 1 should trigger a command buffer request. GLint range1[2] = {0, 0}; GLint precision1 = 0; Cmds expected1; ExpectedMemoryInfo client_result1 = GetExpectedResultMemory(4); - expected1.cmd.Init(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, - client_result1.id, client_result1.offset); + expected1.cmd.Init(GL_FRAGMENT_SHADER, kDummyType1, client_result1.id, + client_result1.offset); Result server_result1 = {true, 14, 14, 10}; EXPECT_CALL(*command_buffer(), OnFlush()) .WillOnce(SetMemory(client_result1.ptr, server_result1)) .RetiresOnSaturation(); - gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, - range1, &precision1); + gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range1, + &precision1); const void* commands2 = GetPut(); EXPECT_NE(commands_, commands2); EXPECT_EQ(0, memcmp(&expected1, commands_, sizeof(expected1))); @@ -848,92 +851,53 @@ TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) { EXPECT_EQ(range1[1], 14); EXPECT_EQ(precision1, 10); - // The second call for mediump should use the cached value and avoid + // The second call for dummy type 1 should use the cached value and avoid // triggering a command buffer request, so we do not expect a call to // OnFlush() here. We do expect the results to be correct though. GLint range2[2] = {0, 0}; GLint precision2 = 0; - gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, - range2, &precision2); + gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range2, + &precision2); const void* commands3 = GetPut(); EXPECT_EQ(commands2, commands3); EXPECT_EQ(range2[0], 14); EXPECT_EQ(range2[1], 14); EXPECT_EQ(precision2, 10); - // If we then make a request for highp, we should get another command + // If we then make a request for dummy type 2, we should get another command // buffer request since it hasn't been cached yet. GLint range3[2] = {0, 0}; GLint precision3 = 0; Cmds expected3; ExpectedMemoryInfo result3 = GetExpectedResultMemory(4); - expected3.cmd.Init(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, - result3.id, result3.offset); + expected3.cmd.Init(GL_FRAGMENT_SHADER, kDummyType2, result3.id, + result3.offset); Result result3_source = {true, 62, 62, 16}; EXPECT_CALL(*command_buffer(), OnFlush()) .WillOnce(SetMemory(result3.ptr, result3_source)) .RetiresOnSaturation(); - gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, - range3, &precision3); + gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType2, range3, + &precision3); const void* commands4 = GetPut(); EXPECT_NE(commands3, commands4); EXPECT_EQ(0, memcmp(&expected3, commands3, sizeof(expected3))); EXPECT_EQ(range3[0], 62); EXPECT_EQ(range3[1], 62); EXPECT_EQ(precision3, 16); -} -TEST_F(GLES2ImplementationTest, ShaderSource) { - const uint32 kBucketId = GLES2Implementation::kResultBucketId; - const GLuint kShaderId = 456; - const char* kString1 = "foobar"; - const char* kString2 = "barfoo"; - const size_t kString1Size = strlen(kString1); - const size_t kString2Size = strlen(kString2); - const size_t kString3Size = 1; // Want the NULL; - const size_t kSourceSize = kString1Size + kString2Size + kString3Size; - const size_t kPaddedString1Size = - transfer_buffer_->RoundToAlignment(kString1Size); - const size_t kPaddedString2Size = - transfer_buffer_->RoundToAlignment(kString2Size); - const size_t kPaddedString3Size = - transfer_buffer_->RoundToAlignment(kString3Size); - struct Cmds { - cmd::SetBucketSize set_bucket_size; - cmd::SetBucketData set_bucket_data1; - cmd::SetToken set_token1; - cmd::SetBucketData set_bucket_data2; - cmd::SetToken set_token2; - cmd::SetBucketData set_bucket_data3; - cmd::SetToken set_token3; - cmds::ShaderSourceBucket shader_source_bucket; - cmd::SetBucketSize clear_bucket_size; - }; - - ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size); - ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size); - ExpectedMemoryInfo mem3 = GetExpectedMemory(kPaddedString3Size); - - Cmds expected; - expected.set_bucket_size.Init(kBucketId, kSourceSize); - expected.set_bucket_data1.Init( - kBucketId, 0, kString1Size, mem1.id, mem1.offset); - expected.set_token1.Init(GetNextToken()); - expected.set_bucket_data2.Init( - kBucketId, kString1Size, kString2Size, mem2.id, mem2.offset); - expected.set_token2.Init(GetNextToken()); - expected.set_bucket_data3.Init( - kBucketId, kString1Size + kString2Size, - kString3Size, mem3.id, mem3.offset); - expected.set_token3.Init(GetNextToken()); - expected.shader_source_bucket.Init(kShaderId, kBucketId); - expected.clear_bucket_size.Init(kBucketId, 0); - const char* strings[] = { - kString1, - kString2, - }; - gl_->ShaderSource(kShaderId, 2, strings, NULL); - EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + // Any call for predefined types should use the cached value from the + // Capabilities and avoid triggering a command buffer request, so we do not + // expect a call to OnFlush() here. We do expect the results to be correct + // though. + GLint range4[2] = {0, 0}; + GLint precision4 = 0; + gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, range4, + &precision4); + const void* commands5 = GetPut(); + EXPECT_EQ(commands4, commands5); + EXPECT_EQ(range4[0], 3); + EXPECT_EQ(range4[1], 5); + EXPECT_EQ(precision4, 7); } TEST_F(GLES2ImplementationTest, GetShaderSource) { @@ -1957,68 +1921,61 @@ TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) { EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); } -TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) { - const GLenum pnames[] = { - GL_DEPTH_WRITEMASK, - GL_COLOR_WRITEMASK, - GL_STENCIL_WRITEMASK, - }; - const GLint num_results = 6; - GLint results[num_results + 1]; - struct Cmds { - cmds::GetMultipleIntegervCHROMIUM get_multiple; - cmd::SetToken set_token; - }; - const GLsizei kNumPnames = arraysize(pnames); - const GLsizeiptr kResultsSize = num_results * sizeof(results[0]); - const size_t kPNamesSize = kNumPnames * sizeof(pnames[0]); - - ExpectedMemoryInfo mem1 = GetExpectedMemory(kPNamesSize + kResultsSize); - ExpectedMemoryInfo result1 = GetExpectedResultMemory( - sizeof(cmds::GetError::Result)); +TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) { + const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const GLuint kProgramId = 123; + const char kBad = 0x12; + GLsizei size = 0; + const Str7 kString = {"foobar"}; + char buf[20]; - const uint32 kPnamesOffset = mem1.offset; - const uint32 kResultsOffset = mem1.offset + kPNamesSize; - Cmds expected; - expected.get_multiple.Init( - mem1.id, kPnamesOffset, kNumPnames, - mem1.id, kResultsOffset, kResultsSize); - expected.set_token.Init(GetNextToken()); + ExpectedMemoryInfo mem1 = + GetExpectedMemory(MaxTransferBufferSize()); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result)); + ExpectedMemoryInfo result2 = + GetExpectedResultMemory(sizeof(cmds::GetError::Result)); - const GLint kSentinel = 0x12345678; - memset(results, 0, sizeof(results)); - results[num_results] = kSentinel; - const GLint returned_results[] = { - 1, 0, 1, 0, 1, -1, - }; - // One call to flush to wait for results + memset(buf, kBad, sizeof(buf)); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemoryFromArray(mem1.ptr + kPNamesSize, - returned_results, sizeof(returned_results))) - .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) + .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))), + SetMemory(mem1.ptr, kString))) + .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); - gl_->GetMultipleIntegervCHROMIUM( - &pnames[0], kNumPnames, &results[0], kResultsSize); + struct Cmds { + cmd::SetBucketSize set_bucket_size1; + cmds::GetProgramInfoCHROMIUM get_program_info; + cmd::GetBucketStart get_bucket_start; + cmd::SetToken set_token1; + cmd::SetBucketSize set_bucket_size2; + }; + Cmds expected; + expected.set_bucket_size1.Init(kBucketId, 0); + expected.get_program_info.Init(kProgramId, kBucketId); + expected.get_bucket_start.Init( + kBucketId, result1.id, result1.offset, + MaxTransferBufferSize(), mem1.id, mem1.offset); + expected.set_token1.Init(GetNextToken()); + expected.set_bucket_size2.Init(kBucketId, 0); + gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(0, memcmp(&returned_results, results, sizeof(returned_results))); - EXPECT_EQ(kSentinel, results[num_results]); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); + EXPECT_EQ(sizeof(kString), static_cast<size_t>(size)); + EXPECT_STREQ(kString.str, buf); + EXPECT_EQ(buf[sizeof(kString)], kBad); } -TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) { - GLenum pnames[] = { - GL_DEPTH_WRITEMASK, - GL_COLOR_WRITEMASK, - GL_STENCIL_WRITEMASK, - }; - const GLint num_results = 6; - GLint results[num_results + 1]; - const GLsizei kNumPnames = arraysize(pnames); - const GLsizeiptr kResultsSize = num_results * sizeof(results[0]); +TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) { + const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const GLuint kProgramId = 123; + GLsizei size = 0; + const Str7 kString = {"foobar"}; + char buf[20]; + ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize()); ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(cmds::GetError::Result)); + GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result)); ExpectedMemoryInfo result2 = GetExpectedResultMemory(sizeof(cmds::GetError::Result)); ExpectedMemoryInfo result3 = @@ -2026,54 +1983,47 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) { ExpectedMemoryInfo result4 = GetExpectedResultMemory(sizeof(cmds::GetError::Result)); - // Calls to flush to wait for GetError EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) + .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))), + SetMemory(mem1.ptr, kString))) .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR))) .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); - const GLint kSentinel = 0x12345678; - memset(results, 0, sizeof(results)); - results[num_results] = kSentinel; - // try bad size. - gl_->GetMultipleIntegervCHROMIUM( - &pnames[0], kNumPnames, &results[0], kResultsSize + 1); - EXPECT_TRUE(NoCommandsWritten()); - EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); - EXPECT_EQ(0, results[0]); - EXPECT_EQ(kSentinel, results[num_results]); - // try bad size. + // try bufsize not big enough. + struct Cmds { + cmd::SetBucketSize set_bucket_size1; + cmds::GetProgramInfoCHROMIUM get_program_info; + cmd::GetBucketStart get_bucket_start; + cmd::SetToken set_token1; + cmd::SetBucketSize set_bucket_size2; + }; + Cmds expected; + expected.set_bucket_size1.Init(kBucketId, 0); + expected.get_program_info.Init(kProgramId, kBucketId); + expected.get_bucket_start.Init( + kBucketId, result1.id, result1.offset, + MaxTransferBufferSize(), mem1.id, mem1.offset); + expected.set_token1.Init(GetNextToken()); + expected.set_bucket_size2.Init(kBucketId, 0); + gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError()); ClearCommands(); - gl_->GetMultipleIntegervCHROMIUM( - &pnames[0], kNumPnames, &results[0], kResultsSize - 1); + + // try bad bufsize + gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf); EXPECT_TRUE(NoCommandsWritten()); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); - EXPECT_EQ(0, results[0]); - EXPECT_EQ(kSentinel, results[num_results]); - // try uncleared results. ClearCommands(); - results[2] = 1; - gl_->GetMultipleIntegervCHROMIUM( - &pnames[0], kNumPnames, &results[0], kResultsSize); + // try no size ptr. + gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf); EXPECT_TRUE(NoCommandsWritten()); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); - EXPECT_EQ(0, results[0]); - EXPECT_EQ(kSentinel, results[num_results]); - // try bad enum results. - ClearCommands(); - results[2] = 0; - pnames[1] = GL_TRUE; - gl_->GetMultipleIntegervCHROMIUM( - &pnames[0], kNumPnames, &results[0], kResultsSize); - EXPECT_TRUE(NoCommandsWritten()); - EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError()); - EXPECT_EQ(0, results[0]); - EXPECT_EQ(kSentinel, results[num_results]); } -TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) { +TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMGoodArgs) { const uint32 kBucketId = GLES2Implementation::kResultBucketId; const GLuint kProgramId = 123; const char kBad = 0x12; @@ -2097,20 +2047,20 @@ TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) { struct Cmds { cmd::SetBucketSize set_bucket_size1; - cmds::GetProgramInfoCHROMIUM get_program_info; + cmds::GetUniformBlocksCHROMIUM get_uniform_blocks; cmd::GetBucketStart get_bucket_start; cmd::SetToken set_token1; cmd::SetBucketSize set_bucket_size2; }; Cmds expected; expected.set_bucket_size1.Init(kBucketId, 0); - expected.get_program_info.Init(kProgramId, kBucketId); + expected.get_uniform_blocks.Init(kProgramId, kBucketId); expected.get_bucket_start.Init( kBucketId, result1.id, result1.offset, MaxTransferBufferSize(), mem1.id, mem1.offset); expected.set_token1.Init(GetNextToken()); expected.set_bucket_size2.Init(kBucketId, 0); - gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf); + gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), &size, &buf); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); EXPECT_EQ(sizeof(kString), static_cast<size_t>(size)); @@ -2118,7 +2068,7 @@ TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) { EXPECT_EQ(buf[sizeof(kString)], kBad); } -TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) { +TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMBadArgs) { const uint32 kBucketId = GLES2Implementation::kResultBucketId; const GLuint kProgramId = 123; GLsizei size = 0; @@ -2146,31 +2096,31 @@ TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) { // try bufsize not big enough. struct Cmds { cmd::SetBucketSize set_bucket_size1; - cmds::GetProgramInfoCHROMIUM get_program_info; + cmds::GetUniformBlocksCHROMIUM get_uniform_blocks; cmd::GetBucketStart get_bucket_start; cmd::SetToken set_token1; cmd::SetBucketSize set_bucket_size2; }; Cmds expected; expected.set_bucket_size1.Init(kBucketId, 0); - expected.get_program_info.Init(kProgramId, kBucketId); + expected.get_uniform_blocks.Init(kProgramId, kBucketId); expected.get_bucket_start.Init( kBucketId, result1.id, result1.offset, MaxTransferBufferSize(), mem1.id, mem1.offset); expected.set_token1.Init(GetNextToken()); expected.set_bucket_size2.Init(kBucketId, 0); - gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf); + gl_->GetUniformBlocksCHROMIUM(kProgramId, 6, &size, &buf); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError()); ClearCommands(); // try bad bufsize - gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf); + gl_->GetUniformBlocksCHROMIUM(kProgramId, -1, &size, &buf); EXPECT_TRUE(NoCommandsWritten()); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); ClearCommands(); // try no size ptr. - gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf); + gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), NULL, &buf); EXPECT_TRUE(NoCommandsWritten()); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); } @@ -2266,7 +2216,7 @@ static bool CheckRect( uint32 unpadded_row_size = 0; uint32 padded_row_size = 0; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, alignment, &size, &unpadded_row_size, + width, height, 1, format, type, alignment, &size, &unpadded_row_size, &padded_row_size)) { return false; } @@ -2372,15 +2322,15 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) { uint32 unpadded_row_size = 0; uint32 padded_row_size = 0; ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, + kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, &size, &unpadded_row_size, &padded_row_size)); const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2; ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, + kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment, &size, NULL, NULL)); uint32 half_size = 0; ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, + kWidth, kHeight / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, &half_size, NULL, NULL)); scoped_ptr<uint8[]> pixels(new uint8[size]); @@ -2481,7 +2431,7 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) { uint32 sub_2_high_size = 0; ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( - kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, + kSubImageWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, &sub_2_high_size, NULL, NULL)); ExpectedMemoryInfo mem1 = GetExpectedMemory(sub_2_high_size); @@ -2563,7 +2513,7 @@ TEST_F(GLES2ImplementationTest, SubImageUnpack) { uint32 src_size; ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( - kSrcWidth, kSrcSubImageY1, kFormat, kType, 8, &src_size, NULL, NULL)); + kSrcWidth, kSrcSubImageY1, 1, kFormat, kType, 8, &src_size, NULL, NULL)); scoped_ptr<uint8[]> src_pixels; src_pixels.reset(new uint8[src_size]); for (size_t i = 0; i < src_size; ++i) { @@ -2578,7 +2528,7 @@ TEST_F(GLES2ImplementationTest, SubImageUnpack) { uint32 unpadded_row_size; uint32 padded_row_size; ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( - kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, alignment, + kSrcSubImageWidth, kSrcSubImageHeight, 1, kFormat, kType, alignment, &size, &unpadded_row_size, &padded_row_size)); ASSERT_TRUE(size <= MaxTransferBufferSize()); ExpectedMemoryInfo mem = GetExpectedMemory(size); @@ -2729,36 +2679,183 @@ TEST_F(GLES2ImplementationTest, TextureInvalidArguments) { EXPECT_EQ(GL_INVALID_VALUE, CheckError()); } +TEST_F(GLES2ImplementationTest, TexImage3DSingleCommand) { + struct Cmds { + cmds::TexImage3D tex_image_3d; + }; + const GLenum kTarget = GL_TEXTURE_3D; + const GLint kLevel = 0; + const GLint kBorder = 0; + const GLenum kFormat = GL_RGB; + const GLenum kType = GL_UNSIGNED_BYTE; + const GLint kPixelStoreUnpackAlignment = 4; + const GLsizei kWidth = 3; + const GLsizei kDepth = 2; -// Binds can not be cached with bind_generates_resource = false because -// our id might not be valid. More specifically if you bind on contextA then -// delete on contextB the resource is still bound on contextA but GetInterger -// won't return an id. -TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) { - struct PNameValue { - GLenum pname; - GLint expected; + uint32 size = 0; + uint32 unpadded_row_size = 0; + uint32 padded_row_size = 0; + ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, 2, kDepth, kFormat, kType, kPixelStoreUnpackAlignment, + &size, &unpadded_row_size, &padded_row_size)); + // Makes sure we can just send over the data in one command. + const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size / kDepth; + ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment, + &size, NULL, NULL)); + + scoped_ptr<uint8[]> pixels(new uint8[size]); + for (uint32 ii = 0; ii < size; ++ii) { + pixels[ii] = static_cast<uint8>(ii); + } + + ExpectedMemoryInfo mem = GetExpectedMemory(size); + + Cmds expected; + expected.tex_image_3d.Init( + kTarget, kLevel, kFormat, kWidth, kHeight, kDepth, + kFormat, kType, mem.id, mem.offset); + + gl_->TexImage3D( + kTarget, kLevel, kFormat, kWidth, kHeight, kDepth, kBorder, + kFormat, kType, pixels.get()); + + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_TRUE(CheckRect( + kWidth, kHeight * kDepth, kFormat, kType, kPixelStoreUnpackAlignment, + false, reinterpret_cast<uint8*>(pixels.get()), mem.ptr)); +} + +TEST_F(GLES2ImplementationTest, TexImage3DViaTexSubImage3D) { + struct Cmds { + cmds::TexImage3D tex_image_3d; + cmds::TexSubImage3D tex_sub_image_3d1; + cmd::SetToken set_token; + cmds::TexSubImage3D tex_sub_image_3d2; }; - const PNameValue pairs[] = {{GL_TEXTURE_BINDING_2D, 1, }, - {GL_TEXTURE_BINDING_CUBE_MAP, 2, }, - {GL_TEXTURE_BINDING_EXTERNAL_OES, 3, }, - {GL_FRAMEBUFFER_BINDING, 4, }, - {GL_RENDERBUFFER_BINDING, 5, }, - {GL_ARRAY_BUFFER_BINDING, 6, }, - {GL_ELEMENT_ARRAY_BUFFER_BINDING, 7, }, }; - size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]); - for (size_t ii = 0; ii < num_pairs; ++ii) { - const PNameValue& pv = pairs[ii]; - GLint v = -1; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(cmds::GetIntegerv::Result)); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, - SizedResultHelper<GLuint>(pv.expected))) - .RetiresOnSaturation(); - gl_->GetIntegerv(pv.pname, &v); - EXPECT_EQ(pv.expected, v); + const GLenum kTarget = GL_TEXTURE_3D; + const GLint kLevel = 0; + const GLint kBorder = 0; + const GLenum kFormat = GL_RGB; + const GLenum kType = GL_UNSIGNED_BYTE; + const GLint kPixelStoreUnpackAlignment = 4; + const GLsizei kWidth = 3; + + uint32 size = 0; + uint32 unpadded_row_size = 0; + uint32 padded_row_size = 0; + ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, + &size, &unpadded_row_size, &padded_row_size)); + // Makes sure the data is more than one command can hold. + const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size + 3; + ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment, + &size, NULL, NULL)); + uint32 first_size = padded_row_size * (kHeight - 3); + uint32 second_size = + padded_row_size * 3 - (padded_row_size - unpadded_row_size); + EXPECT_EQ(size, first_size + second_size); + ExpectedMemoryInfo mem1 = GetExpectedMemory(first_size); + ExpectedMemoryInfo mem2 = GetExpectedMemory(second_size); + scoped_ptr<uint8[]> pixels(new uint8[size]); + for (uint32 ii = 0; ii < size; ++ii) { + pixels[ii] = static_cast<uint8>(ii); } + + Cmds expected; + expected.tex_image_3d.Init( + kTarget, kLevel, kFormat, kWidth, kHeight, 1, kFormat, kType, 0, 0); + expected.tex_sub_image_3d1.Init( + kTarget, kLevel, 0, 0, 0, kWidth, kHeight - 3, 1, kFormat, kType, + mem1.id, mem1.offset, GL_TRUE); + expected.tex_sub_image_3d2.Init( + kTarget, kLevel, 0, kHeight - 3, 0, kWidth, 3, 1, kFormat, kType, + mem2.id, mem2.offset, GL_TRUE); + expected.set_token.Init(GetNextToken()); + + gl_->TexImage3D( + kTarget, kLevel, kFormat, kWidth, kHeight, 1, kBorder, + kFormat, kType, pixels.get()); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +// Test TexSubImage3D with 4 writes +TEST_F(GLES2ImplementationTest, TexSubImage3D4Writes) { + struct Cmds { + cmds::TexSubImage3D tex_sub_image_3d1_1; + cmd::SetToken set_token1; + cmds::TexSubImage3D tex_sub_image_3d1_2; + cmd::SetToken set_token2; + cmds::TexSubImage3D tex_sub_image_3d2_1; + cmd::SetToken set_token3; + cmds::TexSubImage3D tex_sub_image_3d2_2; + }; + const GLenum kTarget = GL_TEXTURE_3D; + const GLint kLevel = 0; + const GLint kXOffset = 0; + const GLint kYOffset = 0; + const GLint kZOffset = 0; + const GLenum kFormat = GL_RGB; + const GLenum kType = GL_UNSIGNED_BYTE; + const GLint kPixelStoreUnpackAlignment = 4; + const GLsizei kWidth = 3; + const GLsizei kDepth = 2; + + uint32 size = 0; + uint32 unpadded_row_size = 0; + uint32 padded_row_size = 0; + ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, + &size, &unpadded_row_size, &padded_row_size)); + const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size + 2; + ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment, + &size, NULL, NULL)); + uint32 first_size = (kHeight - 2) * padded_row_size; + uint32 second_size = 2 * padded_row_size; + uint32 third_size = first_size; + uint32 fourth_size = second_size - (padded_row_size - unpadded_row_size); + EXPECT_EQ(size, first_size + second_size + third_size + fourth_size); + + scoped_ptr<uint8[]> pixels(new uint8[size]); + for (uint32 ii = 0; ii < size; ++ii) { + pixels[ii] = static_cast<uint8>(ii); + } + + ExpectedMemoryInfo mem1_1 = GetExpectedMemory(first_size); + ExpectedMemoryInfo mem1_2 = GetExpectedMemory(second_size); + ExpectedMemoryInfo mem2_1 = GetExpectedMemory(third_size); + ExpectedMemoryInfo mem2_2 = GetExpectedMemory(fourth_size); + + Cmds expected; + expected.tex_sub_image_3d1_1.Init( + kTarget, kLevel, kXOffset, kYOffset, kZOffset, + kWidth, kHeight - 2, 1, kFormat, kType, + mem1_1.id, mem1_1.offset, GL_FALSE); + expected.tex_sub_image_3d1_2.Init( + kTarget, kLevel, kXOffset, kYOffset + kHeight - 2, kZOffset, + kWidth, 2, 1, kFormat, kType, mem1_2.id, mem1_2.offset, GL_FALSE); + expected.tex_sub_image_3d2_1.Init( + kTarget, kLevel, kXOffset, kYOffset, kZOffset + 1, + kWidth, kHeight - 2, 1, kFormat, kType, + mem2_1.id, mem2_1.offset, GL_FALSE); + expected.tex_sub_image_3d2_2.Init( + kTarget, kLevel, kXOffset, kYOffset + kHeight - 2, kZOffset + 1, + kWidth, 2, 1, kFormat, kType, mem2_2.id, mem2_2.offset, GL_FALSE); + expected.set_token1.Init(GetNextToken()); + expected.set_token2.Init(GetNextToken()); + expected.set_token3.Init(GetNextToken()); + + gl_->TexSubImage3D( + kTarget, kLevel, kXOffset, kYOffset, kZOffset, kWidth, kHeight, kDepth, + kFormat, kType, pixels.get()); + + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + uint32 offset_to_last = first_size + second_size + third_size; + EXPECT_TRUE(CheckRect( + kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, false, + reinterpret_cast<uint8*>(pixels.get()) + offset_to_last, mem2_2.ptr)); } // glGen* Ids must not be reused until glDelete* commands have been @@ -3369,6 +3466,284 @@ TEST_F(GLES2ImplementationTest, LimitSizeAndOffsetTo32Bit) { EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str()); } +TEST_F(GLES2ImplementationTest, TraceBeginCHROMIUM) { + const uint32 kCategoryBucketId = GLES2Implementation::kResultBucketId; + const uint32 kNameBucketId = GLES2Implementation::kResultBucketId + 1; + const std::string category_name = "test category"; + const std::string trace_name = "test trace"; + const size_t kPaddedString1Size = + transfer_buffer_->RoundToAlignment(category_name.size() + 1); + const size_t kPaddedString2Size = + transfer_buffer_->RoundToAlignment(trace_name.size() + 1); + + gl_->TraceBeginCHROMIUM(category_name.c_str(), trace_name.c_str()); + EXPECT_EQ(GL_NO_ERROR, CheckError()); + + struct Cmds { + cmd::SetBucketSize category_size1; + cmd::SetBucketData category_data; + cmd::SetToken set_token1; + cmd::SetBucketSize name_size1; + cmd::SetBucketData name_data; + cmd::SetToken set_token2; + cmds::TraceBeginCHROMIUM trace_call_begin; + cmd::SetBucketSize category_size2; + cmd::SetBucketSize name_size2; + }; + + ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size); + ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size); + + ASSERT_STREQ(category_name.c_str(), reinterpret_cast<char*>(mem1.ptr)); + ASSERT_STREQ(trace_name.c_str(), reinterpret_cast<char*>(mem2.ptr)); + + Cmds expected; + expected.category_size1.Init(kCategoryBucketId, category_name.size() + 1); + expected.category_data.Init( + kCategoryBucketId, 0, category_name.size() + 1, mem1.id, mem1.offset); + expected.set_token1.Init(GetNextToken()); + expected.name_size1.Init(kNameBucketId, trace_name.size() + 1); + expected.name_data.Init( + kNameBucketId, 0, trace_name.size() + 1, mem2.id, mem2.offset); + expected.set_token2.Init(GetNextToken()); + expected.trace_call_begin.Init(kCategoryBucketId, kNameBucketId); + expected.category_size2.Init(kCategoryBucketId, 0); + expected.name_size2.Init(kNameBucketId, 0); + + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, AllowNestedTracesCHROMIUM) { + const std::string category1_name = "test category 1"; + const std::string trace1_name = "test trace 1"; + const std::string category2_name = "test category 2"; + const std::string trace2_name = "test trace 2"; + + gl_->TraceBeginCHROMIUM(category1_name.c_str(), trace1_name.c_str()); + EXPECT_EQ(GL_NO_ERROR, CheckError()); + + gl_->TraceBeginCHROMIUM(category2_name.c_str(), trace2_name.c_str()); + EXPECT_EQ(GL_NO_ERROR, CheckError()); + + gl_->TraceEndCHROMIUM(); + EXPECT_EQ(GL_NO_ERROR, CheckError()); + + gl_->TraceEndCHROMIUM(); + EXPECT_EQ(GL_NO_ERROR, CheckError()); + + // No more corresponding begin tracer marker should error. + gl_->TraceEndCHROMIUM(); + EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); +} + +TEST_F(GLES2ImplementationTest, IsEnabled) { + // If we use a valid enum, its state is cached on client side, so no command + // is actually generated, and this test will fail. + // TODO(zmo): it seems we never need the command. Maybe remove it. + GLenum kCap = 1; + struct Cmds { + cmds::IsEnabled cmd; + }; + + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result)); + expected.cmd.Init(kCap, result1.id, result1.offset); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) + .RetiresOnSaturation(); + + GLboolean result = gl_->IsEnabled(kCap); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_TRUE(result); +} + +TEST_F(GLES2ImplementationTest, ClientWaitSync) { + const GLuint client_sync_id = 36; + struct Cmds { + cmds::ClientWaitSync cmd; + }; + + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(cmds::ClientWaitSync::Result)); + const GLuint64 kTimeout = 0xABCDEF0123456789; + uint32_t v32_0 = 0, v32_1 = 0; + GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1); + expected.cmd.Init(client_sync_id, GL_SYNC_FLUSH_COMMANDS_BIT, + v32_0, v32_1, result1.id, result1.offset); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_CONDITION_SATISFIED))) + .RetiresOnSaturation(); + + GLenum result = gl_->ClientWaitSync( + reinterpret_cast<GLsync>(client_sync_id), GL_SYNC_FLUSH_COMMANDS_BIT, + kTimeout); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), result); +} + +TEST_F(GLES2ImplementationTest, WaitSync) { + const GLuint kClientSyncId = 36; + struct Cmds { + cmds::WaitSync cmd; + }; + Cmds expected; + const GLuint64 kTimeout = GL_TIMEOUT_IGNORED; + uint32_t v32_0 = 0, v32_1 = 0; + GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1); + expected.cmd.Init(kClientSyncId, 0, v32_0, v32_1); + + gl_->WaitSync(reinterpret_cast<GLsync>(kClientSyncId), 0, kTimeout); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, MapBufferRangeUnmapBufferWrite) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(1))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT); + EXPECT_TRUE(mem != nullptr); + + EXPECT_TRUE(gl_->UnmapBuffer(GL_ARRAY_BUFFER)); +} + +TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithInvalidateBit) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(1))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + GLsizeiptr kSize = 64; + void* mem = gl_->MapBufferRange( + GL_ARRAY_BUFFER, 10, kSize, + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT); + EXPECT_TRUE(mem != nullptr); + std::vector<int8_t> zero(kSize); + memset(&zero[0], 0, kSize); + EXPECT_EQ(0, memcmp(mem, &zero[0], kSize)); +} + +TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithGLError) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + // Return a result of 0 to indicate an GL error. + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(0))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT); + EXPECT_TRUE(mem == nullptr); +} + +TEST_F(GLES2ImplementationTest, MapBufferRangeUnmapBufferRead) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(1))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT); + EXPECT_TRUE(mem != nullptr); + + EXPECT_TRUE(gl_->UnmapBuffer(GL_ARRAY_BUFFER)); +} + +TEST_F(GLES2ImplementationTest, MapBufferRangeReadWithGLError) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + // Return a result of 0 to indicate an GL error. + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(0))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT); + EXPECT_TRUE(mem == nullptr); +} + +TEST_F(GLES2ImplementationTest, UnmapBufferFails) { + // No bound buffer. + EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER)); + EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + // Buffer is unmapped. + EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER)); + EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); +} + +TEST_F(GLES2ImplementationTest, BufferDataUnmapsDataStore) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(1))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT); + EXPECT_TRUE(mem != nullptr); + + std::vector<uint8_t> data(16); + // BufferData unmaps the data store. + gl_->BufferData(GL_ARRAY_BUFFER, 16, &data[0], GL_STREAM_DRAW); + + EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER)); + EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); +} + +TEST_F(GLES2ImplementationTest, DeleteBuffersUnmapsDataStore) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(1))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT); + EXPECT_TRUE(mem != nullptr); + + std::vector<uint8_t> data(16); + // DeleteBuffers unmaps the data store. + gl_->DeleteBuffers(1, &kBufferId); + + EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER)); + EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); +} + TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) { ContextInitOptions init_options; init_options.lose_context_when_out_of_memory = true; diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 74a438c0f6b..ae9b5e15aa9 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -23,7 +23,7 @@ TEST_F(GLES2ImplementationTest, AttachShader) { gl_->AttachShader(1, 2); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -// TODO: Implement unit test for BindAttribLocation +// TODO(zmo): Implement unit test for BindAttribLocation TEST_F(GLES2ImplementationTest, BindBuffer) { struct Cmds { @@ -39,6 +39,28 @@ TEST_F(GLES2ImplementationTest, BindBuffer) { EXPECT_TRUE(NoCommandsWritten()); } +TEST_F(GLES2ImplementationTest, BindBufferBase) { + struct Cmds { + cmds::BindBufferBase cmd; + }; + Cmds expected; + expected.cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, 3); + + gl_->BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2, 3); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, BindBufferRange) { + struct Cmds { + cmds::BindBufferRange cmd; + }; + Cmds expected; + expected.cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, 3, 4, 4); + + gl_->BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 2, 3, 4, 4); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, BindFramebuffer) { struct Cmds { cmds::BindFramebuffer cmd; @@ -67,6 +89,28 @@ TEST_F(GLES2ImplementationTest, BindRenderbuffer) { EXPECT_TRUE(NoCommandsWritten()); } +TEST_F(GLES2ImplementationTest, BindSampler) { + struct Cmds { + cmds::BindSampler cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2); + + gl_->BindSampler(1, 2); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, BindTransformFeedback) { + struct Cmds { + cmds::BindTransformFeedback cmd; + }; + Cmds expected; + expected.cmd.Init(GL_TRANSFORM_FEEDBACK, 2); + + gl_->BindTransformFeedback(GL_TRANSFORM_FEEDBACK, 2); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, BlendColor) { struct Cmds { cmds::BlendColor cmd; @@ -130,13 +174,13 @@ TEST_F(GLES2ImplementationTest, CheckFramebufferStatus) { Cmds expected; ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(cmds::CheckFramebufferStatus::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + expected.cmd.Init(GL_FRAMEBUFFER, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32_t(1))) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) .RetiresOnSaturation(); - GLboolean result = gl_->CheckFramebufferStatus(1); + GLboolean result = gl_->CheckFramebufferStatus(GL_FRAMEBUFFER); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); EXPECT_TRUE(result); } @@ -152,6 +196,65 @@ TEST_F(GLES2ImplementationTest, Clear) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, ClearBufferfi) { + struct Cmds { + cmds::ClearBufferfi cmd; + }; + Cmds expected; + expected.cmd.Init(GL_COLOR, 2, 3, 4); + + gl_->ClearBufferfi(GL_COLOR, 2, 3, 4); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, ClearBufferfv) { + GLfloat data[4] = {0}; + struct Cmds { + cmds::ClearBufferfvImmediate cmd; + GLfloat data[4]; + }; + + for (int jj = 0; jj < 4; ++jj) { + data[jj] = static_cast<GLfloat>(jj); + } + Cmds expected; + expected.cmd.Init(GL_COLOR, 2, &data[0]); + gl_->ClearBufferfv(GL_COLOR, 2, &data[0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, ClearBufferiv) { + GLint data[4] = {0}; + struct Cmds { + cmds::ClearBufferivImmediate cmd; + GLint data[4]; + }; + + for (int jj = 0; jj < 4; ++jj) { + data[jj] = static_cast<GLint>(jj); + } + Cmds expected; + expected.cmd.Init(GL_COLOR, 2, &data[0]); + gl_->ClearBufferiv(GL_COLOR, 2, &data[0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, ClearBufferuiv) { + GLuint data[4] = {0}; + struct Cmds { + cmds::ClearBufferuivImmediate cmd; + GLuint data[4]; + }; + + for (int jj = 0; jj < 4; ++jj) { + data[jj] = static_cast<GLuint>(jj); + } + Cmds expected; + expected.cmd.Init(GL_COLOR, 2, &data[0]); + gl_->ClearBufferuiv(GL_COLOR, 2, &data[0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, ClearColor) { struct Cmds { cmds::ClearColor cmd; @@ -184,6 +287,7 @@ TEST_F(GLES2ImplementationTest, ClearStencil) { gl_->ClearStencil(1); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +// TODO(zmo): Implement unit test for ClientWaitSync TEST_F(GLES2ImplementationTest, ColorMask) { struct Cmds { @@ -206,8 +310,21 @@ TEST_F(GLES2ImplementationTest, CompileShader) { gl_->CompileShader(1); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -// TODO: Implement unit test for CompressedTexImage2D -// TODO: Implement unit test for CompressedTexSubImage2D +// TODO(zmo): Implement unit test for CompressedTexImage2D +// TODO(zmo): Implement unit test for CompressedTexSubImage2D +// TODO(zmo): Implement unit test for CompressedTexImage3D +// TODO(zmo): Implement unit test for CompressedTexSubImage3D + +TEST_F(GLES2ImplementationTest, CopyBufferSubData) { + struct Cmds { + cmds::CopyBufferSubData cmd; + }; + Cmds expected; + expected.cmd.Init(GL_ARRAY_BUFFER, GL_ARRAY_BUFFER, 3, 4, 5); + + gl_->CopyBufferSubData(GL_ARRAY_BUFFER, GL_ARRAY_BUFFER, 3, 4, 5); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} TEST_F(GLES2ImplementationTest, CopyTexImage2D) { struct Cmds { @@ -237,6 +354,17 @@ TEST_F(GLES2ImplementationTest, CopyTexSubImage2D) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, CopyTexSubImage3D) { + struct Cmds { + cmds::CopyTexSubImage3D cmd; + }; + Cmds expected; + expected.cmd.Init(GL_TEXTURE_3D, 2, 3, 4, 5, 6, 7, 8, 9); + + gl_->CopyTexSubImage3D(GL_TEXTURE_3D, 2, 3, 4, 5, 6, 7, 8, 9); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, CullFace) { struct Cmds { cmds::CullFace cmd; @@ -301,6 +429,31 @@ TEST_F(GLES2ImplementationTest, DeleteRenderbuffers) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, DeleteSamplers) { + GLuint ids[2] = {kSamplersStartId, kSamplersStartId + 1}; + struct Cmds { + cmds::DeleteSamplersImmediate del; + GLuint data[2]; + }; + Cmds expected; + expected.del.Init(arraysize(ids), &ids[0]); + expected.data[0] = kSamplersStartId; + expected.data[1] = kSamplersStartId + 1; + gl_->DeleteSamplers(arraysize(ids), &ids[0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, DeleteSync) { + struct Cmds { + cmds::DeleteSync cmd; + }; + Cmds expected; + expected.cmd.Init(1); + + gl_->DeleteSync(reinterpret_cast<GLsync>(1)); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, DeleteShader) { struct Cmds { cmds::DeleteShader cmd; @@ -326,6 +479,20 @@ TEST_F(GLES2ImplementationTest, DeleteTextures) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, DeleteTransformFeedbacks) { + GLuint ids[2] = {kTransformFeedbacksStartId, kTransformFeedbacksStartId + 1}; + struct Cmds { + cmds::DeleteTransformFeedbacksImmediate del; + GLuint data[2]; + }; + Cmds expected; + expected.del.Init(arraysize(ids), &ids[0]); + expected.data[0] = kTransformFeedbacksStartId; + expected.data[1] = kTransformFeedbacksStartId + 1; + gl_->DeleteTransformFeedbacks(arraysize(ids), &ids[0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, DepthFunc) { struct Cmds { cmds::DepthFunc cmd; @@ -391,6 +558,7 @@ TEST_F(GLES2ImplementationTest, DrawArrays) { gl_->DrawArrays(GL_POINTS, 2, 3); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +// TODO(zmo): Implement unit test for DrawRangeElements TEST_F(GLES2ImplementationTest, EnableVertexAttribArray) { struct Cmds { @@ -445,6 +613,17 @@ TEST_F(GLES2ImplementationTest, FramebufferTexture2DInvalidConstantArg4) { EXPECT_EQ(GL_INVALID_VALUE, CheckError()); } +TEST_F(GLES2ImplementationTest, FramebufferTextureLayer) { + struct Cmds { + cmds::FramebufferTextureLayer cmd; + }; + Cmds expected; + expected.cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 3, 4, 5); + + gl_->FramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 3, 4, 5); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, FrontFace) { struct Cmds { cmds::FrontFace cmd; @@ -521,6 +700,24 @@ TEST_F(GLES2ImplementationTest, GenRenderbuffers) { EXPECT_EQ(kRenderbuffersStartId + 1, ids[1]); } +TEST_F(GLES2ImplementationTest, GenSamplers) { + GLuint ids[2] = { + 0, + }; + struct Cmds { + cmds::GenSamplersImmediate gen; + GLuint data[2]; + }; + Cmds expected; + expected.gen.Init(arraysize(ids), &ids[0]); + expected.data[0] = kSamplersStartId; + expected.data[1] = kSamplersStartId + 1; + gl_->GenSamplers(arraysize(ids), &ids[0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(kSamplersStartId, ids[0]); + EXPECT_EQ(kSamplersStartId + 1, ids[1]); +} + TEST_F(GLES2ImplementationTest, GenTextures) { GLuint ids[2] = { 0, @@ -538,225 +735,429 @@ TEST_F(GLES2ImplementationTest, GenTextures) { EXPECT_EQ(kTexturesStartId, ids[0]); EXPECT_EQ(kTexturesStartId + 1, ids[1]); } -// TODO: Implement unit test for GetActiveAttrib -// TODO: Implement unit test for GetActiveUniform -// TODO: Implement unit test for GetAttachedShaders -// TODO: Implement unit test for GetAttribLocation + +TEST_F(GLES2ImplementationTest, GenTransformFeedbacks) { + GLuint ids[2] = { + 0, + }; + struct Cmds { + cmds::GenTransformFeedbacksImmediate gen; + GLuint data[2]; + }; + Cmds expected; + expected.gen.Init(arraysize(ids), &ids[0]); + expected.data[0] = kTransformFeedbacksStartId; + expected.data[1] = kTransformFeedbacksStartId + 1; + gl_->GenTransformFeedbacks(arraysize(ids), &ids[0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(kTransformFeedbacksStartId, ids[0]); + EXPECT_EQ(kTransformFeedbacksStartId + 1, ids[1]); +} +// TODO(zmo): Implement unit test for GetActiveAttrib +// TODO(zmo): Implement unit test for GetActiveUniform +// TODO(zmo): Implement unit test for GetActiveUniformBlockiv +// TODO(zmo): Implement unit test for GetActiveUniformBlockName +// TODO(zmo): Implement unit test for GetActiveUniformsiv +// TODO(zmo): Implement unit test for GetAttachedShaders +// TODO(zmo): Implement unit test for GetAttribLocation TEST_F(GLES2ImplementationTest, GetBooleanv) { struct Cmds { cmds::GetBooleanv cmd; }; - typedef cmds::GetBooleanv::Result Result; - Result::Type result = 0; + typedef cmds::GetBooleanv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetBooleanv(123, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); } TEST_F(GLES2ImplementationTest, GetBufferParameteriv) { struct Cmds { cmds::GetBufferParameteriv cmd; }; - typedef cmds::GetBufferParameteriv::Result Result; - Result::Type result = 0; + typedef cmds::GetBufferParameteriv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, GL_BUFFER_SIZE, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetBufferParameteriv(123, GL_BUFFER_SIZE, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); } TEST_F(GLES2ImplementationTest, GetFloatv) { struct Cmds { cmds::GetFloatv cmd; }; - typedef cmds::GetFloatv::Result Result; - Result::Type result = 0; + typedef cmds::GetFloatv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetFloatv(123, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); } +// TODO(zmo): Implement unit test for GetFragDataLocation TEST_F(GLES2ImplementationTest, GetFramebufferAttachmentParameteriv) { struct Cmds { cmds::GetFramebufferAttachmentParameteriv cmd; }; - typedef cmds::GetFramebufferAttachmentParameteriv::Result Result; - Result::Type result = 0; + typedef cmds::GetFramebufferAttachmentParameteriv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetFramebufferAttachmentParameteriv( 123, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); +} + +TEST_F(GLES2ImplementationTest, GetInteger64v) { + struct Cmds { + cmds::GetInteger64v cmd; + }; + typedef cmds::GetInteger64v::Result::Type ResultType; + ResultType result = 0; + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); + expected.cmd.Init(123, result1.id, result1.offset); + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) + .RetiresOnSaturation(); + gl_->GetInteger64v(123, &result); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<ResultType>(1), result); +} + +TEST_F(GLES2ImplementationTest, GetIntegeri_v) { + struct Cmds { + cmds::GetIntegeri_v cmd; + }; + typedef cmds::GetIntegeri_v::Result::Type ResultType; + ResultType result = 0; + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); + expected.cmd.Init(123, 2, result1.id, result1.offset); + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) + .RetiresOnSaturation(); + gl_->GetIntegeri_v(123, 2, &result); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<ResultType>(1), result); +} + +TEST_F(GLES2ImplementationTest, GetInteger64i_v) { + struct Cmds { + cmds::GetInteger64i_v cmd; + }; + typedef cmds::GetInteger64i_v::Result::Type ResultType; + ResultType result = 0; + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); + expected.cmd.Init(123, 2, result1.id, result1.offset); + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) + .RetiresOnSaturation(); + gl_->GetInteger64i_v(123, 2, &result); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<ResultType>(1), result); } TEST_F(GLES2ImplementationTest, GetIntegerv) { struct Cmds { cmds::GetIntegerv cmd; }; - typedef cmds::GetIntegerv::Result Result; - Result::Type result = 0; + typedef cmds::GetIntegerv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetIntegerv(123, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); +} + +TEST_F(GLES2ImplementationTest, GetInternalformativ) { + struct Cmds { + cmds::GetInternalformativ cmd; + }; + typedef cmds::GetInternalformativ::Result::Type ResultType; + ResultType result = 0; + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); + expected.cmd.Init(123, GL_RGBA4, GL_NUM_SAMPLE_COUNTS, 4, result1.id, + result1.offset); + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) + .RetiresOnSaturation(); + gl_->GetInternalformativ(123, GL_RGBA4, GL_NUM_SAMPLE_COUNTS, 4, &result); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<ResultType>(1), result); } TEST_F(GLES2ImplementationTest, GetProgramiv) { struct Cmds { cmds::GetProgramiv cmd; }; - typedef cmds::GetProgramiv::Result Result; - Result::Type result = 0; + typedef cmds::GetProgramiv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, GL_DELETE_STATUS, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetProgramiv(123, GL_DELETE_STATUS, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); } -// TODO: Implement unit test for GetProgramInfoLog +// TODO(zmo): Implement unit test for GetProgramInfoLog TEST_F(GLES2ImplementationTest, GetRenderbufferParameteriv) { struct Cmds { cmds::GetRenderbufferParameteriv cmd; }; - typedef cmds::GetRenderbufferParameteriv::Result Result; - Result::Type result = 0; + typedef cmds::GetRenderbufferParameteriv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, GL_RENDERBUFFER_RED_SIZE, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetRenderbufferParameteriv(123, GL_RENDERBUFFER_RED_SIZE, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); +} + +TEST_F(GLES2ImplementationTest, GetSamplerParameterfv) { + struct Cmds { + cmds::GetSamplerParameterfv cmd; + }; + typedef cmds::GetSamplerParameterfv::Result::Type ResultType; + ResultType result = 0; + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); + expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, result1.id, result1.offset); + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) + .RetiresOnSaturation(); + gl_->GetSamplerParameterfv(123, GL_TEXTURE_MAG_FILTER, &result); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<ResultType>(1), result); +} + +TEST_F(GLES2ImplementationTest, GetSamplerParameteriv) { + struct Cmds { + cmds::GetSamplerParameteriv cmd; + }; + typedef cmds::GetSamplerParameteriv::Result::Type ResultType; + ResultType result = 0; + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); + expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, result1.id, result1.offset); + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) + .RetiresOnSaturation(); + gl_->GetSamplerParameteriv(123, GL_TEXTURE_MAG_FILTER, &result); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<ResultType>(1), result); } TEST_F(GLES2ImplementationTest, GetShaderiv) { struct Cmds { cmds::GetShaderiv cmd; }; - typedef cmds::GetShaderiv::Result Result; - Result::Type result = 0; + typedef cmds::GetShaderiv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, GL_SHADER_TYPE, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetShaderiv(123, GL_SHADER_TYPE, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); +} +// TODO(zmo): Implement unit test for GetShaderInfoLog +// TODO(zmo): Implement unit test for GetShaderPrecisionFormat + +TEST_F(GLES2ImplementationTest, GetSynciv) { + struct Cmds { + cmds::GetSynciv cmd; + }; + typedef cmds::GetSynciv::Result::Type ResultType; + ResultType result = 0; + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); + expected.cmd.Init(123, GL_SYNC_STATUS, result1.id, result1.offset); + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) + .RetiresOnSaturation(); + gl_->GetSynciv(reinterpret_cast<GLsync>(123), GL_SYNC_STATUS, 3, nullptr, + &result); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<ResultType>(1), result); } -// TODO: Implement unit test for GetShaderInfoLog -// TODO: Implement unit test for GetShaderPrecisionFormat TEST_F(GLES2ImplementationTest, GetTexParameterfv) { struct Cmds { cmds::GetTexParameterfv cmd; }; - typedef cmds::GetTexParameterfv::Result Result; - Result::Type result = 0; + typedef cmds::GetTexParameterfv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetTexParameterfv(123, GL_TEXTURE_MAG_FILTER, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); } TEST_F(GLES2ImplementationTest, GetTexParameteriv) { struct Cmds { cmds::GetTexParameteriv cmd; }; - typedef cmds::GetTexParameteriv::Result Result; - Result::Type result = 0; + typedef cmds::GetTexParameteriv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetTexParameteriv(123, GL_TEXTURE_MAG_FILTER, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); } -// TODO: Implement unit test for GetUniformfv -// TODO: Implement unit test for GetUniformiv -// TODO: Implement unit test for GetUniformLocation +// TODO(zmo): Implement unit test for GetTransformFeedbackVarying +// TODO(zmo): Implement unit test for GetUniformBlockIndex +// TODO(zmo): Implement unit test for GetUniformfv +// TODO(zmo): Implement unit test for GetUniformiv +// TODO(zmo): Implement unit test for GetUniformuiv +// TODO(zmo): Implement unit test for GetUniformIndices +// TODO(zmo): Implement unit test for GetUniformLocation TEST_F(GLES2ImplementationTest, GetVertexAttribfv) { struct Cmds { cmds::GetVertexAttribfv cmd; }; - typedef cmds::GetVertexAttribfv::Result Result; - Result::Type result = 0; + typedef cmds::GetVertexAttribfv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetVertexAttribfv(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); } TEST_F(GLES2ImplementationTest, GetVertexAttribiv) { struct Cmds { cmds::GetVertexAttribiv cmd; }; - typedef cmds::GetVertexAttribiv::Result Result; - Result::Type result = 0; + typedef cmds::GetVertexAttribiv::Result::Type ResultType; + ResultType result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); expected.cmd.Init(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) .RetiresOnSaturation(); gl_->GetVertexAttribiv(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_EQ(static_cast<Result::Type>(1), result); + EXPECT_EQ(static_cast<ResultType>(1), result); +} + +TEST_F(GLES2ImplementationTest, GetVertexAttribIiv) { + struct Cmds { + cmds::GetVertexAttribIiv cmd; + }; + typedef cmds::GetVertexAttribIiv::Result::Type ResultType; + ResultType result = 0; + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); + expected.cmd.Init(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, result1.id, + result1.offset); + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) + .RetiresOnSaturation(); + gl_->GetVertexAttribIiv(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &result); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<ResultType>(1), result); +} + +TEST_F(GLES2ImplementationTest, GetVertexAttribIuiv) { + struct Cmds { + cmds::GetVertexAttribIuiv cmd; + }; + typedef cmds::GetVertexAttribIuiv::Result::Type ResultType; + ResultType result = 0; + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType)); + expected.cmd.Init(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, result1.id, + result1.offset); + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, SizedResultHelper<ResultType>(1))) + .RetiresOnSaturation(); + gl_->GetVertexAttribIuiv(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &result); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(static_cast<ResultType>(1), result); } TEST_F(GLES2ImplementationTest, Hint) { @@ -770,40 +1171,57 @@ TEST_F(GLES2ImplementationTest, Hint) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -TEST_F(GLES2ImplementationTest, IsBuffer) { +TEST_F(GLES2ImplementationTest, InvalidateFramebuffer) { + GLenum data[2][1] = {{0}}; struct Cmds { - cmds::IsBuffer cmd; + cmds::InvalidateFramebufferImmediate cmd; + GLenum data[2][1]; }; Cmds expected; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(cmds::IsBuffer::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 1; ++jj) { + data[ii][jj] = static_cast<GLenum>(ii * 1 + jj); + } + } + expected.cmd.Init(GL_FRAMEBUFFER, 2, &data[0][0]); + gl_->InvalidateFramebuffer(GL_FRAMEBUFFER, 2, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32_t(1))) - .RetiresOnSaturation(); +TEST_F(GLES2ImplementationTest, InvalidateSubFramebuffer) { + GLenum data[2][1] = {{0}}; + struct Cmds { + cmds::InvalidateSubFramebufferImmediate cmd; + GLenum data[2][1]; + }; - GLboolean result = gl_->IsBuffer(1); + Cmds expected; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 1; ++jj) { + data[ii][jj] = static_cast<GLenum>(ii * 1 + jj); + } + } + expected.cmd.Init(GL_FRAMEBUFFER, 2, &data[0][0], 4, 5, 6, 7); + gl_->InvalidateSubFramebuffer(GL_FRAMEBUFFER, 2, &data[0][0], 4, 5, 6, 7); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); - EXPECT_TRUE(result); } -TEST_F(GLES2ImplementationTest, IsEnabled) { +TEST_F(GLES2ImplementationTest, IsBuffer) { struct Cmds { - cmds::IsEnabled cmd; + cmds::IsBuffer cmd; }; Cmds expected; ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result)); + GetExpectedResultMemory(sizeof(cmds::IsBuffer::Result)); expected.cmd.Init(1, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32_t(1))) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) .RetiresOnSaturation(); - GLboolean result = gl_->IsEnabled(1); + GLboolean result = gl_->IsBuffer(1); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); EXPECT_TRUE(result); } @@ -819,7 +1237,7 @@ TEST_F(GLES2ImplementationTest, IsFramebuffer) { expected.cmd.Init(1, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32_t(1))) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) .RetiresOnSaturation(); GLboolean result = gl_->IsFramebuffer(1); @@ -838,7 +1256,7 @@ TEST_F(GLES2ImplementationTest, IsProgram) { expected.cmd.Init(1, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32_t(1))) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) .RetiresOnSaturation(); GLboolean result = gl_->IsProgram(1); @@ -857,7 +1275,7 @@ TEST_F(GLES2ImplementationTest, IsRenderbuffer) { expected.cmd.Init(1, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32_t(1))) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) .RetiresOnSaturation(); GLboolean result = gl_->IsRenderbuffer(1); @@ -865,6 +1283,25 @@ TEST_F(GLES2ImplementationTest, IsRenderbuffer) { EXPECT_TRUE(result); } +TEST_F(GLES2ImplementationTest, IsSampler) { + struct Cmds { + cmds::IsSampler cmd; + }; + + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(cmds::IsSampler::Result)); + expected.cmd.Init(1, result1.id, result1.offset); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) + .RetiresOnSaturation(); + + GLboolean result = gl_->IsSampler(1); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_TRUE(result); +} + TEST_F(GLES2ImplementationTest, IsShader) { struct Cmds { cmds::IsShader cmd; @@ -876,7 +1313,7 @@ TEST_F(GLES2ImplementationTest, IsShader) { expected.cmd.Init(1, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32_t(1))) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) .RetiresOnSaturation(); GLboolean result = gl_->IsShader(1); @@ -884,6 +1321,25 @@ TEST_F(GLES2ImplementationTest, IsShader) { EXPECT_TRUE(result); } +TEST_F(GLES2ImplementationTest, IsSync) { + struct Cmds { + cmds::IsSync cmd; + }; + + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(cmds::IsSync::Result)); + expected.cmd.Init(1, result1.id, result1.offset); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) + .RetiresOnSaturation(); + + GLboolean result = gl_->IsSync(reinterpret_cast<GLsync>(1)); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_TRUE(result); +} + TEST_F(GLES2ImplementationTest, IsTexture) { struct Cmds { cmds::IsTexture cmd; @@ -895,7 +1351,7 @@ TEST_F(GLES2ImplementationTest, IsTexture) { expected.cmd.Init(1, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32_t(1))) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) .RetiresOnSaturation(); GLboolean result = gl_->IsTexture(1); @@ -903,6 +1359,25 @@ TEST_F(GLES2ImplementationTest, IsTexture) { EXPECT_TRUE(result); } +TEST_F(GLES2ImplementationTest, IsTransformFeedback) { + struct Cmds { + cmds::IsTransformFeedback cmd; + }; + + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(cmds::IsTransformFeedback::Result)); + expected.cmd.Init(1, result1.id, result1.offset); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) + .RetiresOnSaturation(); + + GLboolean result = gl_->IsTransformFeedback(1); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_TRUE(result); +} + TEST_F(GLES2ImplementationTest, LineWidth) { struct Cmds { cmds::LineWidth cmd; @@ -925,6 +1400,17 @@ TEST_F(GLES2ImplementationTest, LinkProgram) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, PauseTransformFeedback) { + struct Cmds { + cmds::PauseTransformFeedback cmd; + }; + Cmds expected; + expected.cmd.Init(); + + gl_->PauseTransformFeedback(); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, PixelStorei) { struct Cmds { cmds::PixelStorei cmd; @@ -947,6 +1433,17 @@ TEST_F(GLES2ImplementationTest, PolygonOffset) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, ReadBuffer) { + struct Cmds { + cmds::ReadBuffer cmd; + }; + Cmds expected; + expected.cmd.Init(1); + + gl_->ReadBuffer(1); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, ReleaseShaderCompiler) { struct Cmds { cmds::ReleaseShaderCompiler cmd; @@ -969,6 +1466,17 @@ TEST_F(GLES2ImplementationTest, RenderbufferStorage) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, ResumeTransformFeedback) { + struct Cmds { + cmds::ResumeTransformFeedback cmd; + }; + Cmds expected; + expected.cmd.Init(); + + gl_->ResumeTransformFeedback(); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, SampleCoverage) { struct Cmds { cmds::SampleCoverage cmd; @@ -980,6 +1488,60 @@ TEST_F(GLES2ImplementationTest, SampleCoverage) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, SamplerParameterf) { + struct Cmds { + cmds::SamplerParameterf cmd; + }; + Cmds expected; + expected.cmd.Init(1, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + gl_->SamplerParameterf(1, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, SamplerParameterfv) { + GLfloat data[1] = {0}; + struct Cmds { + cmds::SamplerParameterfvImmediate cmd; + GLfloat data[1]; + }; + + for (int jj = 0; jj < 1; ++jj) { + data[jj] = static_cast<GLfloat>(jj); + } + Cmds expected; + expected.cmd.Init(1, GL_TEXTURE_MAG_FILTER, &data[0]); + gl_->SamplerParameterfv(1, GL_TEXTURE_MAG_FILTER, &data[0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, SamplerParameteri) { + struct Cmds { + cmds::SamplerParameteri cmd; + }; + Cmds expected; + expected.cmd.Init(1, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + gl_->SamplerParameteri(1, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, SamplerParameteriv) { + GLint data[1] = {0}; + struct Cmds { + cmds::SamplerParameterivImmediate cmd; + GLint data[1]; + }; + + for (int jj = 0; jj < 1; ++jj) { + data[jj] = static_cast<GLint>(jj); + } + Cmds expected; + expected.cmd.Init(1, GL_TEXTURE_MAG_FILTER, &data[0]); + gl_->SamplerParameteriv(1, GL_TEXTURE_MAG_FILTER, &data[0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, Scissor) { struct Cmds { cmds::Scissor cmd; @@ -991,6 +1553,93 @@ TEST_F(GLES2ImplementationTest, Scissor) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, ShaderSource) { + const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const char* kString1 = "happy"; + const char* kString2 = "ending"; + const size_t kString1Size = ::strlen(kString1) + 1; + const size_t kString2Size = ::strlen(kString2) + 1; + const size_t kHeaderSize = sizeof(GLint) * 3; + const size_t kSourceSize = kHeaderSize + kString1Size + kString2Size; + const size_t kPaddedHeaderSize = + transfer_buffer_->RoundToAlignment(kHeaderSize); + const size_t kPaddedString1Size = + transfer_buffer_->RoundToAlignment(kString1Size); + const size_t kPaddedString2Size = + transfer_buffer_->RoundToAlignment(kString2Size); + struct Cmds { + cmd::SetBucketSize set_bucket_size; + cmd::SetBucketData set_bucket_header; + cmd::SetToken set_token1; + cmd::SetBucketData set_bucket_data1; + cmd::SetToken set_token2; + cmd::SetBucketData set_bucket_data2; + cmd::SetToken set_token3; + cmds::ShaderSourceBucket cmd_bucket; + cmd::SetBucketSize clear_bucket_size; + }; + + ExpectedMemoryInfo mem0 = GetExpectedMemory(kPaddedHeaderSize); + ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size); + ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size); + + Cmds expected; + expected.set_bucket_size.Init(kBucketId, kSourceSize); + expected.set_bucket_header.Init(kBucketId, 0, kHeaderSize, mem0.id, + mem0.offset); + expected.set_token1.Init(GetNextToken()); + expected.set_bucket_data1.Init(kBucketId, kHeaderSize, kString1Size, mem1.id, + mem1.offset); + expected.set_token2.Init(GetNextToken()); + expected.set_bucket_data2.Init(kBucketId, kHeaderSize + kString1Size, + kString2Size, mem2.id, mem2.offset); + expected.set_token3.Init(GetNextToken()); + expected.cmd_bucket.Init(1, kBucketId); + expected.clear_bucket_size.Init(kBucketId, 0); + const char* kStrings[] = {kString1, kString2}; + gl_->ShaderSource(1, 2, kStrings, NULL); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, ShaderSourceWithLength) { + const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const char* kString = "foobar******"; + const size_t kStringSize = 6; // We only need "foobar". + const size_t kHeaderSize = sizeof(GLint) * 2; + const size_t kSourceSize = kHeaderSize + kStringSize + 1; + const size_t kPaddedHeaderSize = + transfer_buffer_->RoundToAlignment(kHeaderSize); + const size_t kPaddedStringSize = + transfer_buffer_->RoundToAlignment(kStringSize + 1); + struct Cmds { + cmd::SetBucketSize set_bucket_size; + cmd::SetBucketData set_bucket_header; + cmd::SetToken set_token1; + cmd::SetBucketData set_bucket_data; + cmd::SetToken set_token2; + cmds::ShaderSourceBucket shader_source_bucket; + cmd::SetBucketSize clear_bucket_size; + }; + + ExpectedMemoryInfo mem0 = GetExpectedMemory(kPaddedHeaderSize); + ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedStringSize); + + Cmds expected; + expected.set_bucket_size.Init(kBucketId, kSourceSize); + expected.set_bucket_header.Init(kBucketId, 0, kHeaderSize, mem0.id, + mem0.offset); + expected.set_token1.Init(GetNextToken()); + expected.set_bucket_data.Init(kBucketId, kHeaderSize, kStringSize + 1, + mem1.id, mem1.offset); + expected.set_token2.Init(GetNextToken()); + expected.shader_source_bucket.Init(1, kBucketId); + expected.clear_bucket_size.Init(kBucketId, 0); + const char* kStrings[] = {kString}; + const GLint kLength[] = {kStringSize}; + gl_->ShaderSource(1, 1, kStrings, kLength); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, StencilFunc) { struct Cmds { cmds::StencilFunc cmd; @@ -1111,6 +1760,65 @@ TEST_F(GLES2ImplementationTest, TexParameteriv) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, TexStorage3D) { + struct Cmds { + cmds::TexStorage3D cmd; + }; + Cmds expected; + expected.cmd.Init(GL_TEXTURE_3D, 2, GL_RGB565, 4, 5, 6); + + gl_->TexStorage3D(GL_TEXTURE_3D, 2, GL_RGB565, 4, 5, 6); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, TransformFeedbackVaryings) { + const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const char* kString1 = "happy"; + const char* kString2 = "ending"; + const size_t kString1Size = ::strlen(kString1) + 1; + const size_t kString2Size = ::strlen(kString2) + 1; + const size_t kHeaderSize = sizeof(GLint) * 3; + const size_t kSourceSize = kHeaderSize + kString1Size + kString2Size; + const size_t kPaddedHeaderSize = + transfer_buffer_->RoundToAlignment(kHeaderSize); + const size_t kPaddedString1Size = + transfer_buffer_->RoundToAlignment(kString1Size); + const size_t kPaddedString2Size = + transfer_buffer_->RoundToAlignment(kString2Size); + struct Cmds { + cmd::SetBucketSize set_bucket_size; + cmd::SetBucketData set_bucket_header; + cmd::SetToken set_token1; + cmd::SetBucketData set_bucket_data1; + cmd::SetToken set_token2; + cmd::SetBucketData set_bucket_data2; + cmd::SetToken set_token3; + cmds::TransformFeedbackVaryingsBucket cmd_bucket; + cmd::SetBucketSize clear_bucket_size; + }; + + ExpectedMemoryInfo mem0 = GetExpectedMemory(kPaddedHeaderSize); + ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size); + ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size); + + Cmds expected; + expected.set_bucket_size.Init(kBucketId, kSourceSize); + expected.set_bucket_header.Init(kBucketId, 0, kHeaderSize, mem0.id, + mem0.offset); + expected.set_token1.Init(GetNextToken()); + expected.set_bucket_data1.Init(kBucketId, kHeaderSize, kString1Size, mem1.id, + mem1.offset); + expected.set_token2.Init(GetNextToken()); + expected.set_bucket_data2.Init(kBucketId, kHeaderSize + kString1Size, + kString2Size, mem2.id, mem2.offset); + expected.set_token3.Init(GetNextToken()); + expected.cmd_bucket.Init(1, kBucketId, GL_INTERLEAVED_ATTRIBS); + expected.clear_bucket_size.Init(kBucketId, 0); + const char* kStrings[] = {kString1, kString2}; + gl_->TransformFeedbackVaryings(1, 2, kStrings, GL_INTERLEAVED_ATTRIBS); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, Uniform1f) { struct Cmds { cmds::Uniform1f cmd; @@ -1169,6 +1877,35 @@ TEST_F(GLES2ImplementationTest, Uniform1iv) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, Uniform1ui) { + struct Cmds { + cmds::Uniform1ui cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2); + + gl_->Uniform1ui(1, 2); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, Uniform1uiv) { + GLuint data[2][1] = {{0}}; + struct Cmds { + cmds::Uniform1uivImmediate cmd; + GLuint data[2][1]; + }; + + Cmds expected; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 1; ++jj) { + data[ii][jj] = static_cast<GLuint>(ii * 1 + jj); + } + } + expected.cmd.Init(1, 2, &data[0][0]); + gl_->Uniform1uiv(1, 2, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, Uniform2f) { struct Cmds { cmds::Uniform2f cmd; @@ -1227,6 +1964,35 @@ TEST_F(GLES2ImplementationTest, Uniform2iv) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, Uniform2ui) { + struct Cmds { + cmds::Uniform2ui cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2, 3); + + gl_->Uniform2ui(1, 2, 3); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, Uniform2uiv) { + GLuint data[2][2] = {{0}}; + struct Cmds { + cmds::Uniform2uivImmediate cmd; + GLuint data[2][2]; + }; + + Cmds expected; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 2; ++jj) { + data[ii][jj] = static_cast<GLuint>(ii * 2 + jj); + } + } + expected.cmd.Init(1, 2, &data[0][0]); + gl_->Uniform2uiv(1, 2, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, Uniform3f) { struct Cmds { cmds::Uniform3f cmd; @@ -1285,6 +2051,35 @@ TEST_F(GLES2ImplementationTest, Uniform3iv) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, Uniform3ui) { + struct Cmds { + cmds::Uniform3ui cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2, 3, 4); + + gl_->Uniform3ui(1, 2, 3, 4); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, Uniform3uiv) { + GLuint data[2][3] = {{0}}; + struct Cmds { + cmds::Uniform3uivImmediate cmd; + GLuint data[2][3]; + }; + + Cmds expected; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 3; ++jj) { + data[ii][jj] = static_cast<GLuint>(ii * 3 + jj); + } + } + expected.cmd.Init(1, 2, &data[0][0]); + gl_->Uniform3uiv(1, 2, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, Uniform4f) { struct Cmds { cmds::Uniform4f cmd; @@ -1343,6 +2138,46 @@ TEST_F(GLES2ImplementationTest, Uniform4iv) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, Uniform4ui) { + struct Cmds { + cmds::Uniform4ui cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2, 3, 4, 5); + + gl_->Uniform4ui(1, 2, 3, 4, 5); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, Uniform4uiv) { + GLuint data[2][4] = {{0}}; + struct Cmds { + cmds::Uniform4uivImmediate cmd; + GLuint data[2][4]; + }; + + Cmds expected; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 4; ++jj) { + data[ii][jj] = static_cast<GLuint>(ii * 4 + jj); + } + } + expected.cmd.Init(1, 2, &data[0][0]); + gl_->Uniform4uiv(1, 2, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, UniformBlockBinding) { + struct Cmds { + cmds::UniformBlockBinding cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2, 3); + + gl_->UniformBlockBinding(1, 2, 3); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, UniformMatrix2fv) { GLfloat data[2][4] = {{0}}; struct Cmds { @@ -1373,6 +2208,66 @@ TEST_F(GLES2ImplementationTest, UniformMatrix2fvInvalidConstantArg2) { EXPECT_EQ(GL_INVALID_VALUE, CheckError()); } +TEST_F(GLES2ImplementationTest, UniformMatrix2x3fv) { + GLfloat data[2][6] = {{0}}; + struct Cmds { + cmds::UniformMatrix2x3fvImmediate cmd; + GLfloat data[2][6]; + }; + + Cmds expected; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 6; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 6 + jj); + } + } + expected.cmd.Init(1, 2, &data[0][0]); + gl_->UniformMatrix2x3fv(1, 2, false, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, UniformMatrix2x3fvInvalidConstantArg2) { + GLfloat data[2][6] = {{0}}; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 6; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 6 + jj); + } + } + gl_->UniformMatrix2x3fv(1, 2, true, &data[0][0]); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); +} + +TEST_F(GLES2ImplementationTest, UniformMatrix2x4fv) { + GLfloat data[2][8] = {{0}}; + struct Cmds { + cmds::UniformMatrix2x4fvImmediate cmd; + GLfloat data[2][8]; + }; + + Cmds expected; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 8; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 8 + jj); + } + } + expected.cmd.Init(1, 2, &data[0][0]); + gl_->UniformMatrix2x4fv(1, 2, false, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, UniformMatrix2x4fvInvalidConstantArg2) { + GLfloat data[2][8] = {{0}}; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 8; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 8 + jj); + } + } + gl_->UniformMatrix2x4fv(1, 2, true, &data[0][0]); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); +} + TEST_F(GLES2ImplementationTest, UniformMatrix3fv) { GLfloat data[2][9] = {{0}}; struct Cmds { @@ -1403,6 +2298,66 @@ TEST_F(GLES2ImplementationTest, UniformMatrix3fvInvalidConstantArg2) { EXPECT_EQ(GL_INVALID_VALUE, CheckError()); } +TEST_F(GLES2ImplementationTest, UniformMatrix3x2fv) { + GLfloat data[2][6] = {{0}}; + struct Cmds { + cmds::UniformMatrix3x2fvImmediate cmd; + GLfloat data[2][6]; + }; + + Cmds expected; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 6; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 6 + jj); + } + } + expected.cmd.Init(1, 2, &data[0][0]); + gl_->UniformMatrix3x2fv(1, 2, false, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, UniformMatrix3x2fvInvalidConstantArg2) { + GLfloat data[2][6] = {{0}}; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 6; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 6 + jj); + } + } + gl_->UniformMatrix3x2fv(1, 2, true, &data[0][0]); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); +} + +TEST_F(GLES2ImplementationTest, UniformMatrix3x4fv) { + GLfloat data[2][12] = {{0}}; + struct Cmds { + cmds::UniformMatrix3x4fvImmediate cmd; + GLfloat data[2][12]; + }; + + Cmds expected; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 12; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 12 + jj); + } + } + expected.cmd.Init(1, 2, &data[0][0]); + gl_->UniformMatrix3x4fv(1, 2, false, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, UniformMatrix3x4fvInvalidConstantArg2) { + GLfloat data[2][12] = {{0}}; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 12; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 12 + jj); + } + } + gl_->UniformMatrix3x4fv(1, 2, true, &data[0][0]); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); +} + TEST_F(GLES2ImplementationTest, UniformMatrix4fv) { GLfloat data[2][16] = {{0}}; struct Cmds { @@ -1433,6 +2388,66 @@ TEST_F(GLES2ImplementationTest, UniformMatrix4fvInvalidConstantArg2) { EXPECT_EQ(GL_INVALID_VALUE, CheckError()); } +TEST_F(GLES2ImplementationTest, UniformMatrix4x2fv) { + GLfloat data[2][8] = {{0}}; + struct Cmds { + cmds::UniformMatrix4x2fvImmediate cmd; + GLfloat data[2][8]; + }; + + Cmds expected; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 8; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 8 + jj); + } + } + expected.cmd.Init(1, 2, &data[0][0]); + gl_->UniformMatrix4x2fv(1, 2, false, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, UniformMatrix4x2fvInvalidConstantArg2) { + GLfloat data[2][8] = {{0}}; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 8; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 8 + jj); + } + } + gl_->UniformMatrix4x2fv(1, 2, true, &data[0][0]); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); +} + +TEST_F(GLES2ImplementationTest, UniformMatrix4x3fv) { + GLfloat data[2][12] = {{0}}; + struct Cmds { + cmds::UniformMatrix4x3fvImmediate cmd; + GLfloat data[2][12]; + }; + + Cmds expected; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 12; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 12 + jj); + } + } + expected.cmd.Init(1, 2, &data[0][0]); + gl_->UniformMatrix4x3fv(1, 2, false, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, UniformMatrix4x3fvInvalidConstantArg2) { + GLfloat data[2][12] = {{0}}; + for (int ii = 0; ii < 2; ++ii) { + for (int jj = 0; jj < 12; ++jj) { + data[ii][jj] = static_cast<GLfloat>(ii * 12 + jj); + } + } + gl_->UniformMatrix4x3fv(1, 2, true, &data[0][0]); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); +} + TEST_F(GLES2ImplementationTest, UseProgram) { struct Cmds { cmds::UseProgram cmd; @@ -1566,6 +2581,60 @@ TEST_F(GLES2ImplementationTest, VertexAttrib4fv) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, VertexAttribI4i) { + struct Cmds { + cmds::VertexAttribI4i cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2, 3, 4, 5); + + gl_->VertexAttribI4i(1, 2, 3, 4, 5); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, VertexAttribI4iv) { + GLint data[4] = {0}; + struct Cmds { + cmds::VertexAttribI4ivImmediate cmd; + GLint data[4]; + }; + + for (int jj = 0; jj < 4; ++jj) { + data[jj] = static_cast<GLint>(jj); + } + Cmds expected; + expected.cmd.Init(1, &data[0]); + gl_->VertexAttribI4iv(1, &data[0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, VertexAttribI4ui) { + struct Cmds { + cmds::VertexAttribI4ui cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2, 3, 4, 5); + + gl_->VertexAttribI4ui(1, 2, 3, 4, 5); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, VertexAttribI4uiv) { + GLuint data[4] = {0}; + struct Cmds { + cmds::VertexAttribI4uivImmediate cmd; + GLuint data[4]; + }; + + for (int jj = 0; jj < 4; ++jj) { + data[jj] = static_cast<GLuint>(jj); + } + Cmds expected; + expected.cmd.Init(1, &data[0]); + gl_->VertexAttribI4uiv(1, &data[0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, Viewport) { struct Cmds { cmds::Viewport cmd; @@ -1673,9 +2742,31 @@ TEST_F(GLES2ImplementationTest, DeleteQueriesEXT) { gl_->DeleteQueriesEXT(arraysize(ids), &ids[0]); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -// TODO: Implement unit test for BeginQueryEXT -// TODO: Implement unit test for InsertEventMarkerEXT -// TODO: Implement unit test for PushGroupMarkerEXT +// TODO(zmo): Implement unit test for BeginQueryEXT + +TEST_F(GLES2ImplementationTest, BeginTransformFeedback) { + struct Cmds { + cmds::BeginTransformFeedback cmd; + }; + Cmds expected; + expected.cmd.Init(GL_POINTS); + + gl_->BeginTransformFeedback(GL_POINTS); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, EndTransformFeedback) { + struct Cmds { + cmds::EndTransformFeedback cmd; + }; + Cmds expected; + expected.cmd.Init(); + + gl_->EndTransformFeedback(); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} +// TODO(zmo): Implement unit test for InsertEventMarkerEXT +// TODO(zmo): Implement unit test for PushGroupMarkerEXT TEST_F(GLES2ImplementationTest, PopGroupMarkerEXT) { struct Cmds { @@ -1731,14 +2822,16 @@ TEST_F(GLES2ImplementationTest, IsVertexArrayOES) { expected.cmd.Init(1, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32_t(1))) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) .RetiresOnSaturation(); GLboolean result = gl_->IsVertexArrayOES(1); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); EXPECT_TRUE(result); } -// TODO: Implement unit test for EnableFeatureCHROMIUM +// TODO(zmo): Implement unit test for EnableFeatureCHROMIUM +// TODO(zmo): Implement unit test for MapBufferRange +// TODO(zmo): Implement unit test for UnmapBuffer TEST_F(GLES2ImplementationTest, ResizeCHROMIUM) { struct Cmds { @@ -1750,9 +2843,9 @@ TEST_F(GLES2ImplementationTest, ResizeCHROMIUM) { gl_->ResizeCHROMIUM(1, 2, 3); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -// TODO: Implement unit test for GetRequestableExtensionsCHROMIUM -// TODO: Implement unit test for CreateStreamTextureCHROMIUM -// TODO: Implement unit test for GetTranslatedShaderSourceANGLE +// TODO(zmo): Implement unit test for GetRequestableExtensionsCHROMIUM +// TODO(zmo): Implement unit test for CreateStreamTextureCHROMIUM +// TODO(zmo): Implement unit test for GetTranslatedShaderSourceANGLE TEST_F(GLES2ImplementationTest, TexImageIOSurface2DCHROMIUM) { struct Cmds { @@ -1770,9 +2863,20 @@ TEST_F(GLES2ImplementationTest, CopyTextureCHROMIUM) { cmds::CopyTextureCHROMIUM cmd; }; Cmds expected; - expected.cmd.Init(1, 2, 3, 4, GL_ALPHA, GL_UNSIGNED_BYTE); + expected.cmd.Init(1, 2, 3, GL_ALPHA, GL_UNSIGNED_BYTE); + + gl_->CopyTextureCHROMIUM(1, 2, 3, GL_ALPHA, GL_UNSIGNED_BYTE); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, CopySubTextureCHROMIUM) { + struct Cmds { + cmds::CopySubTextureCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2, 3, 4, 5); - gl_->CopyTextureCHROMIUM(1, 2, 3, 4, GL_ALPHA, GL_UNSIGNED_BYTE); + gl_->CopySubTextureCHROMIUM(1, 2, 3, 4, 5); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } @@ -1797,8 +2901,8 @@ TEST_F(GLES2ImplementationTest, VertexAttribDivisorANGLE) { gl_->VertexAttribDivisorANGLE(1, 2); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -// TODO: Implement unit test for GenMailboxCHROMIUM -// TODO: Implement unit test for BindUniformLocationCHROMIUM +// TODO(zmo): Implement unit test for GenMailboxCHROMIUM +// TODO(zmo): Implement unit test for BindUniformLocationCHROMIUM TEST_F(GLES2ImplementationTest, GenValuebuffersCHROMIUM) { GLuint ids[2] = { @@ -1843,7 +2947,7 @@ TEST_F(GLES2ImplementationTest, IsValuebufferCHROMIUM) { expected.cmd.Init(1, result1.id, result1.offset); EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32_t(1))) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) .RetiresOnSaturation(); GLboolean result = gl_->IsValuebufferCHROMIUM(1); @@ -1953,7 +3057,7 @@ TEST_F(GLES2ImplementationTest, LoseContextCHROMIUM) { GL_GUILTY_CONTEXT_RESET_ARB); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -// TODO: Implement unit test for InsertSyncPointCHROMIUM +// TODO(zmo): Implement unit test for InsertSyncPointCHROMIUM TEST_F(GLES2ImplementationTest, WaitSyncPointCHROMIUM) { struct Cmds { diff --git a/chromium/gpu/command_buffer/client/gles2_interface_autogen.h b/chromium/gpu/command_buffer/client/gles2_interface_autogen.h index af5db19d114..a8bde2922cd 100644 --- a/chromium/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_interface_autogen.h @@ -19,9 +19,17 @@ virtual void BindAttribLocation(GLuint program, GLuint index, const char* name) = 0; virtual void BindBuffer(GLenum target, GLuint buffer) = 0; +virtual void BindBufferBase(GLenum target, GLuint index, GLuint buffer) = 0; +virtual void BindBufferRange(GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) = 0; virtual void BindFramebuffer(GLenum target, GLuint framebuffer) = 0; virtual void BindRenderbuffer(GLenum target, GLuint renderbuffer) = 0; +virtual void BindSampler(GLuint unit, GLuint sampler) = 0; virtual void BindTexture(GLenum target, GLuint texture) = 0; +virtual void BindTransformFeedback(GLenum target, GLuint transformfeedback) = 0; virtual void BlendColor(GLclampf red, GLclampf green, GLclampf blue, @@ -43,12 +51,28 @@ virtual void BufferSubData(GLenum target, const void* data) = 0; virtual GLenum CheckFramebufferStatus(GLenum target) = 0; virtual void Clear(GLbitfield mask) = 0; +virtual void ClearBufferfi(GLenum buffer, + GLint drawbuffers, + GLfloat depth, + GLint stencil) = 0; +virtual void ClearBufferfv(GLenum buffer, + GLint drawbuffers, + const GLfloat* value) = 0; +virtual void ClearBufferiv(GLenum buffer, + GLint drawbuffers, + const GLint* value) = 0; +virtual void ClearBufferuiv(GLenum buffer, + GLint drawbuffers, + const GLuint* value) = 0; virtual void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = 0; virtual void ClearDepthf(GLclampf depth) = 0; virtual void ClearStencil(GLint s) = 0; +virtual GLenum ClientWaitSync(GLsync sync, + GLbitfield flags, + GLuint64 timeout) = 0; virtual void ColorMask(GLboolean red, GLboolean green, GLboolean blue, @@ -71,6 +95,31 @@ virtual void CompressedTexSubImage2D(GLenum target, GLenum format, GLsizei imageSize, const void* data) = 0; +virtual void CompressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void* data) = 0; +virtual void CompressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void* data) = 0; +virtual void CopyBufferSubData(GLenum readtarget, + GLenum writetarget, + GLintptr readoffset, + GLintptr writeoffset, + GLsizeiptr size) = 0; virtual void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, @@ -87,6 +136,15 @@ virtual void CopyTexSubImage2D(GLenum target, GLint y, GLsizei width, GLsizei height) = 0; +virtual void CopyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) = 0; virtual GLuint CreateProgram() = 0; virtual GLuint CreateShader(GLenum type) = 0; virtual void CullFace(GLenum mode) = 0; @@ -94,8 +152,11 @@ virtual void DeleteBuffers(GLsizei n, const GLuint* buffers) = 0; virtual void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) = 0; virtual void DeleteProgram(GLuint program) = 0; virtual void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) = 0; +virtual void DeleteSamplers(GLsizei n, const GLuint* samplers) = 0; +virtual void DeleteSync(GLsync sync) = 0; virtual void DeleteShader(GLuint shader) = 0; virtual void DeleteTextures(GLsizei n, const GLuint* textures) = 0; +virtual void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) = 0; virtual void DepthFunc(GLenum func) = 0; virtual void DepthMask(GLboolean flag) = 0; virtual void DepthRangef(GLclampf zNear, GLclampf zFar) = 0; @@ -107,8 +168,15 @@ virtual void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) = 0; +virtual void DrawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void* indices) = 0; virtual void Enable(GLenum cap) = 0; virtual void EnableVertexAttribArray(GLuint index) = 0; +virtual GLsync FenceSync(GLenum condition, GLbitfield flags) = 0; virtual void Finish() = 0; virtual void Flush() = 0; virtual void FramebufferRenderbuffer(GLenum target, @@ -120,12 +188,19 @@ virtual void FramebufferTexture2D(GLenum target, GLenum textarget, GLuint texture, GLint level) = 0; +virtual void FramebufferTextureLayer(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) = 0; virtual void FrontFace(GLenum mode) = 0; virtual void GenBuffers(GLsizei n, GLuint* buffers) = 0; virtual void GenerateMipmap(GLenum target) = 0; virtual void GenFramebuffers(GLsizei n, GLuint* framebuffers) = 0; virtual void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) = 0; +virtual void GenSamplers(GLsizei n, GLuint* samplers) = 0; virtual void GenTextures(GLsizei n, GLuint* textures) = 0; +virtual void GenTransformFeedbacks(GLsizei n, GLuint* ids) = 0; virtual void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, @@ -140,6 +215,20 @@ virtual void GetActiveUniform(GLuint program, GLint* size, GLenum* type, char* name) = 0; +virtual void GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) = 0; +virtual void GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) = 0; +virtual void GetActiveUniformsiv(GLuint program, + GLsizei count, + const GLuint* indices, + GLenum pname, + GLint* params) = 0; virtual void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -151,11 +240,20 @@ virtual void GetBufferParameteriv(GLenum target, GLint* params) = 0; virtual GLenum GetError() = 0; virtual void GetFloatv(GLenum pname, GLfloat* params) = 0; +virtual GLint GetFragDataLocation(GLuint program, const char* name) = 0; virtual void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) = 0; +virtual void GetInteger64v(GLenum pname, GLint64* params) = 0; +virtual void GetIntegeri_v(GLenum pname, GLuint index, GLint* data) = 0; +virtual void GetInteger64i_v(GLenum pname, GLuint index, GLint64* data) = 0; virtual void GetIntegerv(GLenum pname, GLint* params) = 0; +virtual void GetInternalformativ(GLenum target, + GLenum format, + GLenum pname, + GLsizei bufSize, + GLint* params) = 0; virtual void GetProgramiv(GLuint program, GLenum pname, GLint* params) = 0; virtual void GetProgramInfoLog(GLuint program, GLsizei bufsize, @@ -164,6 +262,12 @@ virtual void GetProgramInfoLog(GLuint program, virtual void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) = 0; +virtual void GetSamplerParameterfv(GLuint sampler, + GLenum pname, + GLfloat* params) = 0; +virtual void GetSamplerParameteriv(GLuint sampler, + GLenum pname, + GLint* params) = 0; virtual void GetShaderiv(GLuint shader, GLenum pname, GLint* params) = 0; virtual void GetShaderInfoLog(GLuint shader, GLsizei bufsize, @@ -178,30 +282,67 @@ virtual void GetShaderSource(GLuint shader, GLsizei* length, char* source) = 0; virtual const GLubyte* GetString(GLenum name) = 0; +virtual void GetSynciv(GLsync sync, + GLenum pname, + GLsizei bufsize, + GLsizei* length, + GLint* values) = 0; virtual void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) = 0; virtual void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) = 0; +virtual void GetTransformFeedbackVarying(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + GLsizei* size, + GLenum* type, + char* name) = 0; +virtual GLuint GetUniformBlockIndex(GLuint program, const char* name) = 0; virtual void GetUniformfv(GLuint program, GLint location, GLfloat* params) = 0; virtual void GetUniformiv(GLuint program, GLint location, GLint* params) = 0; +virtual void GetUniformuiv(GLuint program, GLint location, GLuint* params) = 0; +virtual void GetUniformIndices(GLuint program, + GLsizei count, + const char* const* names, + GLuint* indices) = 0; virtual GLint GetUniformLocation(GLuint program, const char* name) = 0; virtual void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) = 0; virtual void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) = 0; +virtual void GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) = 0; +virtual void GetVertexAttribIuiv(GLuint index, + GLenum pname, + GLuint* params) = 0; virtual void GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer) = 0; virtual void Hint(GLenum target, GLenum mode) = 0; +virtual void InvalidateFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments) = 0; +virtual void InvalidateSubFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) = 0; virtual GLboolean IsBuffer(GLuint buffer) = 0; virtual GLboolean IsEnabled(GLenum cap) = 0; virtual GLboolean IsFramebuffer(GLuint framebuffer) = 0; virtual GLboolean IsProgram(GLuint program) = 0; virtual GLboolean IsRenderbuffer(GLuint renderbuffer) = 0; +virtual GLboolean IsSampler(GLuint sampler) = 0; virtual GLboolean IsShader(GLuint shader) = 0; +virtual GLboolean IsSync(GLsync sync) = 0; virtual GLboolean IsTexture(GLuint texture) = 0; +virtual GLboolean IsTransformFeedback(GLuint transformfeedback) = 0; virtual void LineWidth(GLfloat width) = 0; virtual void LinkProgram(GLuint program) = 0; +virtual void PauseTransformFeedback() = 0; virtual void PixelStorei(GLenum pname, GLint param) = 0; virtual void PolygonOffset(GLfloat factor, GLfloat units) = 0; +virtual void ReadBuffer(GLenum src) = 0; virtual void ReadPixels(GLint x, GLint y, GLsizei width, @@ -214,7 +355,16 @@ virtual void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) = 0; +virtual void ResumeTransformFeedback() = 0; virtual void SampleCoverage(GLclampf value, GLboolean invert) = 0; +virtual void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) = 0; +virtual void SamplerParameterfv(GLuint sampler, + GLenum pname, + const GLfloat* params) = 0; +virtual void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) = 0; +virtual void SamplerParameteriv(GLuint sampler, + GLenum pname, + const GLint* params) = 0; virtual void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) = 0; virtual void ShaderBinary(GLsizei n, const GLuint* shaders, @@ -227,6 +377,7 @@ virtual void ShaderSource(GLuint shader, const GLint* length) = 0; virtual void ShallowFinishCHROMIUM() = 0; virtual void ShallowFlushCHROMIUM() = 0; +virtual void OrderingBarrierCHROMIUM() = 0; virtual void StencilFunc(GLenum func, GLint ref, GLuint mask) = 0; virtual void StencilFuncSeparate(GLenum face, GLenum func, @@ -248,6 +399,16 @@ virtual void TexImage2D(GLenum target, GLenum format, GLenum type, const void* pixels) = 0; +virtual void TexImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void* pixels) = 0; virtual void TexParameterf(GLenum target, GLenum pname, GLfloat param) = 0; virtual void TexParameterfv(GLenum target, GLenum pname, @@ -256,6 +417,12 @@ virtual void TexParameteri(GLenum target, GLenum pname, GLint param) = 0; virtual void TexParameteriv(GLenum target, GLenum pname, const GLint* params) = 0; +virtual void TexStorage3D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth) = 0; virtual void TexSubImage2D(GLenum target, GLint level, GLint xoffset, @@ -265,18 +432,39 @@ virtual void TexSubImage2D(GLenum target, GLenum format, GLenum type, const void* pixels) = 0; +virtual void TexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void* pixels) = 0; +virtual void TransformFeedbackVaryings(GLuint program, + GLsizei count, + const char* const* varyings, + GLenum buffermode) = 0; virtual void Uniform1f(GLint location, GLfloat x) = 0; virtual void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) = 0; virtual void Uniform1i(GLint location, GLint x) = 0; virtual void Uniform1iv(GLint location, GLsizei count, const GLint* v) = 0; +virtual void Uniform1ui(GLint location, GLuint x) = 0; +virtual void Uniform1uiv(GLint location, GLsizei count, const GLuint* v) = 0; virtual void Uniform2f(GLint location, GLfloat x, GLfloat y) = 0; virtual void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) = 0; virtual void Uniform2i(GLint location, GLint x, GLint y) = 0; virtual void Uniform2iv(GLint location, GLsizei count, const GLint* v) = 0; +virtual void Uniform2ui(GLint location, GLuint x, GLuint y) = 0; +virtual void Uniform2uiv(GLint location, GLsizei count, const GLuint* v) = 0; virtual void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) = 0; virtual void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) = 0; virtual void Uniform3i(GLint location, GLint x, GLint y, GLint z) = 0; virtual void Uniform3iv(GLint location, GLsizei count, const GLint* v) = 0; +virtual void Uniform3ui(GLint location, GLuint x, GLuint y, GLuint z) = 0; +virtual void Uniform3uiv(GLint location, GLsizei count, const GLuint* v) = 0; virtual void Uniform4f(GLint location, GLfloat x, GLfloat y, @@ -285,18 +473,51 @@ virtual void Uniform4f(GLint location, virtual void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) = 0; virtual void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) = 0; virtual void Uniform4iv(GLint location, GLsizei count, const GLint* v) = 0; +virtual void Uniform4ui(GLint location, + GLuint x, + GLuint y, + GLuint z, + GLuint w) = 0; +virtual void Uniform4uiv(GLint location, GLsizei count, const GLuint* v) = 0; +virtual void UniformBlockBinding(GLuint program, + GLuint index, + GLuint binding) = 0; virtual void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = 0; +virtual void UniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) = 0; +virtual void UniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) = 0; virtual void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = 0; +virtual void UniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) = 0; +virtual void UniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) = 0; virtual void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = 0; +virtual void UniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) = 0; +virtual void UniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) = 0; virtual void UseProgram(GLuint program) = 0; virtual void ValidateProgram(GLuint program) = 0; virtual void VertexAttrib1f(GLuint indx, GLfloat x) = 0; @@ -311,6 +532,23 @@ virtual void VertexAttrib4f(GLuint indx, GLfloat z, GLfloat w) = 0; virtual void VertexAttrib4fv(GLuint indx, const GLfloat* values) = 0; +virtual void VertexAttribI4i(GLuint indx, + GLint x, + GLint y, + GLint z, + GLint w) = 0; +virtual void VertexAttribI4iv(GLuint indx, const GLint* values) = 0; +virtual void VertexAttribI4ui(GLuint indx, + GLuint x, + GLuint y, + GLuint z, + GLuint w) = 0; +virtual void VertexAttribI4uiv(GLuint indx, const GLuint* values) = 0; +virtual void VertexAttribIPointer(GLuint indx, + GLint size, + GLenum type, + GLsizei stride, + const void* ptr) = 0; virtual void VertexAttribPointer(GLuint indx, GLint size, GLenum type, @@ -318,6 +556,7 @@ virtual void VertexAttribPointer(GLuint indx, GLsizei stride, const void* ptr) = 0; virtual void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) = 0; +virtual void WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) = 0; virtual void BlitFramebufferCHROMIUM(GLint srcX0, GLint srcY0, GLint srcX1, @@ -353,7 +592,9 @@ virtual void GenQueriesEXT(GLsizei n, GLuint* queries) = 0; virtual void DeleteQueriesEXT(GLsizei n, const GLuint* queries) = 0; virtual GLboolean IsQueryEXT(GLuint id) = 0; virtual void BeginQueryEXT(GLenum target, GLuint id) = 0; +virtual void BeginTransformFeedback(GLenum primitivemode) = 0; virtual void EndQueryEXT(GLenum target) = 0; +virtual void EndTransformFeedback() = 0; virtual void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) = 0; virtual void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) = 0; virtual void InsertEventMarkerEXT(GLsizei length, const GLchar* marker) = 0; @@ -376,6 +617,11 @@ virtual void* MapBufferSubDataCHROMIUM(GLuint target, GLsizeiptr size, GLenum access) = 0; virtual void UnmapBufferSubDataCHROMIUM(const void* mem) = 0; +virtual void* MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) = 0; +virtual GLboolean UnmapBuffer(GLenum target) = 0; virtual void* MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, @@ -392,14 +638,22 @@ virtual void ResizeCHROMIUM(GLuint width, virtual const GLchar* GetRequestableExtensionsCHROMIUM() = 0; virtual void RequestExtensionCHROMIUM(const char* extension) = 0; virtual void RateLimitOffscreenContextCHROMIUM() = 0; -virtual void GetMultipleIntegervCHROMIUM(const GLenum* pnames, - GLuint count, - GLint* results, - GLsizeiptr size) = 0; virtual void GetProgramInfoCHROMIUM(GLuint program, GLsizei bufsize, GLsizei* size, void* info) = 0; +virtual void GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) = 0; +virtual void GetTransformFeedbackVaryingsCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) = 0; +virtual void GetUniformsES3CHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) = 0; virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) = 0; virtual GLuint CreateImageCHROMIUM(ClientBuffer buffer, GLsizei width, @@ -426,9 +680,13 @@ virtual void TexImageIOSurface2DCHROMIUM(GLenum target, virtual void CopyTextureCHROMIUM(GLenum target, GLenum source_id, GLenum dest_id, - GLint level, GLint internalformat, GLenum dest_type) = 0; +virtual void CopySubTextureCHROMIUM(GLenum target, + GLenum source_id, + GLenum dest_id, + GLint xoffset, + GLint yoffset) = 0; virtual void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, @@ -462,7 +720,8 @@ virtual void UniformValuebufferCHROMIUM(GLint location, GLenum subscription) = 0; virtual void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) = 0; virtual void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) = 0; -virtual void TraceBeginCHROMIUM(const char* name) = 0; +virtual void TraceBeginCHROMIUM(const char* category_name, + const char* trace_name) = 0; virtual void TraceEndCHROMIUM() = 0; virtual void AsyncTexSubImage2DCHROMIUM(GLenum target, GLint level, @@ -503,6 +762,7 @@ virtual void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order, GLfloat uv_y, GLfloat uv_width, GLfloat uv_height) = 0; +virtual void SwapInterval(GLint interval) = 0; virtual void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) = 0; virtual void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) = 0; virtual void BlendBarrierKHR() = 0; diff --git a/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h index c540360d879..fd5151b8d21 100644 --- a/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -18,9 +18,17 @@ void BindAttribLocation(GLuint program, GLuint index, const char* name) override; void BindBuffer(GLenum target, GLuint buffer) override; +void BindBufferBase(GLenum target, GLuint index, GLuint buffer) override; +void BindBufferRange(GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) override; void BindFramebuffer(GLenum target, GLuint framebuffer) override; void BindRenderbuffer(GLenum target, GLuint renderbuffer) override; +void BindSampler(GLuint unit, GLuint sampler) override; void BindTexture(GLenum target, GLuint texture) override; +void BindTransformFeedback(GLenum target, GLuint transformfeedback) override; void BlendColor(GLclampf red, GLclampf green, GLclampf blue, @@ -42,12 +50,26 @@ void BufferSubData(GLenum target, const void* data) override; GLenum CheckFramebufferStatus(GLenum target) override; void Clear(GLbitfield mask) override; +void ClearBufferfi(GLenum buffer, + GLint drawbuffers, + GLfloat depth, + GLint stencil) override; +void ClearBufferfv(GLenum buffer, + GLint drawbuffers, + const GLfloat* value) override; +void ClearBufferiv(GLenum buffer, + GLint drawbuffers, + const GLint* value) override; +void ClearBufferuiv(GLenum buffer, + GLint drawbuffers, + const GLuint* value) override; void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) override; void ClearDepthf(GLclampf depth) override; void ClearStencil(GLint s) override; +GLenum ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override; void ColorMask(GLboolean red, GLboolean green, GLboolean blue, @@ -70,6 +92,31 @@ void CompressedTexSubImage2D(GLenum target, GLenum format, GLsizei imageSize, const void* data) override; +void CompressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void* data) override; +void CompressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void* data) override; +void CopyBufferSubData(GLenum readtarget, + GLenum writetarget, + GLintptr readoffset, + GLintptr writeoffset, + GLsizeiptr size) override; void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, @@ -86,6 +133,15 @@ void CopyTexSubImage2D(GLenum target, GLint y, GLsizei width, GLsizei height) override; +void CopyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) override; GLuint CreateProgram() override; GLuint CreateShader(GLenum type) override; void CullFace(GLenum mode) override; @@ -93,8 +149,11 @@ void DeleteBuffers(GLsizei n, const GLuint* buffers) override; void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override; void DeleteProgram(GLuint program) override; void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override; +void DeleteSamplers(GLsizei n, const GLuint* samplers) override; +void DeleteSync(GLsync sync) override; void DeleteShader(GLuint shader) override; void DeleteTextures(GLsizei n, const GLuint* textures) override; +void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) override; void DepthFunc(GLenum func) override; void DepthMask(GLboolean flag) override; void DepthRangef(GLclampf zNear, GLclampf zFar) override; @@ -106,8 +165,15 @@ void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) override; +void DrawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void* indices) override; void Enable(GLenum cap) override; void EnableVertexAttribArray(GLuint index) override; +GLsync FenceSync(GLenum condition, GLbitfield flags) override; void Finish() override; void Flush() override; void FramebufferRenderbuffer(GLenum target, @@ -119,12 +185,19 @@ void FramebufferTexture2D(GLenum target, GLenum textarget, GLuint texture, GLint level) override; +void FramebufferTextureLayer(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) override; void FrontFace(GLenum mode) override; void GenBuffers(GLsizei n, GLuint* buffers) override; void GenerateMipmap(GLenum target) override; void GenFramebuffers(GLsizei n, GLuint* framebuffers) override; void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override; +void GenSamplers(GLsizei n, GLuint* samplers) override; void GenTextures(GLsizei n, GLuint* textures) override; +void GenTransformFeedbacks(GLsizei n, GLuint* ids) override; void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, @@ -139,6 +212,20 @@ void GetActiveUniform(GLuint program, GLint* size, GLenum* type, char* name) override; +void GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) override; +void GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) override; +void GetActiveUniformsiv(GLuint program, + GLsizei count, + const GLuint* indices, + GLenum pname, + GLint* params) override; void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -148,11 +235,20 @@ void GetBooleanv(GLenum pname, GLboolean* params) override; void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) override; GLenum GetError() override; void GetFloatv(GLenum pname, GLfloat* params) override; +GLint GetFragDataLocation(GLuint program, const char* name) override; void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) override; +void GetInteger64v(GLenum pname, GLint64* params) override; +void GetIntegeri_v(GLenum pname, GLuint index, GLint* data) override; +void GetInteger64i_v(GLenum pname, GLuint index, GLint64* data) override; void GetIntegerv(GLenum pname, GLint* params) override; +void GetInternalformativ(GLenum target, + GLenum format, + GLenum pname, + GLsizei bufSize, + GLint* params) override; void GetProgramiv(GLuint program, GLenum pname, GLint* params) override; void GetProgramInfoLog(GLuint program, GLsizei bufsize, @@ -161,6 +257,12 @@ void GetProgramInfoLog(GLuint program, void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) override; +void GetSamplerParameterfv(GLuint sampler, + GLenum pname, + GLfloat* params) override; +void GetSamplerParameteriv(GLuint sampler, + GLenum pname, + GLint* params) override; void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override; void GetShaderInfoLog(GLuint shader, GLsizei bufsize, @@ -175,28 +277,63 @@ void GetShaderSource(GLuint shader, GLsizei* length, char* source) override; const GLubyte* GetString(GLenum name) override; +void GetSynciv(GLsync sync, + GLenum pname, + GLsizei bufsize, + GLsizei* length, + GLint* values) override; void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) override; void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) override; +void GetTransformFeedbackVarying(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + GLsizei* size, + GLenum* type, + char* name) override; +GLuint GetUniformBlockIndex(GLuint program, const char* name) override; void GetUniformfv(GLuint program, GLint location, GLfloat* params) override; void GetUniformiv(GLuint program, GLint location, GLint* params) override; +void GetUniformuiv(GLuint program, GLint location, GLuint* params) override; +void GetUniformIndices(GLuint program, + GLsizei count, + const char* const* names, + GLuint* indices) override; GLint GetUniformLocation(GLuint program, const char* name) override; void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) override; void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) override; +void GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) override; +void GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) override; void GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer) override; void Hint(GLenum target, GLenum mode) override; +void InvalidateFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments) override; +void InvalidateSubFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) override; GLboolean IsBuffer(GLuint buffer) override; GLboolean IsEnabled(GLenum cap) override; GLboolean IsFramebuffer(GLuint framebuffer) override; GLboolean IsProgram(GLuint program) override; GLboolean IsRenderbuffer(GLuint renderbuffer) override; +GLboolean IsSampler(GLuint sampler) override; GLboolean IsShader(GLuint shader) override; +GLboolean IsSync(GLsync sync) override; GLboolean IsTexture(GLuint texture) override; +GLboolean IsTransformFeedback(GLuint transformfeedback) override; void LineWidth(GLfloat width) override; void LinkProgram(GLuint program) override; +void PauseTransformFeedback() override; void PixelStorei(GLenum pname, GLint param) override; void PolygonOffset(GLfloat factor, GLfloat units) override; +void ReadBuffer(GLenum src) override; void ReadPixels(GLint x, GLint y, GLsizei width, @@ -209,7 +346,16 @@ void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) override; +void ResumeTransformFeedback() override; void SampleCoverage(GLclampf value, GLboolean invert) override; +void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) override; +void SamplerParameterfv(GLuint sampler, + GLenum pname, + const GLfloat* params) override; +void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) override; +void SamplerParameteriv(GLuint sampler, + GLenum pname, + const GLint* params) override; void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override; void ShaderBinary(GLsizei n, const GLuint* shaders, @@ -222,6 +368,7 @@ void ShaderSource(GLuint shader, const GLint* length) override; void ShallowFinishCHROMIUM() override; void ShallowFlushCHROMIUM() override; +void OrderingBarrierCHROMIUM() override; void StencilFunc(GLenum func, GLint ref, GLuint mask) override; void StencilFuncSeparate(GLenum face, GLenum func, @@ -243,12 +390,28 @@ void TexImage2D(GLenum target, GLenum format, GLenum type, const void* pixels) override; +void TexImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void* pixels) override; void TexParameterf(GLenum target, GLenum pname, GLfloat param) override; void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) override; void TexParameteri(GLenum target, GLenum pname, GLint param) override; void TexParameteriv(GLenum target, GLenum pname, const GLint* params) override; +void TexStorage3D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth) override; void TexSubImage2D(GLenum target, GLint level, GLint xoffset, @@ -258,18 +421,39 @@ void TexSubImage2D(GLenum target, GLenum format, GLenum type, const void* pixels) override; +void TexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void* pixels) override; +void TransformFeedbackVaryings(GLuint program, + GLsizei count, + const char* const* varyings, + GLenum buffermode) override; void Uniform1f(GLint location, GLfloat x) override; void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) override; void Uniform1i(GLint location, GLint x) override; void Uniform1iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform1ui(GLint location, GLuint x) override; +void Uniform1uiv(GLint location, GLsizei count, const GLuint* v) override; void Uniform2f(GLint location, GLfloat x, GLfloat y) override; void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) override; void Uniform2i(GLint location, GLint x, GLint y) override; void Uniform2iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform2ui(GLint location, GLuint x, GLuint y) override; +void Uniform2uiv(GLint location, GLsizei count, const GLuint* v) override; void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) override; void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) override; void Uniform3i(GLint location, GLint x, GLint y, GLint z) override; void Uniform3iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform3ui(GLint location, GLuint x, GLuint y, GLuint z) override; +void Uniform3uiv(GLint location, GLsizei count, const GLuint* v) override; void Uniform4f(GLint location, GLfloat x, GLfloat y, @@ -278,18 +462,49 @@ void Uniform4f(GLint location, void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) override; void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) override; void Uniform4iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform4ui(GLint location, + GLuint x, + GLuint y, + GLuint z, + GLuint w) override; +void Uniform4uiv(GLint location, GLsizei count, const GLuint* v) override; +void UniformBlockBinding(GLuint program, GLuint index, GLuint binding) override; void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override; +void UniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; +void UniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override; +void UniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; +void UniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override; +void UniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; +void UniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; void UseProgram(GLuint program) override; void ValidateProgram(GLuint program) override; void VertexAttrib1f(GLuint indx, GLfloat x) override; @@ -304,6 +519,19 @@ void VertexAttrib4f(GLuint indx, GLfloat z, GLfloat w) override; void VertexAttrib4fv(GLuint indx, const GLfloat* values) override; +void VertexAttribI4i(GLuint indx, GLint x, GLint y, GLint z, GLint w) override; +void VertexAttribI4iv(GLuint indx, const GLint* values) override; +void VertexAttribI4ui(GLuint indx, + GLuint x, + GLuint y, + GLuint z, + GLuint w) override; +void VertexAttribI4uiv(GLuint indx, const GLuint* values) override; +void VertexAttribIPointer(GLuint indx, + GLint size, + GLenum type, + GLsizei stride, + const void* ptr) override; void VertexAttribPointer(GLuint indx, GLint size, GLenum type, @@ -311,6 +539,7 @@ void VertexAttribPointer(GLuint indx, GLsizei stride, const void* ptr) override; void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override; +void WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override; void BlitFramebufferCHROMIUM(GLint srcX0, GLint srcY0, GLint srcX1, @@ -346,7 +575,9 @@ void GenQueriesEXT(GLsizei n, GLuint* queries) override; void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override; GLboolean IsQueryEXT(GLuint id) override; void BeginQueryEXT(GLenum target, GLuint id) override; +void BeginTransformFeedback(GLenum primitivemode) override; void EndQueryEXT(GLenum target) override; +void EndTransformFeedback() override; void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override; void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) override; void InsertEventMarkerEXT(GLsizei length, const GLchar* marker) override; @@ -369,6 +600,11 @@ void* MapBufferSubDataCHROMIUM(GLuint target, GLsizeiptr size, GLenum access) override; void UnmapBufferSubDataCHROMIUM(const void* mem) override; +void* MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) override; +GLboolean UnmapBuffer(GLenum target) override; void* MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, @@ -383,14 +619,22 @@ void ResizeCHROMIUM(GLuint width, GLuint height, GLfloat scale_factor) override; const GLchar* GetRequestableExtensionsCHROMIUM() override; void RequestExtensionCHROMIUM(const char* extension) override; void RateLimitOffscreenContextCHROMIUM() override; -void GetMultipleIntegervCHROMIUM(const GLenum* pnames, - GLuint count, - GLint* results, - GLsizeiptr size) override; void GetProgramInfoCHROMIUM(GLuint program, GLsizei bufsize, GLsizei* size, void* info) override; +void GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; +void GetTransformFeedbackVaryingsCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; +void GetUniformsES3CHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; GLuint CreateStreamTextureCHROMIUM(GLuint texture) override; GLuint CreateImageCHROMIUM(ClientBuffer buffer, GLsizei width, @@ -417,9 +661,13 @@ void TexImageIOSurface2DCHROMIUM(GLenum target, void CopyTextureCHROMIUM(GLenum target, GLenum source_id, GLenum dest_id, - GLint level, GLint internalformat, GLenum dest_type) override; +void CopySubTextureCHROMIUM(GLenum target, + GLenum source_id, + GLenum dest_id, + GLint xoffset, + GLint yoffset) override; void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, @@ -452,7 +700,8 @@ void UniformValuebufferCHROMIUM(GLint location, GLenum subscription) override; void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override; void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override; -void TraceBeginCHROMIUM(const char* name) override; +void TraceBeginCHROMIUM(const char* category_name, + const char* trace_name) override; void TraceEndCHROMIUM() override; void AsyncTexSubImage2DCHROMIUM(GLenum target, GLint level, @@ -493,6 +742,7 @@ void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order, GLfloat uv_y, GLfloat uv_width, GLfloat uv_height) override; +void SwapInterval(GLint interval) override; void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override; void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override; void BlendBarrierKHR() override; diff --git a/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 78fe6d36b71..464f1ed8f32 100644 --- a/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -23,15 +23,30 @@ void GLES2InterfaceStub::BindAttribLocation(GLuint /* program */, } void GLES2InterfaceStub::BindBuffer(GLenum /* target */, GLuint /* buffer */) { } +void GLES2InterfaceStub::BindBufferBase(GLenum /* target */, + GLuint /* index */, + GLuint /* buffer */) { +} +void GLES2InterfaceStub::BindBufferRange(GLenum /* target */, + GLuint /* index */, + GLuint /* buffer */, + GLintptr /* offset */, + GLsizeiptr /* size */) { +} void GLES2InterfaceStub::BindFramebuffer(GLenum /* target */, GLuint /* framebuffer */) { } void GLES2InterfaceStub::BindRenderbuffer(GLenum /* target */, GLuint /* renderbuffer */) { } +void GLES2InterfaceStub::BindSampler(GLuint /* unit */, GLuint /* sampler */) { +} void GLES2InterfaceStub::BindTexture(GLenum /* target */, GLuint /* texture */) { } +void GLES2InterfaceStub::BindTransformFeedback(GLenum /* target */, + GLuint /* transformfeedback */) { +} void GLES2InterfaceStub::BlendColor(GLclampf /* red */, GLclampf /* green */, GLclampf /* blue */, @@ -64,6 +79,23 @@ GLenum GLES2InterfaceStub::CheckFramebufferStatus(GLenum /* target */) { } void GLES2InterfaceStub::Clear(GLbitfield /* mask */) { } +void GLES2InterfaceStub::ClearBufferfi(GLenum /* buffer */, + GLint /* drawbuffers */, + GLfloat /* depth */, + GLint /* stencil */) { +} +void GLES2InterfaceStub::ClearBufferfv(GLenum /* buffer */, + GLint /* drawbuffers */, + const GLfloat* /* value */) { +} +void GLES2InterfaceStub::ClearBufferiv(GLenum /* buffer */, + GLint /* drawbuffers */, + const GLint* /* value */) { +} +void GLES2InterfaceStub::ClearBufferuiv(GLenum /* buffer */, + GLint /* drawbuffers */, + const GLuint* /* value */) { +} void GLES2InterfaceStub::ClearColor(GLclampf /* red */, GLclampf /* green */, GLclampf /* blue */, @@ -73,6 +105,11 @@ void GLES2InterfaceStub::ClearDepthf(GLclampf /* depth */) { } void GLES2InterfaceStub::ClearStencil(GLint /* s */) { } +GLenum GLES2InterfaceStub::ClientWaitSync(GLsync /* sync */, + GLbitfield /* flags */, + GLuint64 /* timeout */) { + return 0; +} void GLES2InterfaceStub::ColorMask(GLboolean /* red */, GLboolean /* green */, GLboolean /* blue */, @@ -99,6 +136,34 @@ void GLES2InterfaceStub::CompressedTexSubImage2D(GLenum /* target */, GLsizei /* imageSize */, const void* /* data */) { } +void GLES2InterfaceStub::CompressedTexImage3D(GLenum /* target */, + GLint /* level */, + GLenum /* internalformat */, + GLsizei /* width */, + GLsizei /* height */, + GLsizei /* depth */, + GLint /* border */, + GLsizei /* imageSize */, + const void* /* data */) { +} +void GLES2InterfaceStub::CompressedTexSubImage3D(GLenum /* target */, + GLint /* level */, + GLint /* xoffset */, + GLint /* yoffset */, + GLint /* zoffset */, + GLsizei /* width */, + GLsizei /* height */, + GLsizei /* depth */, + GLenum /* format */, + GLsizei /* imageSize */, + const void* /* data */) { +} +void GLES2InterfaceStub::CopyBufferSubData(GLenum /* readtarget */, + GLenum /* writetarget */, + GLintptr /* readoffset */, + GLintptr /* writeoffset */, + GLsizeiptr /* size */) { +} void GLES2InterfaceStub::CopyTexImage2D(GLenum /* target */, GLint /* level */, GLenum /* internalformat */, @@ -117,6 +182,16 @@ void GLES2InterfaceStub::CopyTexSubImage2D(GLenum /* target */, GLsizei /* width */, GLsizei /* height */) { } +void GLES2InterfaceStub::CopyTexSubImage3D(GLenum /* target */, + GLint /* level */, + GLint /* xoffset */, + GLint /* yoffset */, + GLint /* zoffset */, + GLint /* x */, + GLint /* y */, + GLsizei /* width */, + GLsizei /* height */) { +} GLuint GLES2InterfaceStub::CreateProgram() { return 0; } @@ -137,11 +212,19 @@ void GLES2InterfaceStub::DeleteRenderbuffers( GLsizei /* n */, const GLuint* /* renderbuffers */) { } +void GLES2InterfaceStub::DeleteSamplers(GLsizei /* n */, + const GLuint* /* samplers */) { +} +void GLES2InterfaceStub::DeleteSync(GLsync /* sync */) { +} void GLES2InterfaceStub::DeleteShader(GLuint /* shader */) { } void GLES2InterfaceStub::DeleteTextures(GLsizei /* n */, const GLuint* /* textures */) { } +void GLES2InterfaceStub::DeleteTransformFeedbacks(GLsizei /* n */, + const GLuint* /* ids */) { +} void GLES2InterfaceStub::DepthFunc(GLenum /* func */) { } void GLES2InterfaceStub::DepthMask(GLboolean /* flag */) { @@ -165,10 +248,21 @@ void GLES2InterfaceStub::DrawElements(GLenum /* mode */, GLenum /* type */, const void* /* indices */) { } +void GLES2InterfaceStub::DrawRangeElements(GLenum /* mode */, + GLuint /* start */, + GLuint /* end */, + GLsizei /* count */, + GLenum /* type */, + const void* /* indices */) { +} void GLES2InterfaceStub::Enable(GLenum /* cap */) { } void GLES2InterfaceStub::EnableVertexAttribArray(GLuint /* index */) { } +GLsync GLES2InterfaceStub::FenceSync(GLenum /* condition */, + GLbitfield /* flags */) { + return 0; +} void GLES2InterfaceStub::Finish() { } void GLES2InterfaceStub::Flush() { @@ -185,6 +279,12 @@ void GLES2InterfaceStub::FramebufferTexture2D(GLenum /* target */, GLuint /* texture */, GLint /* level */) { } +void GLES2InterfaceStub::FramebufferTextureLayer(GLenum /* target */, + GLenum /* attachment */, + GLuint /* texture */, + GLint /* level */, + GLint /* layer */) { +} void GLES2InterfaceStub::FrontFace(GLenum /* mode */) { } void GLES2InterfaceStub::GenBuffers(GLsizei /* n */, GLuint* /* buffers */) { @@ -197,8 +297,13 @@ void GLES2InterfaceStub::GenFramebuffers(GLsizei /* n */, void GLES2InterfaceStub::GenRenderbuffers(GLsizei /* n */, GLuint* /* renderbuffers */) { } +void GLES2InterfaceStub::GenSamplers(GLsizei /* n */, GLuint* /* samplers */) { +} void GLES2InterfaceStub::GenTextures(GLsizei /* n */, GLuint* /* textures */) { } +void GLES2InterfaceStub::GenTransformFeedbacks(GLsizei /* n */, + GLuint* /* ids */) { +} void GLES2InterfaceStub::GetActiveAttrib(GLuint /* program */, GLuint /* index */, GLsizei /* bufsize */, @@ -215,6 +320,23 @@ void GLES2InterfaceStub::GetActiveUniform(GLuint /* program */, GLenum* /* type */, char* /* name */) { } +void GLES2InterfaceStub::GetActiveUniformBlockiv(GLuint /* program */, + GLuint /* index */, + GLenum /* pname */, + GLint* /* params */) { +} +void GLES2InterfaceStub::GetActiveUniformBlockName(GLuint /* program */, + GLuint /* index */, + GLsizei /* bufsize */, + GLsizei* /* length */, + char* /* name */) { +} +void GLES2InterfaceStub::GetActiveUniformsiv(GLuint /* program */, + GLsizei /* count */, + const GLuint* /* indices */, + GLenum /* pname */, + GLint* /* params */) { +} void GLES2InterfaceStub::GetAttachedShaders(GLuint /* program */, GLsizei /* maxcount */, GLsizei* /* count */, @@ -236,14 +358,35 @@ GLenum GLES2InterfaceStub::GetError() { } void GLES2InterfaceStub::GetFloatv(GLenum /* pname */, GLfloat* /* params */) { } +GLint GLES2InterfaceStub::GetFragDataLocation(GLuint /* program */, + const char* /* name */) { + return 0; +} void GLES2InterfaceStub::GetFramebufferAttachmentParameteriv( GLenum /* target */, GLenum /* attachment */, GLenum /* pname */, GLint* /* params */) { } +void GLES2InterfaceStub::GetInteger64v(GLenum /* pname */, + GLint64* /* params */) { +} +void GLES2InterfaceStub::GetIntegeri_v(GLenum /* pname */, + GLuint /* index */, + GLint* /* data */) { +} +void GLES2InterfaceStub::GetInteger64i_v(GLenum /* pname */, + GLuint /* index */, + GLint64* /* data */) { +} void GLES2InterfaceStub::GetIntegerv(GLenum /* pname */, GLint* /* params */) { } +void GLES2InterfaceStub::GetInternalformativ(GLenum /* target */, + GLenum /* format */, + GLenum /* pname */, + GLsizei /* bufSize */, + GLint* /* params */) { +} void GLES2InterfaceStub::GetProgramiv(GLuint /* program */, GLenum /* pname */, GLint* /* params */) { @@ -257,6 +400,14 @@ void GLES2InterfaceStub::GetRenderbufferParameteriv(GLenum /* target */, GLenum /* pname */, GLint* /* params */) { } +void GLES2InterfaceStub::GetSamplerParameterfv(GLuint /* sampler */, + GLenum /* pname */, + GLfloat* /* params */) { +} +void GLES2InterfaceStub::GetSamplerParameteriv(GLuint /* sampler */, + GLenum /* pname */, + GLint* /* params */) { +} void GLES2InterfaceStub::GetShaderiv(GLuint /* shader */, GLenum /* pname */, GLint* /* params */) { @@ -279,6 +430,12 @@ void GLES2InterfaceStub::GetShaderSource(GLuint /* shader */, const GLubyte* GLES2InterfaceStub::GetString(GLenum /* name */) { return 0; } +void GLES2InterfaceStub::GetSynciv(GLsync /* sync */, + GLenum /* pname */, + GLsizei /* bufsize */, + GLsizei* /* length */, + GLint* /* values */) { +} void GLES2InterfaceStub::GetTexParameterfv(GLenum /* target */, GLenum /* pname */, GLfloat* /* params */) { @@ -287,6 +444,18 @@ void GLES2InterfaceStub::GetTexParameteriv(GLenum /* target */, GLenum /* pname */, GLint* /* params */) { } +void GLES2InterfaceStub::GetTransformFeedbackVarying(GLuint /* program */, + GLuint /* index */, + GLsizei /* bufsize */, + GLsizei* /* length */, + GLsizei* /* size */, + GLenum* /* type */, + char* /* name */) { +} +GLuint GLES2InterfaceStub::GetUniformBlockIndex(GLuint /* program */, + const char* /* name */) { + return 0; +} void GLES2InterfaceStub::GetUniformfv(GLuint /* program */, GLint /* location */, GLfloat* /* params */) { @@ -295,6 +464,15 @@ void GLES2InterfaceStub::GetUniformiv(GLuint /* program */, GLint /* location */, GLint* /* params */) { } +void GLES2InterfaceStub::GetUniformuiv(GLuint /* program */, + GLint /* location */, + GLuint* /* params */) { +} +void GLES2InterfaceStub::GetUniformIndices(GLuint /* program */, + GLsizei /* count */, + const char* const* /* names */, + GLuint* /* indices */) { +} GLint GLES2InterfaceStub::GetUniformLocation(GLuint /* program */, const char* /* name */) { return 0; @@ -307,12 +485,34 @@ void GLES2InterfaceStub::GetVertexAttribiv(GLuint /* index */, GLenum /* pname */, GLint* /* params */) { } +void GLES2InterfaceStub::GetVertexAttribIiv(GLuint /* index */, + GLenum /* pname */, + GLint* /* params */) { +} +void GLES2InterfaceStub::GetVertexAttribIuiv(GLuint /* index */, + GLenum /* pname */, + GLuint* /* params */) { +} void GLES2InterfaceStub::GetVertexAttribPointerv(GLuint /* index */, GLenum /* pname */, void** /* pointer */) { } void GLES2InterfaceStub::Hint(GLenum /* target */, GLenum /* mode */) { } +void GLES2InterfaceStub::InvalidateFramebuffer( + GLenum /* target */, + GLsizei /* count */, + const GLenum* /* attachments */) { +} +void GLES2InterfaceStub::InvalidateSubFramebuffer( + GLenum /* target */, + GLsizei /* count */, + const GLenum* /* attachments */, + GLint /* x */, + GLint /* y */, + GLsizei /* width */, + GLsizei /* height */) { +} GLboolean GLES2InterfaceStub::IsBuffer(GLuint /* buffer */) { return 0; } @@ -328,21 +528,35 @@ GLboolean GLES2InterfaceStub::IsProgram(GLuint /* program */) { GLboolean GLES2InterfaceStub::IsRenderbuffer(GLuint /* renderbuffer */) { return 0; } +GLboolean GLES2InterfaceStub::IsSampler(GLuint /* sampler */) { + return 0; +} GLboolean GLES2InterfaceStub::IsShader(GLuint /* shader */) { return 0; } +GLboolean GLES2InterfaceStub::IsSync(GLsync /* sync */) { + return 0; +} GLboolean GLES2InterfaceStub::IsTexture(GLuint /* texture */) { return 0; } +GLboolean GLES2InterfaceStub::IsTransformFeedback( + GLuint /* transformfeedback */) { + return 0; +} void GLES2InterfaceStub::LineWidth(GLfloat /* width */) { } void GLES2InterfaceStub::LinkProgram(GLuint /* program */) { } +void GLES2InterfaceStub::PauseTransformFeedback() { +} void GLES2InterfaceStub::PixelStorei(GLenum /* pname */, GLint /* param */) { } void GLES2InterfaceStub::PolygonOffset(GLfloat /* factor */, GLfloat /* units */) { } +void GLES2InterfaceStub::ReadBuffer(GLenum /* src */) { +} void GLES2InterfaceStub::ReadPixels(GLint /* x */, GLint /* y */, GLsizei /* width */, @@ -358,9 +572,27 @@ void GLES2InterfaceStub::RenderbufferStorage(GLenum /* target */, GLsizei /* width */, GLsizei /* height */) { } +void GLES2InterfaceStub::ResumeTransformFeedback() { +} void GLES2InterfaceStub::SampleCoverage(GLclampf /* value */, GLboolean /* invert */) { } +void GLES2InterfaceStub::SamplerParameterf(GLuint /* sampler */, + GLenum /* pname */, + GLfloat /* param */) { +} +void GLES2InterfaceStub::SamplerParameterfv(GLuint /* sampler */, + GLenum /* pname */, + const GLfloat* /* params */) { +} +void GLES2InterfaceStub::SamplerParameteri(GLuint /* sampler */, + GLenum /* pname */, + GLint /* param */) { +} +void GLES2InterfaceStub::SamplerParameteriv(GLuint /* sampler */, + GLenum /* pname */, + const GLint* /* params */) { +} void GLES2InterfaceStub::Scissor(GLint /* x */, GLint /* y */, GLsizei /* width */, @@ -381,6 +613,8 @@ void GLES2InterfaceStub::ShallowFinishCHROMIUM() { } void GLES2InterfaceStub::ShallowFlushCHROMIUM() { } +void GLES2InterfaceStub::OrderingBarrierCHROMIUM() { +} void GLES2InterfaceStub::StencilFunc(GLenum /* func */, GLint /* ref */, GLuint /* mask */) { @@ -414,6 +648,17 @@ void GLES2InterfaceStub::TexImage2D(GLenum /* target */, GLenum /* type */, const void* /* pixels */) { } +void GLES2InterfaceStub::TexImage3D(GLenum /* target */, + GLint /* level */, + GLint /* internalformat */, + GLsizei /* width */, + GLsizei /* height */, + GLsizei /* depth */, + GLint /* border */, + GLenum /* format */, + GLenum /* type */, + const void* /* pixels */) { +} void GLES2InterfaceStub::TexParameterf(GLenum /* target */, GLenum /* pname */, GLfloat /* param */) { @@ -430,6 +675,13 @@ void GLES2InterfaceStub::TexParameteriv(GLenum /* target */, GLenum /* pname */, const GLint* /* params */) { } +void GLES2InterfaceStub::TexStorage3D(GLenum /* target */, + GLsizei /* levels */, + GLenum /* internalFormat */, + GLsizei /* width */, + GLsizei /* height */, + GLsizei /* depth */) { +} void GLES2InterfaceStub::TexSubImage2D(GLenum /* target */, GLint /* level */, GLint /* xoffset */, @@ -440,6 +692,24 @@ void GLES2InterfaceStub::TexSubImage2D(GLenum /* target */, GLenum /* type */, const void* /* pixels */) { } +void GLES2InterfaceStub::TexSubImage3D(GLenum /* target */, + GLint /* level */, + GLint /* xoffset */, + GLint /* yoffset */, + GLint /* zoffset */, + GLsizei /* width */, + GLsizei /* height */, + GLsizei /* depth */, + GLenum /* format */, + GLenum /* type */, + const void* /* pixels */) { +} +void GLES2InterfaceStub::TransformFeedbackVaryings( + GLuint /* program */, + GLsizei /* count */, + const char* const* /* varyings */, + GLenum /* buffermode */) { +} void GLES2InterfaceStub::Uniform1f(GLint /* location */, GLfloat /* x */) { } void GLES2InterfaceStub::Uniform1fv(GLint /* location */, @@ -452,6 +722,12 @@ void GLES2InterfaceStub::Uniform1iv(GLint /* location */, GLsizei /* count */, const GLint* /* v */) { } +void GLES2InterfaceStub::Uniform1ui(GLint /* location */, GLuint /* x */) { +} +void GLES2InterfaceStub::Uniform1uiv(GLint /* location */, + GLsizei /* count */, + const GLuint* /* v */) { +} void GLES2InterfaceStub::Uniform2f(GLint /* location */, GLfloat /* x */, GLfloat /* y */) { @@ -468,6 +744,14 @@ void GLES2InterfaceStub::Uniform2iv(GLint /* location */, GLsizei /* count */, const GLint* /* v */) { } +void GLES2InterfaceStub::Uniform2ui(GLint /* location */, + GLuint /* x */, + GLuint /* y */) { +} +void GLES2InterfaceStub::Uniform2uiv(GLint /* location */, + GLsizei /* count */, + const GLuint* /* v */) { +} void GLES2InterfaceStub::Uniform3f(GLint /* location */, GLfloat /* x */, GLfloat /* y */, @@ -486,6 +770,15 @@ void GLES2InterfaceStub::Uniform3iv(GLint /* location */, GLsizei /* count */, const GLint* /* v */) { } +void GLES2InterfaceStub::Uniform3ui(GLint /* location */, + GLuint /* x */, + GLuint /* y */, + GLuint /* z */) { +} +void GLES2InterfaceStub::Uniform3uiv(GLint /* location */, + GLsizei /* count */, + const GLuint* /* v */) { +} void GLES2InterfaceStub::Uniform4f(GLint /* location */, GLfloat /* x */, GLfloat /* y */, @@ -506,21 +799,65 @@ void GLES2InterfaceStub::Uniform4iv(GLint /* location */, GLsizei /* count */, const GLint* /* v */) { } +void GLES2InterfaceStub::Uniform4ui(GLint /* location */, + GLuint /* x */, + GLuint /* y */, + GLuint /* z */, + GLuint /* w */) { +} +void GLES2InterfaceStub::Uniform4uiv(GLint /* location */, + GLsizei /* count */, + const GLuint* /* v */) { +} +void GLES2InterfaceStub::UniformBlockBinding(GLuint /* program */, + GLuint /* index */, + GLuint /* binding */) { +} void GLES2InterfaceStub::UniformMatrix2fv(GLint /* location */, GLsizei /* count */, GLboolean /* transpose */, const GLfloat* /* value */) { } +void GLES2InterfaceStub::UniformMatrix2x3fv(GLint /* location */, + GLsizei /* count */, + GLboolean /* transpose */, + const GLfloat* /* value */) { +} +void GLES2InterfaceStub::UniformMatrix2x4fv(GLint /* location */, + GLsizei /* count */, + GLboolean /* transpose */, + const GLfloat* /* value */) { +} void GLES2InterfaceStub::UniformMatrix3fv(GLint /* location */, GLsizei /* count */, GLboolean /* transpose */, const GLfloat* /* value */) { } +void GLES2InterfaceStub::UniformMatrix3x2fv(GLint /* location */, + GLsizei /* count */, + GLboolean /* transpose */, + const GLfloat* /* value */) { +} +void GLES2InterfaceStub::UniformMatrix3x4fv(GLint /* location */, + GLsizei /* count */, + GLboolean /* transpose */, + const GLfloat* /* value */) { +} void GLES2InterfaceStub::UniformMatrix4fv(GLint /* location */, GLsizei /* count */, GLboolean /* transpose */, const GLfloat* /* value */) { } +void GLES2InterfaceStub::UniformMatrix4x2fv(GLint /* location */, + GLsizei /* count */, + GLboolean /* transpose */, + const GLfloat* /* value */) { +} +void GLES2InterfaceStub::UniformMatrix4x3fv(GLint /* location */, + GLsizei /* count */, + GLboolean /* transpose */, + const GLfloat* /* value */) { +} void GLES2InterfaceStub::UseProgram(GLuint /* program */) { } void GLES2InterfaceStub::ValidateProgram(GLuint /* program */) { @@ -554,6 +891,30 @@ void GLES2InterfaceStub::VertexAttrib4f(GLuint /* indx */, void GLES2InterfaceStub::VertexAttrib4fv(GLuint /* indx */, const GLfloat* /* values */) { } +void GLES2InterfaceStub::VertexAttribI4i(GLuint /* indx */, + GLint /* x */, + GLint /* y */, + GLint /* z */, + GLint /* w */) { +} +void GLES2InterfaceStub::VertexAttribI4iv(GLuint /* indx */, + const GLint* /* values */) { +} +void GLES2InterfaceStub::VertexAttribI4ui(GLuint /* indx */, + GLuint /* x */, + GLuint /* y */, + GLuint /* z */, + GLuint /* w */) { +} +void GLES2InterfaceStub::VertexAttribI4uiv(GLuint /* indx */, + const GLuint* /* values */) { +} +void GLES2InterfaceStub::VertexAttribIPointer(GLuint /* indx */, + GLint /* size */, + GLenum /* type */, + GLsizei /* stride */, + const void* /* ptr */) { +} void GLES2InterfaceStub::VertexAttribPointer(GLuint /* indx */, GLint /* size */, GLenum /* type */, @@ -566,6 +927,10 @@ void GLES2InterfaceStub::Viewport(GLint /* x */, GLsizei /* width */, GLsizei /* height */) { } +void GLES2InterfaceStub::WaitSync(GLsync /* sync */, + GLbitfield /* flags */, + GLuint64 /* timeout */) { +} void GLES2InterfaceStub::BlitFramebufferCHROMIUM(GLint /* srcX0 */, GLint /* srcY0 */, GLint /* srcX1 */, @@ -615,8 +980,12 @@ GLboolean GLES2InterfaceStub::IsQueryEXT(GLuint /* id */) { } void GLES2InterfaceStub::BeginQueryEXT(GLenum /* target */, GLuint /* id */) { } +void GLES2InterfaceStub::BeginTransformFeedback(GLenum /* primitivemode */) { +} void GLES2InterfaceStub::EndQueryEXT(GLenum /* target */) { } +void GLES2InterfaceStub::EndTransformFeedback() { +} void GLES2InterfaceStub::GetQueryivEXT(GLenum /* target */, GLenum /* pname */, GLint* /* params */) { @@ -670,6 +1039,15 @@ void* GLES2InterfaceStub::MapBufferSubDataCHROMIUM(GLuint /* target */, } void GLES2InterfaceStub::UnmapBufferSubDataCHROMIUM(const void* /* mem */) { } +void* GLES2InterfaceStub::MapBufferRange(GLenum /* target */, + GLintptr /* offset */, + GLsizeiptr /* size */, + GLbitfield /* access */) { + return 0; +} +GLboolean GLES2InterfaceStub::UnmapBuffer(GLenum /* target */) { + return 0; +} void* GLES2InterfaceStub::MapTexSubImage2DCHROMIUM(GLenum /* target */, GLint /* level */, GLint /* xoffset */, @@ -694,16 +1072,27 @@ void GLES2InterfaceStub::RequestExtensionCHROMIUM(const char* /* extension */) { } void GLES2InterfaceStub::RateLimitOffscreenContextCHROMIUM() { } -void GLES2InterfaceStub::GetMultipleIntegervCHROMIUM(const GLenum* /* pnames */, - GLuint /* count */, - GLint* /* results */, - GLsizeiptr /* size */) { -} void GLES2InterfaceStub::GetProgramInfoCHROMIUM(GLuint /* program */, GLsizei /* bufsize */, GLsizei* /* size */, void* /* info */) { } +void GLES2InterfaceStub::GetUniformBlocksCHROMIUM(GLuint /* program */, + GLsizei /* bufsize */, + GLsizei* /* size */, + void* /* info */) { +} +void GLES2InterfaceStub::GetTransformFeedbackVaryingsCHROMIUM( + GLuint /* program */, + GLsizei /* bufsize */, + GLsizei* /* size */, + void* /* info */) { +} +void GLES2InterfaceStub::GetUniformsES3CHROMIUM(GLuint /* program */, + GLsizei /* bufsize */, + GLsizei* /* size */, + void* /* info */) { +} GLuint GLES2InterfaceStub::CreateStreamTextureCHROMIUM(GLuint /* texture */) { return 0; } @@ -741,10 +1130,15 @@ void GLES2InterfaceStub::TexImageIOSurface2DCHROMIUM(GLenum /* target */, void GLES2InterfaceStub::CopyTextureCHROMIUM(GLenum /* target */, GLenum /* source_id */, GLenum /* dest_id */, - GLint /* level */, GLint /* internalformat */, GLenum /* dest_type */) { } +void GLES2InterfaceStub::CopySubTextureCHROMIUM(GLenum /* target */, + GLenum /* source_id */, + GLenum /* dest_id */, + GLint /* xoffset */, + GLint /* yoffset */) { +} void GLES2InterfaceStub::DrawArraysInstancedANGLE(GLenum /* mode */, GLint /* first */, GLsizei /* count */, @@ -809,7 +1203,8 @@ void GLES2InterfaceStub::BindTexImage2DCHROMIUM(GLenum /* target */, void GLES2InterfaceStub::ReleaseTexImage2DCHROMIUM(GLenum /* target */, GLint /* imageId */) { } -void GLES2InterfaceStub::TraceBeginCHROMIUM(const char* /* name */) { +void GLES2InterfaceStub::TraceBeginCHROMIUM(const char* /* category_name */, + const char* /* trace_name */) { } void GLES2InterfaceStub::TraceEndCHROMIUM() { } @@ -868,6 +1263,8 @@ void GLES2InterfaceStub::ScheduleOverlayPlaneCHROMIUM( GLfloat /* uv_width */, GLfloat /* uv_height */) { } +void GLES2InterfaceStub::SwapInterval(GLint /* interval */) { +} void GLES2InterfaceStub::MatrixLoadfCHROMIUM(GLenum /* matrixMode */, const GLfloat* /* m */) { } diff --git a/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index cb6091084bd..8ad90c561ca 100644 --- a/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h @@ -18,9 +18,17 @@ void BindAttribLocation(GLuint program, GLuint index, const char* name) override; void BindBuffer(GLenum target, GLuint buffer) override; +void BindBufferBase(GLenum target, GLuint index, GLuint buffer) override; +void BindBufferRange(GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) override; void BindFramebuffer(GLenum target, GLuint framebuffer) override; void BindRenderbuffer(GLenum target, GLuint renderbuffer) override; +void BindSampler(GLuint unit, GLuint sampler) override; void BindTexture(GLenum target, GLuint texture) override; +void BindTransformFeedback(GLenum target, GLuint transformfeedback) override; void BlendColor(GLclampf red, GLclampf green, GLclampf blue, @@ -42,12 +50,26 @@ void BufferSubData(GLenum target, const void* data) override; GLenum CheckFramebufferStatus(GLenum target) override; void Clear(GLbitfield mask) override; +void ClearBufferfi(GLenum buffer, + GLint drawbuffers, + GLfloat depth, + GLint stencil) override; +void ClearBufferfv(GLenum buffer, + GLint drawbuffers, + const GLfloat* value) override; +void ClearBufferiv(GLenum buffer, + GLint drawbuffers, + const GLint* value) override; +void ClearBufferuiv(GLenum buffer, + GLint drawbuffers, + const GLuint* value) override; void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) override; void ClearDepthf(GLclampf depth) override; void ClearStencil(GLint s) override; +GLenum ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override; void ColorMask(GLboolean red, GLboolean green, GLboolean blue, @@ -70,6 +92,31 @@ void CompressedTexSubImage2D(GLenum target, GLenum format, GLsizei imageSize, const void* data) override; +void CompressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void* data) override; +void CompressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void* data) override; +void CopyBufferSubData(GLenum readtarget, + GLenum writetarget, + GLintptr readoffset, + GLintptr writeoffset, + GLsizeiptr size) override; void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, @@ -86,6 +133,15 @@ void CopyTexSubImage2D(GLenum target, GLint y, GLsizei width, GLsizei height) override; +void CopyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) override; GLuint CreateProgram() override; GLuint CreateShader(GLenum type) override; void CullFace(GLenum mode) override; @@ -93,8 +149,11 @@ void DeleteBuffers(GLsizei n, const GLuint* buffers) override; void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override; void DeleteProgram(GLuint program) override; void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override; +void DeleteSamplers(GLsizei n, const GLuint* samplers) override; +void DeleteSync(GLsync sync) override; void DeleteShader(GLuint shader) override; void DeleteTextures(GLsizei n, const GLuint* textures) override; +void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) override; void DepthFunc(GLenum func) override; void DepthMask(GLboolean flag) override; void DepthRangef(GLclampf zNear, GLclampf zFar) override; @@ -106,8 +165,15 @@ void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) override; +void DrawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void* indices) override; void Enable(GLenum cap) override; void EnableVertexAttribArray(GLuint index) override; +GLsync FenceSync(GLenum condition, GLbitfield flags) override; void Finish() override; void Flush() override; void FramebufferRenderbuffer(GLenum target, @@ -119,12 +185,19 @@ void FramebufferTexture2D(GLenum target, GLenum textarget, GLuint texture, GLint level) override; +void FramebufferTextureLayer(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) override; void FrontFace(GLenum mode) override; void GenBuffers(GLsizei n, GLuint* buffers) override; void GenerateMipmap(GLenum target) override; void GenFramebuffers(GLsizei n, GLuint* framebuffers) override; void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override; +void GenSamplers(GLsizei n, GLuint* samplers) override; void GenTextures(GLsizei n, GLuint* textures) override; +void GenTransformFeedbacks(GLsizei n, GLuint* ids) override; void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, @@ -139,6 +212,20 @@ void GetActiveUniform(GLuint program, GLint* size, GLenum* type, char* name) override; +void GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) override; +void GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) override; +void GetActiveUniformsiv(GLuint program, + GLsizei count, + const GLuint* indices, + GLenum pname, + GLint* params) override; void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -148,11 +235,20 @@ void GetBooleanv(GLenum pname, GLboolean* params) override; void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) override; GLenum GetError() override; void GetFloatv(GLenum pname, GLfloat* params) override; +GLint GetFragDataLocation(GLuint program, const char* name) override; void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) override; +void GetInteger64v(GLenum pname, GLint64* params) override; +void GetIntegeri_v(GLenum pname, GLuint index, GLint* data) override; +void GetInteger64i_v(GLenum pname, GLuint index, GLint64* data) override; void GetIntegerv(GLenum pname, GLint* params) override; +void GetInternalformativ(GLenum target, + GLenum format, + GLenum pname, + GLsizei bufSize, + GLint* params) override; void GetProgramiv(GLuint program, GLenum pname, GLint* params) override; void GetProgramInfoLog(GLuint program, GLsizei bufsize, @@ -161,6 +257,12 @@ void GetProgramInfoLog(GLuint program, void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) override; +void GetSamplerParameterfv(GLuint sampler, + GLenum pname, + GLfloat* params) override; +void GetSamplerParameteriv(GLuint sampler, + GLenum pname, + GLint* params) override; void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override; void GetShaderInfoLog(GLuint shader, GLsizei bufsize, @@ -175,28 +277,63 @@ void GetShaderSource(GLuint shader, GLsizei* length, char* source) override; const GLubyte* GetString(GLenum name) override; +void GetSynciv(GLsync sync, + GLenum pname, + GLsizei bufsize, + GLsizei* length, + GLint* values) override; void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) override; void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) override; +void GetTransformFeedbackVarying(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + GLsizei* size, + GLenum* type, + char* name) override; +GLuint GetUniformBlockIndex(GLuint program, const char* name) override; void GetUniformfv(GLuint program, GLint location, GLfloat* params) override; void GetUniformiv(GLuint program, GLint location, GLint* params) override; +void GetUniformuiv(GLuint program, GLint location, GLuint* params) override; +void GetUniformIndices(GLuint program, + GLsizei count, + const char* const* names, + GLuint* indices) override; GLint GetUniformLocation(GLuint program, const char* name) override; void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) override; void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) override; +void GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) override; +void GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) override; void GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer) override; void Hint(GLenum target, GLenum mode) override; +void InvalidateFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments) override; +void InvalidateSubFramebuffer(GLenum target, + GLsizei count, + const GLenum* attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) override; GLboolean IsBuffer(GLuint buffer) override; GLboolean IsEnabled(GLenum cap) override; GLboolean IsFramebuffer(GLuint framebuffer) override; GLboolean IsProgram(GLuint program) override; GLboolean IsRenderbuffer(GLuint renderbuffer) override; +GLboolean IsSampler(GLuint sampler) override; GLboolean IsShader(GLuint shader) override; +GLboolean IsSync(GLsync sync) override; GLboolean IsTexture(GLuint texture) override; +GLboolean IsTransformFeedback(GLuint transformfeedback) override; void LineWidth(GLfloat width) override; void LinkProgram(GLuint program) override; +void PauseTransformFeedback() override; void PixelStorei(GLenum pname, GLint param) override; void PolygonOffset(GLfloat factor, GLfloat units) override; +void ReadBuffer(GLenum src) override; void ReadPixels(GLint x, GLint y, GLsizei width, @@ -209,7 +346,16 @@ void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) override; +void ResumeTransformFeedback() override; void SampleCoverage(GLclampf value, GLboolean invert) override; +void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) override; +void SamplerParameterfv(GLuint sampler, + GLenum pname, + const GLfloat* params) override; +void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) override; +void SamplerParameteriv(GLuint sampler, + GLenum pname, + const GLint* params) override; void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override; void ShaderBinary(GLsizei n, const GLuint* shaders, @@ -222,6 +368,7 @@ void ShaderSource(GLuint shader, const GLint* length) override; void ShallowFinishCHROMIUM() override; void ShallowFlushCHROMIUM() override; +void OrderingBarrierCHROMIUM() override; void StencilFunc(GLenum func, GLint ref, GLuint mask) override; void StencilFuncSeparate(GLenum face, GLenum func, @@ -243,12 +390,28 @@ void TexImage2D(GLenum target, GLenum format, GLenum type, const void* pixels) override; +void TexImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void* pixels) override; void TexParameterf(GLenum target, GLenum pname, GLfloat param) override; void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) override; void TexParameteri(GLenum target, GLenum pname, GLint param) override; void TexParameteriv(GLenum target, GLenum pname, const GLint* params) override; +void TexStorage3D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth) override; void TexSubImage2D(GLenum target, GLint level, GLint xoffset, @@ -258,18 +421,39 @@ void TexSubImage2D(GLenum target, GLenum format, GLenum type, const void* pixels) override; +void TexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void* pixels) override; +void TransformFeedbackVaryings(GLuint program, + GLsizei count, + const char* const* varyings, + GLenum buffermode) override; void Uniform1f(GLint location, GLfloat x) override; void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) override; void Uniform1i(GLint location, GLint x) override; void Uniform1iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform1ui(GLint location, GLuint x) override; +void Uniform1uiv(GLint location, GLsizei count, const GLuint* v) override; void Uniform2f(GLint location, GLfloat x, GLfloat y) override; void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) override; void Uniform2i(GLint location, GLint x, GLint y) override; void Uniform2iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform2ui(GLint location, GLuint x, GLuint y) override; +void Uniform2uiv(GLint location, GLsizei count, const GLuint* v) override; void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) override; void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) override; void Uniform3i(GLint location, GLint x, GLint y, GLint z) override; void Uniform3iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform3ui(GLint location, GLuint x, GLuint y, GLuint z) override; +void Uniform3uiv(GLint location, GLsizei count, const GLuint* v) override; void Uniform4f(GLint location, GLfloat x, GLfloat y, @@ -278,18 +462,49 @@ void Uniform4f(GLint location, void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) override; void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) override; void Uniform4iv(GLint location, GLsizei count, const GLint* v) override; +void Uniform4ui(GLint location, + GLuint x, + GLuint y, + GLuint z, + GLuint w) override; +void Uniform4uiv(GLint location, GLsizei count, const GLuint* v) override; +void UniformBlockBinding(GLuint program, GLuint index, GLuint binding) override; void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override; +void UniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; +void UniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override; +void UniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; +void UniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override; +void UniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; +void UniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) override; void UseProgram(GLuint program) override; void ValidateProgram(GLuint program) override; void VertexAttrib1f(GLuint indx, GLfloat x) override; @@ -304,6 +519,19 @@ void VertexAttrib4f(GLuint indx, GLfloat z, GLfloat w) override; void VertexAttrib4fv(GLuint indx, const GLfloat* values) override; +void VertexAttribI4i(GLuint indx, GLint x, GLint y, GLint z, GLint w) override; +void VertexAttribI4iv(GLuint indx, const GLint* values) override; +void VertexAttribI4ui(GLuint indx, + GLuint x, + GLuint y, + GLuint z, + GLuint w) override; +void VertexAttribI4uiv(GLuint indx, const GLuint* values) override; +void VertexAttribIPointer(GLuint indx, + GLint size, + GLenum type, + GLsizei stride, + const void* ptr) override; void VertexAttribPointer(GLuint indx, GLint size, GLenum type, @@ -311,6 +539,7 @@ void VertexAttribPointer(GLuint indx, GLsizei stride, const void* ptr) override; void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override; +void WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override; void BlitFramebufferCHROMIUM(GLint srcX0, GLint srcY0, GLint srcX1, @@ -346,7 +575,9 @@ void GenQueriesEXT(GLsizei n, GLuint* queries) override; void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override; GLboolean IsQueryEXT(GLuint id) override; void BeginQueryEXT(GLenum target, GLuint id) override; +void BeginTransformFeedback(GLenum primitivemode) override; void EndQueryEXT(GLenum target) override; +void EndTransformFeedback() override; void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override; void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) override; void InsertEventMarkerEXT(GLsizei length, const GLchar* marker) override; @@ -369,6 +600,11 @@ void* MapBufferSubDataCHROMIUM(GLuint target, GLsizeiptr size, GLenum access) override; void UnmapBufferSubDataCHROMIUM(const void* mem) override; +void* MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) override; +GLboolean UnmapBuffer(GLenum target) override; void* MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, @@ -383,14 +619,22 @@ void ResizeCHROMIUM(GLuint width, GLuint height, GLfloat scale_factor) override; const GLchar* GetRequestableExtensionsCHROMIUM() override; void RequestExtensionCHROMIUM(const char* extension) override; void RateLimitOffscreenContextCHROMIUM() override; -void GetMultipleIntegervCHROMIUM(const GLenum* pnames, - GLuint count, - GLint* results, - GLsizeiptr size) override; void GetProgramInfoCHROMIUM(GLuint program, GLsizei bufsize, GLsizei* size, void* info) override; +void GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; +void GetTransformFeedbackVaryingsCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; +void GetUniformsES3CHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) override; GLuint CreateStreamTextureCHROMIUM(GLuint texture) override; GLuint CreateImageCHROMIUM(ClientBuffer buffer, GLsizei width, @@ -417,9 +661,13 @@ void TexImageIOSurface2DCHROMIUM(GLenum target, void CopyTextureCHROMIUM(GLenum target, GLenum source_id, GLenum dest_id, - GLint level, GLint internalformat, GLenum dest_type) override; +void CopySubTextureCHROMIUM(GLenum target, + GLenum source_id, + GLenum dest_id, + GLint xoffset, + GLint yoffset) override; void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, @@ -452,7 +700,8 @@ void UniformValuebufferCHROMIUM(GLint location, GLenum subscription) override; void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override; void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override; -void TraceBeginCHROMIUM(const char* name) override; +void TraceBeginCHROMIUM(const char* category_name, + const char* trace_name) override; void TraceEndCHROMIUM() override; void AsyncTexSubImage2DCHROMIUM(GLenum target, GLint level, @@ -493,6 +742,7 @@ void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order, GLfloat uv_y, GLfloat uv_width, GLfloat uv_height) override; +void SwapInterval(GLint interval) override; void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override; void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override; void BlendBarrierKHR() override; diff --git a/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index dd9d201d6a2..5d4641fb5f3 100644 --- a/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h @@ -34,6 +34,22 @@ void GLES2TraceImplementation::BindBuffer(GLenum target, GLuint buffer) { gl_->BindBuffer(target, buffer); } +void GLES2TraceImplementation::BindBufferBase(GLenum target, + GLuint index, + GLuint buffer) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindBufferBase"); + gl_->BindBufferBase(target, index, buffer); +} + +void GLES2TraceImplementation::BindBufferRange(GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindBufferRange"); + gl_->BindBufferRange(target, index, buffer, offset, size); +} + void GLES2TraceImplementation::BindFramebuffer(GLenum target, GLuint framebuffer) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindFramebuffer"); @@ -46,11 +62,22 @@ void GLES2TraceImplementation::BindRenderbuffer(GLenum target, gl_->BindRenderbuffer(target, renderbuffer); } +void GLES2TraceImplementation::BindSampler(GLuint unit, GLuint sampler) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindSampler"); + gl_->BindSampler(unit, sampler); +} + void GLES2TraceImplementation::BindTexture(GLenum target, GLuint texture) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindTexture"); gl_->BindTexture(target, texture); } +void GLES2TraceImplementation::BindTransformFeedback(GLenum target, + GLuint transformfeedback) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindTransformFeedback"); + gl_->BindTransformFeedback(target, transformfeedback); +} + void GLES2TraceImplementation::BlendColor(GLclampf red, GLclampf green, GLclampf blue, @@ -109,6 +136,35 @@ void GLES2TraceImplementation::Clear(GLbitfield mask) { gl_->Clear(mask); } +void GLES2TraceImplementation::ClearBufferfi(GLenum buffer, + GLint drawbuffers, + GLfloat depth, + GLint stencil) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ClearBufferfi"); + gl_->ClearBufferfi(buffer, drawbuffers, depth, stencil); +} + +void GLES2TraceImplementation::ClearBufferfv(GLenum buffer, + GLint drawbuffers, + const GLfloat* value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ClearBufferfv"); + gl_->ClearBufferfv(buffer, drawbuffers, value); +} + +void GLES2TraceImplementation::ClearBufferiv(GLenum buffer, + GLint drawbuffers, + const GLint* value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ClearBufferiv"); + gl_->ClearBufferiv(buffer, drawbuffers, value); +} + +void GLES2TraceImplementation::ClearBufferuiv(GLenum buffer, + GLint drawbuffers, + const GLuint* value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ClearBufferuiv"); + gl_->ClearBufferuiv(buffer, drawbuffers, value); +} + void GLES2TraceImplementation::ClearColor(GLclampf red, GLclampf green, GLclampf blue, @@ -127,6 +183,13 @@ void GLES2TraceImplementation::ClearStencil(GLint s) { gl_->ClearStencil(s); } +GLenum GLES2TraceImplementation::ClientWaitSync(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ClientWaitSync"); + return gl_->ClientWaitSync(sync, flags, timeout); +} + void GLES2TraceImplementation::ColorMask(GLboolean red, GLboolean green, GLboolean blue, @@ -167,6 +230,46 @@ void GLES2TraceImplementation::CompressedTexSubImage2D(GLenum target, format, imageSize, data); } +void GLES2TraceImplementation::CompressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void* data) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CompressedTexImage3D"); + gl_->CompressedTexImage3D(target, level, internalformat, width, height, depth, + border, imageSize, data); +} + +void GLES2TraceImplementation::CompressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void* data) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CompressedTexSubImage3D"); + gl_->CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, + height, depth, format, imageSize, data); +} + +void GLES2TraceImplementation::CopyBufferSubData(GLenum readtarget, + GLenum writetarget, + GLintptr readoffset, + GLintptr writeoffset, + GLsizeiptr size) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CopyBufferSubData"); + gl_->CopyBufferSubData(readtarget, writetarget, readoffset, writeoffset, + size); +} + void GLES2TraceImplementation::CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, @@ -192,6 +295,20 @@ void GLES2TraceImplementation::CopyTexSubImage2D(GLenum target, gl_->CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); } +void GLES2TraceImplementation::CopyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CopyTexSubImage3D"); + gl_->CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, + height); +} + GLuint GLES2TraceImplementation::CreateProgram() { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CreateProgram"); return gl_->CreateProgram(); @@ -230,6 +347,17 @@ void GLES2TraceImplementation::DeleteRenderbuffers( gl_->DeleteRenderbuffers(n, renderbuffers); } +void GLES2TraceImplementation::DeleteSamplers(GLsizei n, + const GLuint* samplers) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DeleteSamplers"); + gl_->DeleteSamplers(n, samplers); +} + +void GLES2TraceImplementation::DeleteSync(GLsync sync) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DeleteSync"); + gl_->DeleteSync(sync); +} + void GLES2TraceImplementation::DeleteShader(GLuint shader) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DeleteShader"); gl_->DeleteShader(shader); @@ -241,6 +369,12 @@ void GLES2TraceImplementation::DeleteTextures(GLsizei n, gl_->DeleteTextures(n, textures); } +void GLES2TraceImplementation::DeleteTransformFeedbacks(GLsizei n, + const GLuint* ids) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DeleteTransformFeedbacks"); + gl_->DeleteTransformFeedbacks(n, ids); +} + void GLES2TraceImplementation::DepthFunc(GLenum func) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DepthFunc"); gl_->DepthFunc(func); @@ -286,6 +420,16 @@ void GLES2TraceImplementation::DrawElements(GLenum mode, gl_->DrawElements(mode, count, type, indices); } +void GLES2TraceImplementation::DrawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void* indices) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DrawRangeElements"); + gl_->DrawRangeElements(mode, start, end, count, type, indices); +} + void GLES2TraceImplementation::Enable(GLenum cap) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Enable"); gl_->Enable(cap); @@ -296,6 +440,11 @@ void GLES2TraceImplementation::EnableVertexAttribArray(GLuint index) { gl_->EnableVertexAttribArray(index); } +GLsync GLES2TraceImplementation::FenceSync(GLenum condition, GLbitfield flags) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::FenceSync"); + return gl_->FenceSync(condition, flags); +} + void GLES2TraceImplementation::Finish() { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Finish"); gl_->Finish(); @@ -325,6 +474,15 @@ void GLES2TraceImplementation::FramebufferTexture2D(GLenum target, gl_->FramebufferTexture2D(target, attachment, textarget, texture, level); } +void GLES2TraceImplementation::FramebufferTextureLayer(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::FramebufferTextureLayer"); + gl_->FramebufferTextureLayer(target, attachment, texture, level, layer); +} + void GLES2TraceImplementation::FrontFace(GLenum mode) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::FrontFace"); gl_->FrontFace(mode); @@ -352,11 +510,21 @@ void GLES2TraceImplementation::GenRenderbuffers(GLsizei n, gl_->GenRenderbuffers(n, renderbuffers); } +void GLES2TraceImplementation::GenSamplers(GLsizei n, GLuint* samplers) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GenSamplers"); + gl_->GenSamplers(n, samplers); +} + void GLES2TraceImplementation::GenTextures(GLsizei n, GLuint* textures) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GenTextures"); gl_->GenTextures(n, textures); } +void GLES2TraceImplementation::GenTransformFeedbacks(GLsizei n, GLuint* ids) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GenTransformFeedbacks"); + gl_->GenTransformFeedbacks(n, ids); +} + void GLES2TraceImplementation::GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, @@ -379,6 +547,32 @@ void GLES2TraceImplementation::GetActiveUniform(GLuint program, gl_->GetActiveUniform(program, index, bufsize, length, size, type, name); } +void GLES2TraceImplementation::GetActiveUniformBlockiv(GLuint program, + GLuint index, + GLenum pname, + GLint* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetActiveUniformBlockiv"); + gl_->GetActiveUniformBlockiv(program, index, pname, params); +} + +void GLES2TraceImplementation::GetActiveUniformBlockName(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + char* name) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetActiveUniformBlockName"); + gl_->GetActiveUniformBlockName(program, index, bufsize, length, name); +} + +void GLES2TraceImplementation::GetActiveUniformsiv(GLuint program, + GLsizei count, + const GLuint* indices, + GLenum pname, + GLint* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetActiveUniformsiv"); + gl_->GetActiveUniformsiv(program, count, indices, pname, params); +} + void GLES2TraceImplementation::GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, @@ -415,6 +609,12 @@ void GLES2TraceImplementation::GetFloatv(GLenum pname, GLfloat* params) { gl_->GetFloatv(pname, params); } +GLint GLES2TraceImplementation::GetFragDataLocation(GLuint program, + const char* name) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetFragDataLocation"); + return gl_->GetFragDataLocation(program, name); +} + void GLES2TraceImplementation::GetFramebufferAttachmentParameteriv( GLenum target, GLenum attachment, @@ -425,11 +625,39 @@ void GLES2TraceImplementation::GetFramebufferAttachmentParameteriv( gl_->GetFramebufferAttachmentParameteriv(target, attachment, pname, params); } +void GLES2TraceImplementation::GetInteger64v(GLenum pname, GLint64* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetInteger64v"); + gl_->GetInteger64v(pname, params); +} + +void GLES2TraceImplementation::GetIntegeri_v(GLenum pname, + GLuint index, + GLint* data) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetIntegeri_v"); + gl_->GetIntegeri_v(pname, index, data); +} + +void GLES2TraceImplementation::GetInteger64i_v(GLenum pname, + GLuint index, + GLint64* data) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetInteger64i_v"); + gl_->GetInteger64i_v(pname, index, data); +} + void GLES2TraceImplementation::GetIntegerv(GLenum pname, GLint* params) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetIntegerv"); gl_->GetIntegerv(pname, params); } +void GLES2TraceImplementation::GetInternalformativ(GLenum target, + GLenum format, + GLenum pname, + GLsizei bufSize, + GLint* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetInternalformativ"); + gl_->GetInternalformativ(target, format, pname, bufSize, params); +} + void GLES2TraceImplementation::GetProgramiv(GLuint program, GLenum pname, GLint* params) { @@ -453,6 +681,20 @@ void GLES2TraceImplementation::GetRenderbufferParameteriv(GLenum target, gl_->GetRenderbufferParameteriv(target, pname, params); } +void GLES2TraceImplementation::GetSamplerParameterfv(GLuint sampler, + GLenum pname, + GLfloat* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetSamplerParameterfv"); + gl_->GetSamplerParameterfv(sampler, pname, params); +} + +void GLES2TraceImplementation::GetSamplerParameteriv(GLuint sampler, + GLenum pname, + GLint* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetSamplerParameteriv"); + gl_->GetSamplerParameteriv(sampler, pname, params); +} + void GLES2TraceImplementation::GetShaderiv(GLuint shader, GLenum pname, GLint* params) { @@ -489,6 +731,15 @@ const GLubyte* GLES2TraceImplementation::GetString(GLenum name) { return gl_->GetString(name); } +void GLES2TraceImplementation::GetSynciv(GLsync sync, + GLenum pname, + GLsizei bufsize, + GLsizei* length, + GLint* values) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetSynciv"); + gl_->GetSynciv(sync, pname, bufsize, length, values); +} + void GLES2TraceImplementation::GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { @@ -503,6 +754,25 @@ void GLES2TraceImplementation::GetTexParameteriv(GLenum target, gl_->GetTexParameteriv(target, pname, params); } +void GLES2TraceImplementation::GetTransformFeedbackVarying(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei* length, + GLsizei* size, + GLenum* type, + char* name) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", + "GLES2Trace::GetTransformFeedbackVarying"); + gl_->GetTransformFeedbackVarying(program, index, bufsize, length, size, type, + name); +} + +GLuint GLES2TraceImplementation::GetUniformBlockIndex(GLuint program, + const char* name) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetUniformBlockIndex"); + return gl_->GetUniformBlockIndex(program, name); +} + void GLES2TraceImplementation::GetUniformfv(GLuint program, GLint location, GLfloat* params) { @@ -517,6 +787,21 @@ void GLES2TraceImplementation::GetUniformiv(GLuint program, gl_->GetUniformiv(program, location, params); } +void GLES2TraceImplementation::GetUniformuiv(GLuint program, + GLint location, + GLuint* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetUniformuiv"); + gl_->GetUniformuiv(program, location, params); +} + +void GLES2TraceImplementation::GetUniformIndices(GLuint program, + GLsizei count, + const char* const* names, + GLuint* indices) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetUniformIndices"); + gl_->GetUniformIndices(program, count, names, indices); +} + GLint GLES2TraceImplementation::GetUniformLocation(GLuint program, const char* name) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetUniformLocation"); @@ -537,6 +822,20 @@ void GLES2TraceImplementation::GetVertexAttribiv(GLuint index, gl_->GetVertexAttribiv(index, pname, params); } +void GLES2TraceImplementation::GetVertexAttribIiv(GLuint index, + GLenum pname, + GLint* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetVertexAttribIiv"); + gl_->GetVertexAttribIiv(index, pname, params); +} + +void GLES2TraceImplementation::GetVertexAttribIuiv(GLuint index, + GLenum pname, + GLuint* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetVertexAttribIuiv"); + gl_->GetVertexAttribIuiv(index, pname, params); +} + void GLES2TraceImplementation::GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer) { @@ -549,6 +848,27 @@ void GLES2TraceImplementation::Hint(GLenum target, GLenum mode) { gl_->Hint(target, mode); } +void GLES2TraceImplementation::InvalidateFramebuffer( + GLenum target, + GLsizei count, + const GLenum* attachments) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::InvalidateFramebuffer"); + gl_->InvalidateFramebuffer(target, count, attachments); +} + +void GLES2TraceImplementation::InvalidateSubFramebuffer( + GLenum target, + GLsizei count, + const GLenum* attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::InvalidateSubFramebuffer"); + gl_->InvalidateSubFramebuffer(target, count, attachments, x, y, width, + height); +} + GLboolean GLES2TraceImplementation::IsBuffer(GLuint buffer) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsBuffer"); return gl_->IsBuffer(buffer); @@ -574,16 +894,32 @@ GLboolean GLES2TraceImplementation::IsRenderbuffer(GLuint renderbuffer) { return gl_->IsRenderbuffer(renderbuffer); } +GLboolean GLES2TraceImplementation::IsSampler(GLuint sampler) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsSampler"); + return gl_->IsSampler(sampler); +} + GLboolean GLES2TraceImplementation::IsShader(GLuint shader) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsShader"); return gl_->IsShader(shader); } +GLboolean GLES2TraceImplementation::IsSync(GLsync sync) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsSync"); + return gl_->IsSync(sync); +} + GLboolean GLES2TraceImplementation::IsTexture(GLuint texture) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsTexture"); return gl_->IsTexture(texture); } +GLboolean GLES2TraceImplementation::IsTransformFeedback( + GLuint transformfeedback) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsTransformFeedback"); + return gl_->IsTransformFeedback(transformfeedback); +} + void GLES2TraceImplementation::LineWidth(GLfloat width) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::LineWidth"); gl_->LineWidth(width); @@ -594,6 +930,11 @@ void GLES2TraceImplementation::LinkProgram(GLuint program) { gl_->LinkProgram(program); } +void GLES2TraceImplementation::PauseTransformFeedback() { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::PauseTransformFeedback"); + gl_->PauseTransformFeedback(); +} + void GLES2TraceImplementation::PixelStorei(GLenum pname, GLint param) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::PixelStorei"); gl_->PixelStorei(pname, param); @@ -604,6 +945,11 @@ void GLES2TraceImplementation::PolygonOffset(GLfloat factor, GLfloat units) { gl_->PolygonOffset(factor, units); } +void GLES2TraceImplementation::ReadBuffer(GLenum src) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ReadBuffer"); + gl_->ReadBuffer(src); +} + void GLES2TraceImplementation::ReadPixels(GLint x, GLint y, GLsizei width, @@ -628,12 +974,45 @@ void GLES2TraceImplementation::RenderbufferStorage(GLenum target, gl_->RenderbufferStorage(target, internalformat, width, height); } +void GLES2TraceImplementation::ResumeTransformFeedback() { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ResumeTransformFeedback"); + gl_->ResumeTransformFeedback(); +} + void GLES2TraceImplementation::SampleCoverage(GLclampf value, GLboolean invert) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SampleCoverage"); gl_->SampleCoverage(value, invert); } +void GLES2TraceImplementation::SamplerParameterf(GLuint sampler, + GLenum pname, + GLfloat param) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SamplerParameterf"); + gl_->SamplerParameterf(sampler, pname, param); +} + +void GLES2TraceImplementation::SamplerParameterfv(GLuint sampler, + GLenum pname, + const GLfloat* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SamplerParameterfv"); + gl_->SamplerParameterfv(sampler, pname, params); +} + +void GLES2TraceImplementation::SamplerParameteri(GLuint sampler, + GLenum pname, + GLint param) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SamplerParameteri"); + gl_->SamplerParameteri(sampler, pname, param); +} + +void GLES2TraceImplementation::SamplerParameteriv(GLuint sampler, + GLenum pname, + const GLint* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SamplerParameteriv"); + gl_->SamplerParameteriv(sampler, pname, params); +} + void GLES2TraceImplementation::Scissor(GLint x, GLint y, GLsizei width, @@ -669,6 +1048,11 @@ void GLES2TraceImplementation::ShallowFlushCHROMIUM() { gl_->ShallowFlushCHROMIUM(); } +void GLES2TraceImplementation::OrderingBarrierCHROMIUM() { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::OrderingBarrierCHROMIUM"); + gl_->OrderingBarrierCHROMIUM(); +} + void GLES2TraceImplementation::StencilFunc(GLenum func, GLint ref, GLuint mask) { @@ -723,6 +1107,21 @@ void GLES2TraceImplementation::TexImage2D(GLenum target, type, pixels); } +void GLES2TraceImplementation::TexImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void* pixels) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::TexImage3D"); + gl_->TexImage3D(target, level, internalformat, width, height, depth, border, + format, type, pixels); +} + void GLES2TraceImplementation::TexParameterf(GLenum target, GLenum pname, GLfloat param) { @@ -751,6 +1150,16 @@ void GLES2TraceImplementation::TexParameteriv(GLenum target, gl_->TexParameteriv(target, pname, params); } +void GLES2TraceImplementation::TexStorage3D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::TexStorage3D"); + gl_->TexStorage3D(target, levels, internalFormat, width, height, depth); +} + void GLES2TraceImplementation::TexSubImage2D(GLenum target, GLint level, GLint xoffset, @@ -765,6 +1174,31 @@ void GLES2TraceImplementation::TexSubImage2D(GLenum target, type, pixels); } +void GLES2TraceImplementation::TexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void* pixels) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::TexSubImage3D"); + gl_->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, + depth, format, type, pixels); +} + +void GLES2TraceImplementation::TransformFeedbackVaryings( + GLuint program, + GLsizei count, + const char* const* varyings, + GLenum buffermode) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::TransformFeedbackVaryings"); + gl_->TransformFeedbackVaryings(program, count, varyings, buffermode); +} + void GLES2TraceImplementation::Uniform1f(GLint location, GLfloat x) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Uniform1f"); gl_->Uniform1f(location, x); @@ -789,6 +1223,18 @@ void GLES2TraceImplementation::Uniform1iv(GLint location, gl_->Uniform1iv(location, count, v); } +void GLES2TraceImplementation::Uniform1ui(GLint location, GLuint x) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Uniform1ui"); + gl_->Uniform1ui(location, x); +} + +void GLES2TraceImplementation::Uniform1uiv(GLint location, + GLsizei count, + const GLuint* v) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Uniform1uiv"); + gl_->Uniform1uiv(location, count, v); +} + void GLES2TraceImplementation::Uniform2f(GLint location, GLfloat x, GLfloat y) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Uniform2f"); gl_->Uniform2f(location, x, y); @@ -813,6 +1259,18 @@ void GLES2TraceImplementation::Uniform2iv(GLint location, gl_->Uniform2iv(location, count, v); } +void GLES2TraceImplementation::Uniform2ui(GLint location, GLuint x, GLuint y) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Uniform2ui"); + gl_->Uniform2ui(location, x, y); +} + +void GLES2TraceImplementation::Uniform2uiv(GLint location, + GLsizei count, + const GLuint* v) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Uniform2uiv"); + gl_->Uniform2uiv(location, count, v); +} + void GLES2TraceImplementation::Uniform3f(GLint location, GLfloat x, GLfloat y, @@ -843,6 +1301,21 @@ void GLES2TraceImplementation::Uniform3iv(GLint location, gl_->Uniform3iv(location, count, v); } +void GLES2TraceImplementation::Uniform3ui(GLint location, + GLuint x, + GLuint y, + GLuint z) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Uniform3ui"); + gl_->Uniform3ui(location, x, y, z); +} + +void GLES2TraceImplementation::Uniform3uiv(GLint location, + GLsizei count, + const GLuint* v) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Uniform3uiv"); + gl_->Uniform3uiv(location, count, v); +} + void GLES2TraceImplementation::Uniform4f(GLint location, GLfloat x, GLfloat y, @@ -875,6 +1348,29 @@ void GLES2TraceImplementation::Uniform4iv(GLint location, gl_->Uniform4iv(location, count, v); } +void GLES2TraceImplementation::Uniform4ui(GLint location, + GLuint x, + GLuint y, + GLuint z, + GLuint w) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Uniform4ui"); + gl_->Uniform4ui(location, x, y, z, w); +} + +void GLES2TraceImplementation::Uniform4uiv(GLint location, + GLsizei count, + const GLuint* v) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Uniform4uiv"); + gl_->Uniform4uiv(location, count, v); +} + +void GLES2TraceImplementation::UniformBlockBinding(GLuint program, + GLuint index, + GLuint binding) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UniformBlockBinding"); + gl_->UniformBlockBinding(program, index, binding); +} + void GLES2TraceImplementation::UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, @@ -883,6 +1379,22 @@ void GLES2TraceImplementation::UniformMatrix2fv(GLint location, gl_->UniformMatrix2fv(location, count, transpose, value); } +void GLES2TraceImplementation::UniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UniformMatrix2x3fv"); + gl_->UniformMatrix2x3fv(location, count, transpose, value); +} + +void GLES2TraceImplementation::UniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UniformMatrix2x4fv"); + gl_->UniformMatrix2x4fv(location, count, transpose, value); +} + void GLES2TraceImplementation::UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, @@ -891,6 +1403,22 @@ void GLES2TraceImplementation::UniformMatrix3fv(GLint location, gl_->UniformMatrix3fv(location, count, transpose, value); } +void GLES2TraceImplementation::UniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UniformMatrix3x2fv"); + gl_->UniformMatrix3x2fv(location, count, transpose, value); +} + +void GLES2TraceImplementation::UniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UniformMatrix3x4fv"); + gl_->UniformMatrix3x4fv(location, count, transpose, value); +} + void GLES2TraceImplementation::UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, @@ -899,6 +1427,22 @@ void GLES2TraceImplementation::UniformMatrix4fv(GLint location, gl_->UniformMatrix4fv(location, count, transpose, value); } +void GLES2TraceImplementation::UniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UniformMatrix4x2fv"); + gl_->UniformMatrix4x2fv(location, count, transpose, value); +} + +void GLES2TraceImplementation::UniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UniformMatrix4x3fv"); + gl_->UniformMatrix4x3fv(location, count, transpose, value); +} + void GLES2TraceImplementation::UseProgram(GLuint program) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UseProgram"); gl_->UseProgram(program); @@ -962,6 +1506,45 @@ void GLES2TraceImplementation::VertexAttrib4fv(GLuint indx, gl_->VertexAttrib4fv(indx, values); } +void GLES2TraceImplementation::VertexAttribI4i(GLuint indx, + GLint x, + GLint y, + GLint z, + GLint w) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::VertexAttribI4i"); + gl_->VertexAttribI4i(indx, x, y, z, w); +} + +void GLES2TraceImplementation::VertexAttribI4iv(GLuint indx, + const GLint* values) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::VertexAttribI4iv"); + gl_->VertexAttribI4iv(indx, values); +} + +void GLES2TraceImplementation::VertexAttribI4ui(GLuint indx, + GLuint x, + GLuint y, + GLuint z, + GLuint w) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::VertexAttribI4ui"); + gl_->VertexAttribI4ui(indx, x, y, z, w); +} + +void GLES2TraceImplementation::VertexAttribI4uiv(GLuint indx, + const GLuint* values) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::VertexAttribI4uiv"); + gl_->VertexAttribI4uiv(indx, values); +} + +void GLES2TraceImplementation::VertexAttribIPointer(GLuint indx, + GLint size, + GLenum type, + GLsizei stride, + const void* ptr) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::VertexAttribIPointer"); + gl_->VertexAttribIPointer(indx, size, type, stride, ptr); +} + void GLES2TraceImplementation::VertexAttribPointer(GLuint indx, GLint size, GLenum type, @@ -980,6 +1563,13 @@ void GLES2TraceImplementation::Viewport(GLint x, gl_->Viewport(x, y, width, height); } +void GLES2TraceImplementation::WaitSync(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::WaitSync"); + gl_->WaitSync(sync, flags, timeout); +} + void GLES2TraceImplementation::BlitFramebufferCHROMIUM(GLint srcX0, GLint srcY0, GLint srcX1, @@ -1062,11 +1652,21 @@ void GLES2TraceImplementation::BeginQueryEXT(GLenum target, GLuint id) { gl_->BeginQueryEXT(target, id); } +void GLES2TraceImplementation::BeginTransformFeedback(GLenum primitivemode) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BeginTransformFeedback"); + gl_->BeginTransformFeedback(primitivemode); +} + void GLES2TraceImplementation::EndQueryEXT(GLenum target) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::EndQueryEXT"); gl_->EndQueryEXT(target); } +void GLES2TraceImplementation::EndTransformFeedback() { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::EndTransformFeedback"); + gl_->EndTransformFeedback(); +} + void GLES2TraceImplementation::GetQueryivEXT(GLenum target, GLenum pname, GLint* params) { @@ -1163,6 +1763,19 @@ void GLES2TraceImplementation::UnmapBufferSubDataCHROMIUM(const void* mem) { gl_->UnmapBufferSubDataCHROMIUM(mem); } +void* GLES2TraceImplementation::MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::MapBufferRange"); + return gl_->MapBufferRange(target, offset, size, access); +} + +GLboolean GLES2TraceImplementation::UnmapBuffer(GLenum target) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UnmapBuffer"); + return gl_->UnmapBuffer(target); +} + void* GLES2TraceImplementation::MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, @@ -1207,15 +1820,6 @@ void GLES2TraceImplementation::RateLimitOffscreenContextCHROMIUM() { gl_->RateLimitOffscreenContextCHROMIUM(); } -void GLES2TraceImplementation::GetMultipleIntegervCHROMIUM(const GLenum* pnames, - GLuint count, - GLint* results, - GLsizeiptr size) { - TRACE_EVENT_BINARY_EFFICIENT0("gpu", - "GLES2Trace::GetMultipleIntegervCHROMIUM"); - gl_->GetMultipleIntegervCHROMIUM(pnames, count, results, size); -} - void GLES2TraceImplementation::GetProgramInfoCHROMIUM(GLuint program, GLsizei bufsize, GLsizei* size, @@ -1224,6 +1828,32 @@ void GLES2TraceImplementation::GetProgramInfoCHROMIUM(GLuint program, gl_->GetProgramInfoCHROMIUM(program, bufsize, size, info); } +void GLES2TraceImplementation::GetUniformBlocksCHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetUniformBlocksCHROMIUM"); + gl_->GetUniformBlocksCHROMIUM(program, bufsize, size, info); +} + +void GLES2TraceImplementation::GetTransformFeedbackVaryingsCHROMIUM( + GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) { + TRACE_EVENT_BINARY_EFFICIENT0( + "gpu", "GLES2Trace::GetTransformFeedbackVaryingsCHROMIUM"); + gl_->GetTransformFeedbackVaryingsCHROMIUM(program, bufsize, size, info); +} + +void GLES2TraceImplementation::GetUniformsES3CHROMIUM(GLuint program, + GLsizei bufsize, + GLsizei* size, + void* info) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetUniformsES3CHROMIUM"); + gl_->GetUniformsES3CHROMIUM(program, bufsize, size, info); +} + GLuint GLES2TraceImplementation::CreateStreamTextureCHROMIUM(GLuint texture) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CreateStreamTextureCHROMIUM"); @@ -1284,14 +1914,22 @@ void GLES2TraceImplementation::TexImageIOSurface2DCHROMIUM(GLenum target, void GLES2TraceImplementation::CopyTextureCHROMIUM(GLenum target, GLenum source_id, GLenum dest_id, - GLint level, GLint internalformat, GLenum dest_type) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CopyTextureCHROMIUM"); - gl_->CopyTextureCHROMIUM(target, source_id, dest_id, level, internalformat, + gl_->CopyTextureCHROMIUM(target, source_id, dest_id, internalformat, dest_type); } +void GLES2TraceImplementation::CopySubTextureCHROMIUM(GLenum target, + GLenum source_id, + GLenum dest_id, + GLint xoffset, + GLint yoffset) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CopySubTextureCHROMIUM"); + gl_->CopySubTextureCHROMIUM(target, source_id, dest_id, xoffset, yoffset); +} + void GLES2TraceImplementation::DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, @@ -1415,9 +2053,10 @@ void GLES2TraceImplementation::ReleaseTexImage2DCHROMIUM(GLenum target, gl_->ReleaseTexImage2DCHROMIUM(target, imageId); } -void GLES2TraceImplementation::TraceBeginCHROMIUM(const char* name) { +void GLES2TraceImplementation::TraceBeginCHROMIUM(const char* category_name, + const char* trace_name) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::TraceBeginCHROMIUM"); - gl_->TraceBeginCHROMIUM(name); + gl_->TraceBeginCHROMIUM(category_name, trace_name); } void GLES2TraceImplementation::TraceEndCHROMIUM() { @@ -1520,6 +2159,11 @@ void GLES2TraceImplementation::ScheduleOverlayPlaneCHROMIUM( bounds_width, bounds_height, uv_x, uv_y, uv_width, uv_height); } +void GLES2TraceImplementation::SwapInterval(GLint interval) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SwapInterval"); + gl_->SwapInterval(interval); +} + void GLES2TraceImplementation::MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::MatrixLoadfCHROMIUM"); diff --git a/chromium/gpu/command_buffer/client/gpu_control.h b/chromium/gpu/command_buffer/client/gpu_control.h index a56bd516fc5..2b303b3b4d5 100644 --- a/chromium/gpu/command_buffer/client/gpu_control.h +++ b/chromium/gpu/command_buffer/client/gpu_control.h @@ -17,6 +17,10 @@ extern "C" typedef struct _ClientBuffer* ClientBuffer; +namespace base { +class Lock; +} + namespace gfx { class GpuMemoryBuffer; } @@ -75,6 +79,12 @@ class GPU_EXPORT GpuControl { // returns a stream identifier. virtual uint32_t CreateStreamTexture(uint32_t texture_id) = 0; + // Sets a lock this will be held on every callback from the GPU + // implementation. This lock must be set and must be held on every call into + // the GPU implementation if it is to be used from multiple threads. This + // may not be supported with all implementations. + virtual void SetLock(base::Lock*) = 0; + private: DISALLOW_COPY_AND_ASSIGN(GpuControl); }; diff --git a/chromium/gpu/command_buffer/client/mapped_memory.cc b/chromium/gpu/command_buffer/client/mapped_memory.cc index fc6ca5dad9a..6d57af4ed57 100644 --- a/chromium/gpu/command_buffer/client/mapped_memory.cc +++ b/chromium/gpu/command_buffer/client/mapped_memory.cc @@ -7,8 +7,8 @@ #include <algorithm> #include <functional> -#include "base/debug/trace_event.h" #include "base/logging.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" namespace gpu { @@ -26,7 +26,7 @@ MemoryChunk::~MemoryChunk() {} MappedMemoryManager::MappedMemoryManager(CommandBufferHelper* helper, const base::Closure& poll_callback, size_t unused_memory_reclaim_limit) - : chunk_size_multiple_(1), + : chunk_size_multiple_(FencedAllocator::kAllocAlignment), helper_(helper), poll_callback_(poll_callback), allocated_memory_(0), diff --git a/chromium/gpu/command_buffer/client/mapped_memory.h b/chromium/gpu/command_buffer/client/mapped_memory.h index 789e69cf7f8..10ac639929f 100644 --- a/chromium/gpu/command_buffer/client/mapped_memory.h +++ b/chromium/gpu/command_buffer/client/mapped_memory.h @@ -135,6 +135,7 @@ class GPU_EXPORT MappedMemoryManager { } void set_chunk_size_multiple(unsigned int multiple) { + DCHECK(multiple % FencedAllocator::kAllocAlignment == 0); chunk_size_multiple_ = multiple; } @@ -201,4 +202,3 @@ class GPU_EXPORT MappedMemoryManager { } // namespace gpu #endif // GPU_COMMAND_BUFFER_CLIENT_MAPPED_MEMORY_H_ - diff --git a/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc b/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc index 9d5badac656..6430b667d3f 100644 --- a/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc +++ b/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc @@ -15,10 +15,6 @@ #include "gpu/command_buffer/service/transfer_buffer_manager.h" #include "testing/gtest/include/gtest/gtest.h" -#if defined(OS_MACOSX) -#include "base/mac/scoped_nsautorelease_pool.h" -#endif - namespace gpu { using testing::Return; @@ -71,10 +67,6 @@ class MappedMemoryTestBase : public testing::Test { return command_buffer_->GetLastState().token; } -#if defined(OS_MACOSX) - base::mac::ScopedNSAutoreleasePool autorelease_pool_; -#endif - base::MessageLoop message_loop_; scoped_ptr<AsyncAPIMock> api_mock_; scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; scoped_ptr<CommandBufferService> command_buffer_; diff --git a/chromium/gpu/command_buffer/client/program_info_manager.cc b/chromium/gpu/command_buffer/client/program_info_manager.cc index c0f8600aa87..89e8913a63a 100644 --- a/chromium/gpu/command_buffer/client/program_info_manager.cc +++ b/chromium/gpu/command_buffer/client/program_info_manager.cc @@ -4,243 +4,94 @@ #include "gpu/command_buffer/client/program_info_manager.h" -#include <map> +namespace { -#include "base/compiler_specific.h" -#include "base/synchronization/lock.h" -#include "gpu/command_buffer/client/gles2_implementation.h" -#include "gpu/command_buffer/common/gles2_cmd_utils.h" +template<typename T> static T LocalGetAs( + const std::vector<int8>& data, uint32 offset, size_t size) { + const int8* p = &data[0] + offset; + if (offset + size > data.size()) { + NOTREACHED(); + return NULL; + } + return static_cast<T>(static_cast<const void*>(p)); +} + +} // namespace anonymous namespace gpu { namespace gles2 { -class NonCachedProgramInfoManager : public ProgramInfoManager { - public: - NonCachedProgramInfoManager(); - ~NonCachedProgramInfoManager() override; - - void CreateInfo(GLuint program) override; - - void DeleteInfo(GLuint program) override; - - bool GetProgramiv(GLES2Implementation* gl, - GLuint program, - GLenum pname, - GLint* params) override; - - GLint GetAttribLocation(GLES2Implementation* gl, - GLuint program, - const char* name) override; - - GLint GetUniformLocation(GLES2Implementation* gl, - GLuint program, - const char* name) override; - - bool GetActiveAttrib(GLES2Implementation* gl, - GLuint program, - GLuint index, - GLsizei bufsize, - GLsizei* length, - GLint* size, - GLenum* type, - char* name) override; - - bool GetActiveUniform(GLES2Implementation* gl, - GLuint program, - GLuint index, - GLsizei bufsize, - GLsizei* length, - GLint* size, - GLenum* type, - char* name) override; -}; - -NonCachedProgramInfoManager::NonCachedProgramInfoManager() { +ProgramInfoManager::Program::VertexAttrib::VertexAttrib( + GLsizei _size, GLenum _type, const std::string& _name, GLint _location) + : size(_size), + type(_type), + location(_location), + name(_name) { } -NonCachedProgramInfoManager::~NonCachedProgramInfoManager() { +ProgramInfoManager::Program::VertexAttrib::~VertexAttrib() { } -void NonCachedProgramInfoManager::CreateInfo(GLuint /* program */) { +ProgramInfoManager::Program::UniformInfo::UniformInfo( + GLsizei _size, GLenum _type, const std::string& _name) + : size(_size), + type(_type), + name(_name) { + is_array = (!name.empty() && name[name.size() - 1] == ']'); + DCHECK(!(size > 1 && !is_array)); } -void NonCachedProgramInfoManager::DeleteInfo(GLuint /* program */) { +ProgramInfoManager::Program::UniformInfo::~UniformInfo() { } -bool NonCachedProgramInfoManager::GetProgramiv( - GLES2Implementation* /* gl */, - GLuint /* program */, - GLenum /* pname */, - GLint* /* params */) { - return false; +ProgramInfoManager::Program::UniformES3::UniformES3() + : block_index(-1), + offset(-1), + array_stride(-1), + matrix_stride(-1), + is_row_major(0) { } -GLint NonCachedProgramInfoManager::GetAttribLocation( - GLES2Implementation* gl, GLuint program, const char* name) { - return gl->GetAttribLocationHelper(program, name); +ProgramInfoManager::Program::UniformES3::~UniformES3() { } -GLint NonCachedProgramInfoManager::GetUniformLocation( - GLES2Implementation* gl, GLuint program, const char* name) { - return gl->GetUniformLocationHelper(program, name); +ProgramInfoManager::Program::UniformBlock::UniformBlock() + : binding(0), + data_size(0), + referenced_by_vertex_shader(false), + referenced_by_fragment_shader(false) { } -bool NonCachedProgramInfoManager::GetActiveAttrib( - GLES2Implementation* gl, - GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, - GLint* size, GLenum* type, char* name) { - return gl->GetActiveAttribHelper( - program, index, bufsize, length, size, type, name); +ProgramInfoManager::Program::UniformBlock::~UniformBlock() { } -bool NonCachedProgramInfoManager::GetActiveUniform( - GLES2Implementation* gl, - GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, - GLint* size, GLenum* type, char* name) { - return gl->GetActiveUniformHelper( - program, index, bufsize, length, size, type, name); +ProgramInfoManager::Program::TransformFeedbackVarying:: +TransformFeedbackVarying() + : size(0), + type(0) { } -class CachedProgramInfoManager : public ProgramInfoManager { - public: - CachedProgramInfoManager(); - ~CachedProgramInfoManager() override; - - void CreateInfo(GLuint program) override; - - void DeleteInfo(GLuint program) override; - - bool GetProgramiv(GLES2Implementation* gl, - GLuint program, - GLenum pname, - GLint* params) override; - - GLint GetAttribLocation(GLES2Implementation* gl, - GLuint program, - const char* name) override; - - GLint GetUniformLocation(GLES2Implementation* gl, - GLuint program, - const char* name) override; - - bool GetActiveAttrib(GLES2Implementation* gl, - GLuint program, - GLuint index, - GLsizei bufsize, - GLsizei* length, - GLint* size, - GLenum* type, - char* name) override; - - bool GetActiveUniform(GLES2Implementation* gl, - GLuint program, - GLuint index, - GLsizei bufsize, - GLsizei* length, - GLint* size, - GLenum* type, - char* name) override; - - private: - class Program { - public: - struct UniformInfo { - UniformInfo(GLsizei _size, GLenum _type, const std::string& _name); - - GLsizei size; - GLenum type; - bool is_array; - std::string name; - std::vector<GLint> element_locations; - }; - struct VertexAttrib { - VertexAttrib(GLsizei _size, GLenum _type, const std::string& _name, - GLint _location) - : size(_size), - type(_type), - location(_location), - name(_name) { - } - GLsizei size; - GLenum type; - GLint location; - std::string name; - }; - - typedef std::vector<UniformInfo> UniformInfoVector; - typedef std::vector<VertexAttrib> AttribInfoVector; - - Program(); - - const AttribInfoVector& GetAttribInfos() const { - return attrib_infos_; - } - - const VertexAttrib* GetAttribInfo(GLint index) const { - return (static_cast<size_t>(index) < attrib_infos_.size()) ? - &attrib_infos_[index] : NULL; - } - - GLint GetAttribLocation(const std::string& name) const; - - const UniformInfo* GetUniformInfo(GLint index) const { - return (static_cast<size_t>(index) < uniform_infos_.size()) ? - &uniform_infos_[index] : NULL; - } - - // Gets the location of a uniform by name. - GLint GetUniformLocation(const std::string& name) const; - - bool GetProgramiv(GLenum pname, GLint* params); - - // Updates the program info after a successful link. - void Update(GLES2Implementation* gl, GLuint program); - - private: - bool cached_; - - GLsizei max_attrib_name_length_; - - // Attrib by index. - AttribInfoVector attrib_infos_; - - GLsizei max_uniform_name_length_; - - // Uniform info by index. - UniformInfoVector uniform_infos_; - - // This is true if glLinkProgram was successful last time it was called. - bool link_status_; - }; - - Program* GetProgramInfo(GLES2Implementation* gl, GLuint program); - - // TODO(gman): Switch to a faster container. - typedef std::map<GLuint, Program> ProgramInfoMap; - - ProgramInfoMap program_infos_; - - mutable base::Lock lock_; -}; - -CachedProgramInfoManager::Program::UniformInfo::UniformInfo( - GLsizei _size, GLenum _type, const std::string& _name) - : size(_size), - type(_type), - name(_name) { - is_array = (!name.empty() && name[name.size() - 1] == ']'); - DCHECK(!(size > 1 && !is_array)); +ProgramInfoManager::Program::TransformFeedbackVarying:: +~TransformFeedbackVarying() { } -CachedProgramInfoManager::Program::Program() - : cached_(false), +ProgramInfoManager::Program::Program() + : cached_es2_(false), max_attrib_name_length_(0), max_uniform_name_length_(0), - link_status_(false) { + link_status_(false), + cached_es3_uniform_blocks_(false), + active_uniform_block_max_name_length_(0), + cached_es3_transform_feedback_varyings_(false), + transform_feedback_varying_max_length_(0), + cached_es3_uniformsiv_(false) { +} + +ProgramInfoManager::Program::~Program() { } // TODO(gman): Add a faster lookup. -GLint CachedProgramInfoManager::Program::GetAttribLocation( +GLint ProgramInfoManager::Program::GetAttribLocation( const std::string& name) const { for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { const VertexAttrib& info = attrib_infos_[ii]; @@ -251,7 +102,24 @@ GLint CachedProgramInfoManager::Program::GetAttribLocation( return -1; } -GLint CachedProgramInfoManager::Program::GetUniformLocation( +const ProgramInfoManager::Program::VertexAttrib* +ProgramInfoManager::Program::GetAttribInfo(GLint index) const { + return (static_cast<size_t>(index) < attrib_infos_.size()) ? + &attrib_infos_[index] : NULL; +} + +const ProgramInfoManager::Program::UniformInfo* +ProgramInfoManager::Program::GetUniformInfo(GLint index) const { + return (static_cast<size_t>(index) < uniform_infos_.size()) ? + &uniform_infos_[index] : NULL; +} + +const ProgramInfoManager::Program::UniformBlock* +ProgramInfoManager::Program::GetUniformBlock(GLuint index) const { + return (index < uniform_blocks_.size()) ? &uniform_blocks_[index] : NULL; +} + +GLint ProgramInfoManager::Program::GetUniformLocation( const std::string& name) const { bool getting_array_location = false; size_t open_pos = std::string::npos; @@ -280,47 +148,179 @@ GLint CachedProgramInfoManager::Program::GetUniformLocation( return -1; } -bool CachedProgramInfoManager::Program::GetProgramiv( +GLuint ProgramInfoManager::Program::GetUniformIndex( + const std::string& name) const { + // TODO(zmo): Maybe build a hashed_map for faster lookup. + for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { + const UniformInfo& info = uniform_infos_[ii]; + // For an array, either "var" or "var[0]" is considered as a match. + // See "OpenGL ES 3.0.0, Section 2.11.3 Program Objects." + if (info.name == name || + (info.is_array && + info.name.compare(0, info.name.size() - 3, name) == 0)) { + return ii; + } + } + return GL_INVALID_INDEX; +} + +GLint ProgramInfoManager::Program::GetFragDataLocation( + const std::string& name) const { + base::hash_map<std::string, GLint>::const_iterator iter = + frag_data_locations_.find(name); + if (iter == frag_data_locations_.end()) + return -1; + return iter->second; +} + +void ProgramInfoManager::Program::CacheFragDataLocation( + const std::string& name, GLint loc) { + frag_data_locations_[name] = loc; +} + +bool ProgramInfoManager::Program::GetProgramiv( GLenum pname, GLint* params) { switch (pname) { case GL_LINK_STATUS: - *params = link_status_; + *params = static_cast<GLint>(link_status_); return true; case GL_ACTIVE_ATTRIBUTES: - *params = attrib_infos_.size(); + *params = static_cast<GLint>(attrib_infos_.size()); return true; case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = max_attrib_name_length_; + *params = static_cast<GLint>(max_attrib_name_length_); return true; case GL_ACTIVE_UNIFORMS: - *params = uniform_infos_.size(); + *params = static_cast<GLint>(uniform_infos_.size()); return true; case GL_ACTIVE_UNIFORM_MAX_LENGTH: - *params = max_uniform_name_length_; + *params = static_cast<GLint>(max_uniform_name_length_); + return true; + case GL_ACTIVE_UNIFORM_BLOCKS: + *params = static_cast<GLint>(uniform_blocks_.size()); + return true; + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + *params = static_cast<GLint>(active_uniform_block_max_name_length_); + return true; + case GL_TRANSFORM_FEEDBACK_VARYINGS: + *params = static_cast<GLint>(transform_feedback_varyings_.size()); + return true; + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + *params = static_cast<GLint>(transform_feedback_varying_max_length_); return true; default: + NOTREACHED(); break; } return false; } -template<typename T> static T LocalGetAs( - const std::vector<int8>& data, uint32 offset, size_t size) { - const int8* p = &data[0] + offset; - if (offset + size > data.size()) { - NOTREACHED(); - return NULL; +GLuint ProgramInfoManager::Program::GetUniformBlockIndex( + const std::string& name) const { + for (size_t ii = 0; ii < uniform_blocks_.size(); ++ii) { + if (uniform_blocks_[ii].name == name) { + return static_cast<GLuint>(ii); + } } - return static_cast<T>(static_cast<const void*>(p)); + return GL_INVALID_INDEX; +} + +void ProgramInfoManager::Program::UniformBlockBinding( + GLuint index , GLuint binding) { + if (index < uniform_blocks_.size()) { + uniform_blocks_[index].binding = binding; + } +} + +const ProgramInfoManager::Program::TransformFeedbackVarying* +ProgramInfoManager::Program::GetTransformFeedbackVarying(GLuint index) const { + return (index < transform_feedback_varyings_.size()) ? + &transform_feedback_varyings_[index] : NULL; } -void CachedProgramInfoManager::Program::Update( - GLES2Implementation* gl, GLuint program) { - if (cached_) { +bool ProgramInfoManager::Program::GetUniformsiv( + GLsizei count, const GLuint* indices, GLenum pname, GLint* params) { + if (count == 0) { + // At this point, pname has already been validated. + return true; + } + DCHECK(count > 0 && indices); + size_t num_uniforms = uniform_infos_.size(); + if (num_uniforms == 0) { + num_uniforms = uniforms_es3_.size(); + } + if (static_cast<size_t>(count) > num_uniforms) { + return false; + } + for (GLsizei ii = 0; ii < count; ++ii) { + if (indices[ii] >= num_uniforms) { + return false; + } + } + if (!params) { + return true; + } + switch (pname) { + case GL_UNIFORM_SIZE: + DCHECK_EQ(num_uniforms, uniform_infos_.size()); + for (GLsizei ii = 0; ii < count; ++ii) { + params[ii] = static_cast<GLint>(uniform_infos_[indices[ii]].size); + } + return true; + case GL_UNIFORM_TYPE: + DCHECK_EQ(num_uniforms, uniform_infos_.size()); + for (GLsizei ii = 0; ii < count; ++ii) { + params[ii] = static_cast<GLint>(uniform_infos_[indices[ii]].type); + } + return true; + case GL_UNIFORM_NAME_LENGTH: + DCHECK_EQ(num_uniforms, uniform_infos_.size()); + for (GLsizei ii = 0; ii < count; ++ii) { + params[ii] = static_cast<GLint>( + uniform_infos_[indices[ii]].name.length() + 1); + } + return true; + case GL_UNIFORM_BLOCK_INDEX: + DCHECK_EQ(num_uniforms, uniforms_es3_.size()); + for (GLsizei ii = 0; ii < count; ++ii) { + params[ii] = uniforms_es3_[indices[ii]].block_index; + } + return true; + case GL_UNIFORM_OFFSET: + DCHECK_EQ(num_uniforms, uniforms_es3_.size()); + for (GLsizei ii = 0; ii < count; ++ii) { + params[ii] = uniforms_es3_[indices[ii]].offset; + } + return true; + case GL_UNIFORM_ARRAY_STRIDE: + DCHECK_EQ(num_uniforms, uniforms_es3_.size()); + for (GLsizei ii = 0; ii < count; ++ii) { + params[ii] = uniforms_es3_[indices[ii]].array_stride; + } + return true; + case GL_UNIFORM_MATRIX_STRIDE: + DCHECK_EQ(num_uniforms, uniforms_es3_.size()); + for (GLsizei ii = 0; ii < count; ++ii) { + params[ii] = uniforms_es3_[indices[ii]].matrix_stride; + } + return true; + case GL_UNIFORM_IS_ROW_MAJOR: + DCHECK_EQ(num_uniforms, uniforms_es3_.size()); + for (GLsizei ii = 0; ii < count; ++ii) { + params[ii] = uniforms_es3_[indices[ii]].is_row_major; + } + return true; + default: + NOTREACHED(); + break; + } + return false; +} + +void ProgramInfoManager::Program::UpdateES2(const std::vector<int8>& result) { + if (cached_es2_) { return; } - std::vector<int8> result; - gl->GetProgramInfoCHROMIUMHelper(program, &result); if (result.empty()) { // This should only happen on a lost context. return; @@ -332,10 +332,10 @@ void CachedProgramInfoManager::Program::Update( if (!link_status_) { return; } - attrib_infos_.clear(); - uniform_infos_.clear(); - max_attrib_name_length_ = 0; - max_uniform_name_length_ = 0; + DCHECK_EQ(0u, attrib_infos_.size()); + DCHECK_EQ(0u, uniform_infos_.size()); + DCHECK_EQ(0, max_attrib_name_length_); + DCHECK_EQ(0, max_uniform_name_length_); const ProgramInput* inputs = LocalGetAs<const ProgramInput*>( result, sizeof(*header), sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms)); @@ -368,31 +368,264 @@ void CachedProgramInfoManager::Program::Update( ++input; } DCHECK_EQ(header->num_attribs + header->num_uniforms, - static_cast<uint32>(input - inputs)); - cached_ = true; + static_cast<uint32>(input - inputs)); + cached_es2_ = true; } -CachedProgramInfoManager::CachedProgramInfoManager() { +void ProgramInfoManager::Program::UpdateES3UniformBlocks( + const std::vector<int8>& result) { + if (cached_es3_uniform_blocks_) { + return; + } + if (result.empty()) { + // This should only happen on a lost context. + return; + } + DCHECK_EQ(0u, uniform_blocks_.size()); + DCHECK_EQ(0u, active_uniform_block_max_name_length_); + + // |result| comes from GPU process. We consider it trusted data. Therefore, + // no need to check for overflows as the GPU side did the checks already. + uint32_t header_size = sizeof(UniformBlocksHeader); + DCHECK_GE(result.size(), header_size); + const UniformBlocksHeader* header = LocalGetAs<const UniformBlocksHeader*>( + result, 0, header_size); + DCHECK(header); + if (header->num_uniform_blocks == 0) { + DCHECK_EQ(result.size(), header_size); + // TODO(zmo): Here we can't tell if no uniform blocks are defined, or + // the previous link failed. + return; + } + uniform_blocks_.resize(header->num_uniform_blocks); + + uint32_t entry_size = sizeof(UniformBlockInfo) * header->num_uniform_blocks; + DCHECK_GE(result.size(), header_size + entry_size); + uint32_t data_size = result.size() - header_size - entry_size; + DCHECK_LT(0u, data_size); + const UniformBlockInfo* entries = LocalGetAs<const UniformBlockInfo*>( + result, header_size, entry_size); + DCHECK(entries); + const char* data = LocalGetAs<const char*>( + result, header_size + entry_size, data_size); + DCHECK(data); + + uint32_t size = 0; + for (uint32_t ii = 0; ii < header->num_uniform_blocks; ++ii) { + uniform_blocks_[ii].binding = static_cast<GLuint>(entries[ii].binding); + uniform_blocks_[ii].data_size = static_cast<GLuint>(entries[ii].data_size); + uniform_blocks_[ii].active_uniform_indices.resize( + entries[ii].active_uniforms); + uniform_blocks_[ii].referenced_by_vertex_shader = static_cast<GLboolean>( + entries[ii].referenced_by_vertex_shader); + uniform_blocks_[ii].referenced_by_fragment_shader = static_cast<GLboolean>( + entries[ii].referenced_by_fragment_shader); + // Uniform block names can't be empty strings. + DCHECK_LT(1u, entries[ii].name_length); + if (entries[ii].name_length > active_uniform_block_max_name_length_) { + active_uniform_block_max_name_length_ = entries[ii].name_length; + } + size += entries[ii].name_length; + DCHECK_GE(data_size, size); + uniform_blocks_[ii].name = std::string(data, entries[ii].name_length - 1); + data += entries[ii].name_length; + size += entries[ii].active_uniforms * sizeof(uint32_t); + DCHECK_GE(data_size, size); + const uint32_t* indices = reinterpret_cast<const uint32_t*>(data); + for (uint32_t uu = 0; uu < entries[ii].active_uniforms; ++uu) { + uniform_blocks_[ii].active_uniform_indices[uu] = + static_cast<GLuint>(indices[uu]); + } + indices += entries[ii].active_uniforms; + data = reinterpret_cast<const char*>(indices); + } + DCHECK_EQ(data_size, size); + cached_es3_uniform_blocks_ = true; } -CachedProgramInfoManager::~CachedProgramInfoManager() { +void ProgramInfoManager::Program::UpdateES3Uniformsiv( + const std::vector<int8>& result) { + if (cached_es3_uniformsiv_) { + return; + } + if (result.empty()) { + // This should only happen on a lost context. + return; + } + DCHECK_EQ(0u, uniforms_es3_.size()); + + // |result| comes from GPU process. We consider it trusted data. Therefore, + // no need to check for overflows as the GPU side did the checks already. + uint32_t header_size = sizeof(UniformsES3Header); + DCHECK_GE(result.size(), header_size); + const UniformsES3Header* header = LocalGetAs<const UniformsES3Header*>( + result, 0, header_size); + DCHECK(header); + if (header->num_uniforms == 0) { + DCHECK_EQ(result.size(), header_size); + // TODO(zmo): Here we can't tell if no uniforms are defined, or + // the previous link failed. + return; + } + uniforms_es3_.resize(header->num_uniforms); + + uint32_t entry_size = sizeof(UniformES3Info) * header->num_uniforms; + DCHECK_EQ(result.size(), header_size + entry_size); + const UniformES3Info* entries = LocalGetAs<const UniformES3Info*>( + result, header_size, entry_size); + DCHECK(entries); + + for (uint32_t ii = 0; ii < header->num_uniforms; ++ii) { + uniforms_es3_[ii].block_index = entries[ii].block_index; + uniforms_es3_[ii].offset = entries[ii].offset; + uniforms_es3_[ii].array_stride = entries[ii].array_stride; + uniforms_es3_[ii].matrix_stride = entries[ii].matrix_stride; + uniforms_es3_[ii].is_row_major = entries[ii].is_row_major; + } + cached_es3_uniformsiv_ = true; +} +void ProgramInfoManager::Program::UpdateES3TransformFeedbackVaryings( + const std::vector<int8>& result) { + if (cached_es3_transform_feedback_varyings_) { + return; + } + if (result.empty()) { + // This should only happen on a lost context. + return; + } + DCHECK_EQ(0u, transform_feedback_varyings_.size()); + DCHECK_EQ(0u, transform_feedback_varying_max_length_); + + // |result| comes from GPU process. We consider it trusted data. Therefore, + // no need to check for overflows as the GPU side did the checks already. + uint32_t header_size = sizeof(TransformFeedbackVaryingsHeader); + DCHECK_GE(result.size(), header_size); + const TransformFeedbackVaryingsHeader* header = + LocalGetAs<const TransformFeedbackVaryingsHeader*>( + result, 0, header_size); + DCHECK(header); + if (header->num_transform_feedback_varyings == 0) { + DCHECK_EQ(result.size(), header_size); + // TODO(zmo): Here we can't tell if no TransformFeedback varyings are + // defined, or the previous link failed. + return; + } + transform_feedback_varyings_.resize(header->num_transform_feedback_varyings); + + uint32_t entry_size = sizeof(TransformFeedbackVaryingInfo) * + header->num_transform_feedback_varyings; + DCHECK_GE(result.size(), header_size + entry_size); + uint32_t data_size = result.size() - header_size - entry_size; + DCHECK_LT(0u, data_size); + const TransformFeedbackVaryingInfo* entries = + LocalGetAs<const TransformFeedbackVaryingInfo*>( + result, header_size, entry_size); + DCHECK(entries); + const char* data = LocalGetAs<const char*>( + result, header_size + entry_size, data_size); + DCHECK(data); + + uint32_t size = 0; + for (uint32_t ii = 0; ii < header->num_transform_feedback_varyings; ++ii) { + transform_feedback_varyings_[ii].size = + static_cast<GLsizei>(entries[ii].size); + transform_feedback_varyings_[ii].type = + static_cast<GLenum>(entries[ii].type); + DCHECK_LE(1u, entries[ii].name_length); + if (entries[ii].name_length > transform_feedback_varying_max_length_) { + transform_feedback_varying_max_length_ = entries[ii].name_length; + } + size += entries[ii].name_length; + DCHECK_GE(data_size, size); + transform_feedback_varyings_[ii].name = + std::string(data, entries[ii].name_length - 1); + data += entries[ii].name_length; + } + DCHECK_EQ(data_size, size); + cached_es3_transform_feedback_varyings_ = true; } -CachedProgramInfoManager::Program* - CachedProgramInfoManager::GetProgramInfo( - GLES2Implementation* gl, GLuint program) { +bool ProgramInfoManager::Program::IsCached(ProgramInfoType type) const { + switch (type) { + case kES2: + return cached_es2_; + case kES3UniformBlocks: + return cached_es3_uniform_blocks_; + case kES3TransformFeedbackVaryings: + return cached_es3_transform_feedback_varyings_; + case kES3Uniformsiv: + return cached_es3_uniformsiv_; + case kNone: + return true; + default: + NOTREACHED(); + return true; + } +} + + +ProgramInfoManager::ProgramInfoManager() { +} + +ProgramInfoManager::~ProgramInfoManager() { +} + +ProgramInfoManager::Program* ProgramInfoManager::GetProgramInfo( + GLES2Implementation* gl, GLuint program, ProgramInfoType type) { lock_.AssertAcquired(); ProgramInfoMap::iterator it = program_infos_.find(program); if (it == program_infos_.end()) { return NULL; } Program* info = &it->second; - info->Update(gl, program); + if (info->IsCached(type)) + return info; + + std::vector<int8> result; + switch (type) { + case kES2: + { + base::AutoUnlock unlock(lock_); + // lock_ can't be held across IPC call or else it may deadlock in + // pepper. http://crbug.com/418651 + gl->GetProgramInfoCHROMIUMHelper(program, &result); + } + info->UpdateES2(result); + break; + case kES3UniformBlocks: + { + base::AutoUnlock unlock(lock_); + // lock_ can't be held across IPC call or else it may deadlock in + // pepper. http://crbug.com/418651 + gl->GetUniformBlocksCHROMIUMHelper(program, &result); + } + info->UpdateES3UniformBlocks(result); + break; + case kES3TransformFeedbackVaryings: + { + base::AutoUnlock unlock(lock_); + // lock_ can't be held across IPC call or else it may deadlock in + // pepper. http://crbug.com/418651 + gl->GetTransformFeedbackVaryingsCHROMIUMHelper(program, &result); + } + info->UpdateES3TransformFeedbackVaryings(result); + case kES3Uniformsiv: + { + base::AutoUnlock unlock(lock_); + // lock_ can't be held across IPC call or else it may deadlock in + // pepper. http://crbug.com/418651 + gl->GetUniformsES3CHROMIUMHelper(program, &result); + } + info->UpdateES3Uniformsiv(result); + default: + NOTREACHED(); + return NULL; + } return info; } -void CachedProgramInfoManager::CreateInfo(GLuint program) { +void ProgramInfoManager::CreateInfo(GLuint program) { base::AutoLock auto_lock(lock_); program_infos_.erase(program); std::pair<ProgramInfoMap::iterator, bool> result = @@ -401,123 +634,364 @@ void CachedProgramInfoManager::CreateInfo(GLuint program) { DCHECK(result.second); } -void CachedProgramInfoManager::DeleteInfo(GLuint program) { +void ProgramInfoManager::DeleteInfo(GLuint program) { base::AutoLock auto_lock(lock_); program_infos_.erase(program); } -bool CachedProgramInfoManager::GetProgramiv( +bool ProgramInfoManager::GetProgramiv( GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) { base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); + ProgramInfoType type = kNone; + switch (pname) { + case GL_ACTIVE_ATTRIBUTES: + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + case GL_ACTIVE_UNIFORMS: + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + case GL_LINK_STATUS: + type = kES2; + break; + case GL_ACTIVE_UNIFORM_BLOCKS: + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + type = kES3UniformBlocks; + break; + case GL_TRANSFORM_FEEDBACK_VARYINGS: + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + type = kES3TransformFeedbackVaryings; + break; + default: + return false; + } + Program* info = GetProgramInfo(gl, program, type); if (!info) { return false; } return info->GetProgramiv(pname, params); } -GLint CachedProgramInfoManager::GetAttribLocation( - GLES2Implementation* gl, GLuint program, const char* name) { +bool ProgramInfoManager::GetActiveUniformsiv( + GLES2Implementation* gl, GLuint program, GLsizei count, + const GLuint* indices, GLenum pname, GLint* params) { base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); + ProgramInfoType type = kNone; + switch (pname) { + case GL_UNIFORM_SIZE: + case GL_UNIFORM_TYPE: + case GL_UNIFORM_NAME_LENGTH: + type = kES2; + break; + case GL_UNIFORM_BLOCK_INDEX: + case GL_UNIFORM_OFFSET: + case GL_UNIFORM_ARRAY_STRIDE: + case GL_UNIFORM_MATRIX_STRIDE: + case GL_UNIFORM_IS_ROW_MAJOR: + type = kES3Uniformsiv; + break; + default: + return false; + } + Program* info = GetProgramInfo(gl, program, type); if (info) { - return info->GetAttribLocation(name); + return info->GetUniformsiv(count, indices, pname, params); + } + return gl->GetActiveUniformsivHelper(program, count, indices, pname, params); +} + +GLint ProgramInfoManager::GetAttribLocation( + GLES2Implementation* gl, GLuint program, const char* name) { + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES2); + if (info) { + return info->GetAttribLocation(name); + } } return gl->GetAttribLocationHelper(program, name); } -GLint CachedProgramInfoManager::GetUniformLocation( +GLint ProgramInfoManager::GetUniformLocation( GLES2Implementation* gl, GLuint program, const char* name) { - base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); - if (info) { - return info->GetUniformLocation(name); + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES2); + if (info) { + return info->GetUniformLocation(name); + } } return gl->GetUniformLocationHelper(program, name); } -bool CachedProgramInfoManager::GetActiveAttrib( +GLint ProgramInfoManager::GetFragDataLocation( + GLES2Implementation* gl, GLuint program, const char* name) { + // TODO(zmo): make FragData locations part of the ProgramInfo that are + // fetched altogether from the service side. See crbug.com/452104. + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kNone); + if (info) { + GLint possible_loc = info->GetFragDataLocation(name); + if (possible_loc != -1) + return possible_loc; + } + } + GLint loc = gl->GetFragDataLocationHelper(program, name); + if (loc != -1) { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kNone); + if (info) { + info->CacheFragDataLocation(name, loc); + } + } + return loc; +} + +bool ProgramInfoManager::GetActiveAttrib( GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { - base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); - if (info) { - const Program::VertexAttrib* attrib_info = - info->GetAttribInfo(index); - if (attrib_info) { - if (size) { - *size = attrib_info->size; - } - if (type) { - *type = attrib_info->type; - } - if (length || name) { - GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1, - std::max(static_cast<size_t>(0), - attrib_info->name.size())); - if (length) { - *length = max_size; + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES2); + if (info) { + const Program::VertexAttrib* attrib_info = info->GetAttribInfo(index); + if (attrib_info) { + if (size) { + *size = attrib_info->size; } - if (name && bufsize > 0) { - memcpy(name, attrib_info->name.c_str(), max_size); - name[max_size] = '\0'; + if (type) { + *type = attrib_info->type; } + if (length || name) { + GLsizei max_size = std::min( + static_cast<size_t>(bufsize) - 1, + std::max(static_cast<size_t>(0), attrib_info->name.size())); + if (length) { + *length = max_size; + } + if (name && bufsize > 0) { + memcpy(name, attrib_info->name.c_str(), max_size); + name[max_size] = '\0'; + } + } + return true; } - return true; } } return gl->GetActiveAttribHelper( program, index, bufsize, length, size, type, name); } -bool CachedProgramInfoManager::GetActiveUniform( +bool ProgramInfoManager::GetActiveUniform( GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { - base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); - if (info) { - const Program::UniformInfo* uniform_info = info->GetUniformInfo(index); - if (uniform_info) { - if (size) { - *size = uniform_info->size; - } - if (type) { - *type = uniform_info->type; - } - if (length || name) { - GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1, - std::max(static_cast<size_t>(0), - uniform_info->name.size())); - if (length) { - *length = max_size; + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES2); + if (info) { + const Program::UniformInfo* uniform_info = info->GetUniformInfo(index); + if (uniform_info) { + if (size) { + *size = uniform_info->size; } - if (name && bufsize > 0) { - memcpy(name, uniform_info->name.c_str(), max_size); - name[max_size] = '\0'; + if (type) { + *type = uniform_info->type; } + if (length || name) { + GLsizei max_size = std::min( + static_cast<size_t>(bufsize) - 1, + std::max(static_cast<size_t>(0), uniform_info->name.size())); + if (length) { + *length = max_size; + } + if (name && bufsize > 0) { + memcpy(name, uniform_info->name.c_str(), max_size); + name[max_size] = '\0'; + } + } + return true; } - return true; } } return gl->GetActiveUniformHelper( program, index, bufsize, length, size, type, name); } -ProgramInfoManager::ProgramInfoManager() { +GLuint ProgramInfoManager::GetUniformBlockIndex( + GLES2Implementation* gl, GLuint program, const char* name) { + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES3UniformBlocks); + if (info) { + return info->GetUniformBlockIndex(name); + } + } + return gl->GetUniformBlockIndexHelper(program, name); } -ProgramInfoManager::~ProgramInfoManager() { +bool ProgramInfoManager::GetActiveUniformBlockName( + GLES2Implementation* gl, GLuint program, GLuint index, + GLsizei buf_size, GLsizei* length, char* name) { + DCHECK_LE(0, buf_size); + if (!name) { + buf_size = 0; + } + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES3UniformBlocks); + if (info) { + const Program::UniformBlock* uniform_block = info->GetUniformBlock(index); + if (uniform_block) { + if (buf_size == 0) { + if (length) { + *length = 0; + } + } else if (length || name) { + GLsizei max_size = std::min( + buf_size - 1, static_cast<GLsizei>(uniform_block->name.size())); + if (length) { + *length = max_size; + } + if (name) { + memcpy(name, uniform_block->name.data(), max_size); + name[max_size] = '\0'; + } + } + return true; + } + } + } + return gl->GetActiveUniformBlockNameHelper( + program, index, buf_size, length, name); +} + +bool ProgramInfoManager::GetActiveUniformBlockiv( + GLES2Implementation* gl, GLuint program, GLuint index, + GLenum pname, GLint* params) { + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES3UniformBlocks); + if (info) { + const Program::UniformBlock* uniform_block = info->GetUniformBlock(index); + bool valid_pname; + switch (pname) { + case GL_UNIFORM_BLOCK_BINDING: + case GL_UNIFORM_BLOCK_DATA_SIZE: + case GL_UNIFORM_BLOCK_NAME_LENGTH: + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: + case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: + case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: + valid_pname = true; + break; + default: + valid_pname = false; + break; + } + if (uniform_block && valid_pname && params) { + switch (pname) { + case GL_UNIFORM_BLOCK_BINDING: + *params = static_cast<GLint>(uniform_block->binding); + break; + case GL_UNIFORM_BLOCK_DATA_SIZE: + *params = static_cast<GLint>(uniform_block->data_size); + break; + case GL_UNIFORM_BLOCK_NAME_LENGTH: + *params = static_cast<GLint>(uniform_block->name.size()) + 1; + break; + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + *params = static_cast<GLint>( + uniform_block->active_uniform_indices.size()); + break; + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: + for (size_t ii = 0; + ii < uniform_block->active_uniform_indices.size(); ++ii) { + params[ii] = static_cast<GLint>( + uniform_block->active_uniform_indices[ii]); + } + break; + case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: + *params = static_cast<GLint>( + uniform_block->referenced_by_vertex_shader); + break; + case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: + *params = static_cast<GLint>( + uniform_block->referenced_by_fragment_shader); + break; + default: + NOTREACHED(); + } + return true; + } + } + } + return gl->GetActiveUniformBlockivHelper(program, index, pname, params); +} + +void ProgramInfoManager::UniformBlockBinding( + GLES2Implementation* gl, GLuint program, GLuint index, GLuint binding) { + GLuint max_bindings = + static_cast<GLuint>(gl->capabilities().max_uniform_buffer_bindings); + if (binding < max_bindings) { + base::AutoLock auto_lock(lock_); + // If UniformBlock info haven't been cached yet, skip updating the binding. + Program* info = GetProgramInfo(gl, program, kNone); + if (info) { + info->UniformBlockBinding(index, binding); + } + } } -ProgramInfoManager* ProgramInfoManager::Create( - bool shared_resources_across_processes) { - if (shared_resources_across_processes) { - return new NonCachedProgramInfoManager(); - } else { - return new CachedProgramInfoManager(); +bool ProgramInfoManager::GetTransformFeedbackVarying( + GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, GLsizei* size, GLenum* type, char* name) { + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES3TransformFeedbackVaryings); + if (info) { + const Program::TransformFeedbackVarying* varying = + info->GetTransformFeedbackVarying(index); + if (varying) { + if (size) { + *size = varying->size; + } + if (type) { + *type = varying->type; + } + if (length || name) { + GLsizei max_size = std::min( + bufsize - 1, static_cast<GLsizei>(varying->name.size())); + if (length) { + *length = static_cast<GLsizei>(max_size); + } + if (name && bufsize > 0) { + memcpy(name, varying->name.c_str(), max_size); + name[max_size] = '\0'; + } + } + return true; + } + } + } + return gl->GetTransformFeedbackVaryingHelper( + program, index, bufsize, length, size, type, name); +} + +bool ProgramInfoManager::GetUniformIndices(GLES2Implementation* gl, + GLuint program, GLsizei count, const char* const* names, GLuint* indices) { + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES2); + if (info) { + DCHECK_LT(0, count); + DCHECK(names && indices); + for (GLsizei ii = 0; ii < count; ++ii) { + indices[ii] = info->GetUniformIndex(names[ii]); + } + return true; + } } + return gl->GetUniformIndicesHelper(program, count, names, indices); } } // namespace gles2 diff --git a/chromium/gpu/command_buffer/client/program_info_manager.h b/chromium/gpu/command_buffer/client/program_info_manager.h index 099f182184b..6f8a745c0b8 100644 --- a/chromium/gpu/command_buffer/client/program_info_manager.h +++ b/chromium/gpu/command_buffer/client/program_info_manager.h @@ -5,46 +5,242 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_ #define GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_ -#include <GLES2/gl2.h> +#include <GLES3/gl3.h> + +#include <string> +#include <vector> + +#include "base/containers/hash_tables.h" +#include "base/gtest_prod_util.h" +#include "base/synchronization/lock.h" #include "gles2_impl_export.h" +#include "gpu/command_buffer/client/gles2_implementation.h" namespace gpu { namespace gles2 { -class GLES2Implementation; - // Manages info about OpenGL ES Programs. class GLES2_IMPL_EXPORT ProgramInfoManager { public: - virtual ~ProgramInfoManager(); + ProgramInfoManager(); + ~ProgramInfoManager(); + + void CreateInfo(GLuint program); + + void DeleteInfo(GLuint program); + + bool GetProgramiv( + GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params); + + GLint GetAttribLocation( + GLES2Implementation* gl, GLuint program, const char* name); + + GLint GetUniformLocation( + GLES2Implementation* gl, GLuint program, const char* name); + + GLint GetFragDataLocation( + GLES2Implementation* gl, GLuint program, const char* name); + + bool GetActiveAttrib( + GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, GLint* size, GLenum* type, char* name); + + bool GetActiveUniform( + GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, GLint* size, GLenum* type, char* name); + + GLuint GetUniformBlockIndex( + GLES2Implementation* gl, GLuint program, const char* name); + + bool GetActiveUniformBlockName( + GLES2Implementation* gl, GLuint program, GLuint index, + GLsizei buf_size, GLsizei* length, char* name); + + bool GetActiveUniformBlockiv( + GLES2Implementation* gl, GLuint program, GLuint index, + GLenum pname, GLint* params); + + // Attempt to update the |index| uniform block binding. + // It's no op if the program does not exist, or the |index| uniform block + // is not in the cache, or binding >= GL_MAX_UNIFORM_BUFFER_BINDINGS. + void UniformBlockBinding( + GLES2Implementation* gl, GLuint program, GLuint index, GLuint binding); + + bool GetTransformFeedbackVarying( + GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, GLsizei* size, GLenum* type, char* name); + + bool GetUniformIndices( + GLES2Implementation* gl, GLuint program, GLsizei count, + const char* const* names, GLuint* indices); + + bool GetActiveUniformsiv( + GLES2Implementation* gl, GLuint program, GLsizei count, + const GLuint* indices, GLenum pname, GLint* params); + + private: + friend class ProgramInfoManagerTest; + + FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest, UpdateES2); + FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest, UpdateES3UniformBlocks); + FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest, + UpdateES3TransformFeedbackVaryings); + FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest, + GetActiveUniformsivCached); + + enum ProgramInfoType { + kES2, + kES3UniformBlocks, + kES3TransformFeedbackVaryings, + kES3Uniformsiv, + kNone, + }; + + // Need GLES2_IMPL_EXPORT for tests. + class GLES2_IMPL_EXPORT Program { + public: + struct UniformInfo { + UniformInfo(GLsizei _size, GLenum _type, const std::string& _name); + ~UniformInfo(); + + GLsizei size; + GLenum type; + bool is_array; + std::string name; + std::vector<GLint> element_locations; + }; + struct UniformES3 { + UniformES3(); + ~UniformES3(); - static ProgramInfoManager* Create(bool shared_resources_across_processes); + GLint block_index; + GLint offset; + GLint array_stride; + GLint matrix_stride; + GLint is_row_major; + }; + struct VertexAttrib { + VertexAttrib(GLsizei _size, GLenum _type, const std::string& _name, + GLint _location); + ~VertexAttrib(); - virtual void CreateInfo(GLuint program) = 0; + GLsizei size; + GLenum type; + GLint location; + std::string name; + }; + struct UniformBlock { + UniformBlock(); + ~UniformBlock(); - virtual void DeleteInfo(GLuint program) = 0; + GLuint binding; + GLuint data_size; + std::vector<GLuint> active_uniform_indices; + GLboolean referenced_by_vertex_shader; + GLboolean referenced_by_fragment_shader; + std::string name; + }; + struct TransformFeedbackVarying { + TransformFeedbackVarying(); + ~TransformFeedbackVarying(); - virtual bool GetProgramiv( - GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) = 0; + GLsizei size; + GLenum type; + std::string name; + }; - virtual GLint GetAttribLocation( - GLES2Implementation* gl, GLuint program, const char* name) = 0; + Program(); + ~Program(); - virtual GLint GetUniformLocation( - GLES2Implementation* gl, GLuint program, const char* name) = 0; + const VertexAttrib* GetAttribInfo(GLint index) const; - virtual bool GetActiveAttrib( - GLES2Implementation* gl, - GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, - GLint* size, GLenum* type, char* name) = 0; + GLint GetAttribLocation(const std::string& name) const; - virtual bool GetActiveUniform( - GLES2Implementation* gl, - GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, - GLint* size, GLenum* type, char* name) = 0; + const UniformInfo* GetUniformInfo(GLint index) const; - protected: - ProgramInfoManager(); + // Gets the location of a uniform by name. + GLint GetUniformLocation(const std::string& name) const; + // Gets the index of a uniform by name. Return INVALID_INDEX in failure. + GLuint GetUniformIndex(const std::string& name) const; + + bool GetUniformsiv( + GLsizei count, const GLuint* indices, GLenum pname, GLint* params); + + GLint GetFragDataLocation(const std::string& name) const; + void CacheFragDataLocation(const std::string& name, GLint loc); + + bool GetProgramiv(GLenum pname, GLint* params); + + // Gets the index of a uniform block by name. + GLuint GetUniformBlockIndex(const std::string& name) const; + const UniformBlock* GetUniformBlock(GLuint index) const; + // Update the binding if the |index| uniform block is in the cache. + void UniformBlockBinding(GLuint index, GLuint binding); + + const TransformFeedbackVarying* GetTransformFeedbackVarying( + GLuint index) const; + + // Updates the ES2 only program info after a successful link. + void UpdateES2(const std::vector<int8>& result); + + // Updates the ES3 UniformBlock info after a successful link. + void UpdateES3UniformBlocks(const std::vector<int8>& result); + + // Updates the ES3 Uniformsiv info after a successful link. + void UpdateES3Uniformsiv(const std::vector<int8>& result); + + // Updates the ES3 TransformFeedbackVaryings info after a successful link. + void UpdateES3TransformFeedbackVaryings(const std::vector<int8>& result); + + bool IsCached(ProgramInfoType type) const; + + private: + bool cached_es2_; + + GLsizei max_attrib_name_length_; + + // Attrib by index. + std::vector<VertexAttrib> attrib_infos_; + + GLsizei max_uniform_name_length_; + + // Uniform info by index. + std::vector<UniformInfo> uniform_infos_; + + // This is true if glLinkProgram was successful last time it was called. + bool link_status_; + + // BELOW ARE ES3 ONLY INFORMATION. + + bool cached_es3_uniform_blocks_; + + uint32_t active_uniform_block_max_name_length_; + + // Uniform blocks by index. + std::vector<UniformBlock> uniform_blocks_; + + bool cached_es3_transform_feedback_varyings_; + + uint32_t transform_feedback_varying_max_length_; + + // TransformFeedback varyings by index. + std::vector<TransformFeedbackVarying> transform_feedback_varyings_; + + bool cached_es3_uniformsiv_; + + std::vector<UniformES3> uniforms_es3_; + + base::hash_map<std::string, GLint> frag_data_locations_; + }; + + Program* GetProgramInfo( + GLES2Implementation* gl, GLuint program, ProgramInfoType type); + + typedef base::hash_map<GLuint, Program> ProgramInfoMap; + + ProgramInfoMap program_infos_; + + mutable base::Lock lock_; }; } // namespace gles2 diff --git a/chromium/gpu/command_buffer/client/program_info_manager_unittest.cc b/chromium/gpu/command_buffer/client/program_info_manager_unittest.cc index ba62703ef98..f9c6b00320a 100644 --- a/chromium/gpu/command_buffer/client/program_info_manager_unittest.cc +++ b/chromium/gpu/command_buffer/client/program_info_manager_unittest.cc @@ -1,30 +1,549 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2015 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. -// Tests for the Command Buffer Helper. - #include "gpu/command_buffer/client/program_info_manager.h" -#include "base/memory/scoped_ptr.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/gmock/include/gmock/gmock.h" + +namespace { + +uint32 ComputeOffset(const void* start, const void* position) { + return static_cast<const uint8*>(position) - + static_cast<const uint8*>(start); +} + +const GLuint kClientProgramId = 321; + +} // namespace anonymous namespace gpu { namespace gles2 { class ProgramInfoManagerTest : public testing::Test { + public: + ProgramInfoManagerTest() {} + ~ProgramInfoManagerTest() override {} + protected: - void SetUp() override {} + typedef ProgramInfoManager::Program Program; + + struct ProgramES2Data { + // TODO(zmo): Also add attrib data. + ProgramInfoHeader header; + ProgramInput uniforms[2]; + int32_t uniform_loc0[1]; + int32_t uniform_loc1[2]; + char uniform_name0[4]; + char uniform_name1[8]; + }; + + struct UniformBlocksData { + UniformBlocksHeader header; + UniformBlockInfo entry[2]; + char name0[4]; + uint32_t indices0[2]; + char name1[8]; + uint32_t indices1[1]; + }; + + struct UniformsES3Data { + UniformsES3Header header; + UniformES3Info entry[2]; + }; + + struct TransformFeedbackVaryingsData { + TransformFeedbackVaryingsHeader header; + TransformFeedbackVaryingInfo entry[2]; + char name0[4]; + char name1[8]; + }; + + void SetUp() override { + program_info_manager_.reset(new ProgramInfoManager); + program_info_manager_->CreateInfo(kClientProgramId); + { + base::AutoLock auto_lock(program_info_manager_->lock_); + program_ = program_info_manager_->GetProgramInfo( + NULL, kClientProgramId, ProgramInfoManager::kNone); + ASSERT_TRUE(program_ != NULL); + } + } void TearDown() override {} + void SetupProgramES2Data(ProgramES2Data* data) { + // The names needs to be of size 4*k-1 to avoid padding in the struct Data. + // This is a testing only problem. + const char* kName[] = { "cow", "bull[0]" }; + data->header.link_status = 1; + data->header.num_attribs = 0; + data->header.num_uniforms = 2; + data->uniforms[0].type = GL_FLOAT; + data->uniforms[0].size = 1; + data->uniforms[0].location_offset = + ComputeOffset(data, &data->uniform_loc0); + data->uniforms[0].name_offset = + ComputeOffset(data, &data->uniform_name0); + data->uniforms[0].name_length = strlen(kName[0]); + data->uniforms[1].type = GL_FLOAT_VEC4; + data->uniforms[1].size = 2; + data->uniforms[1].location_offset = + ComputeOffset(data, &data->uniform_loc1); + data->uniforms[1].name_offset = + ComputeOffset(data, &data->uniform_name1); + data->uniforms[1].name_length = strlen(kName[1]); + data->uniform_loc0[0] = 1; + data->uniform_loc1[0] = 2; + data->uniform_loc1[1] = 3; + memcpy(data->uniform_name0, kName[0], arraysize(data->uniform_name0)); + memcpy(data->uniform_name1, kName[1], arraysize(data->uniform_name1)); + } + + void SetupUniformBlocksData(UniformBlocksData* data) { + // The names needs to be of size 4*k-1 to avoid padding in the struct Data. + // This is a testing only problem. + const char* kName[] = { "cow", "chicken" }; + const uint32_t kIndices0[] = { 1, 2 }; + const uint32_t kIndices1[] = { 3 }; + const uint32_t* kIndices[] = { kIndices0, kIndices1 }; + data->header.num_uniform_blocks = 2; + data->entry[0].binding = 0; + data->entry[0].data_size = 8; + data->entry[0].name_offset = ComputeOffset(data, data->name0); + data->entry[0].name_length = arraysize(data->name0); + data->entry[0].active_uniforms = arraysize(data->indices0); + data->entry[0].active_uniform_offset = ComputeOffset(data, data->indices0); + data->entry[0].referenced_by_vertex_shader = static_cast<uint32_t>(true); + data->entry[0].referenced_by_fragment_shader = static_cast<uint32_t>(false); + data->entry[1].binding = 1; + data->entry[1].data_size = 4; + data->entry[1].name_offset = ComputeOffset(data, data->name1); + data->entry[1].name_length = arraysize(data->name1); + data->entry[1].active_uniforms = arraysize(data->indices1); + data->entry[1].active_uniform_offset = ComputeOffset(data, data->indices1); + data->entry[1].referenced_by_vertex_shader = static_cast<uint32_t>(false); + data->entry[1].referenced_by_fragment_shader = static_cast<uint32_t>(true); + memcpy(data->name0, kName[0], arraysize(data->name0)); + data->indices0[0] = kIndices[0][0]; + data->indices0[1] = kIndices[0][1]; + memcpy(data->name1, kName[1], arraysize(data->name1)); + data->indices1[0] = kIndices[1][0]; + } + + void SetupUniformsES3Data(UniformsES3Data* data) { + data->header.num_uniforms = 2; + data->entry[0].block_index = 1; + data->entry[0].offset = 2; + data->entry[0].array_stride = 3; + data->entry[0].matrix_stride = 4; + data->entry[0].is_row_major = 0; + data->entry[1].block_index = 5; + data->entry[1].offset = 6; + data->entry[1].array_stride = 7; + data->entry[1].matrix_stride = 8; + data->entry[1].is_row_major = 1; + } + + void SetupTransformFeedbackVaryingsData(TransformFeedbackVaryingsData* data) { + // The names needs to be of size 4*k-1 to avoid padding in the struct Data. + // This is a testing only problem. + const char* kName[] = { "cow", "chicken" }; + data->header.num_transform_feedback_varyings = 2; + data->entry[0].size = 1; + data->entry[0].type = GL_FLOAT_VEC2; + data->entry[0].name_offset = ComputeOffset(data, data->name0); + data->entry[0].name_length = arraysize(data->name0); + data->entry[1].size = 2; + data->entry[1].type = GL_FLOAT; + data->entry[1].name_offset = ComputeOffset(data, data->name1); + data->entry[1].name_length = arraysize(data->name1); + memcpy(data->name0, kName[0], arraysize(data->name0)); + memcpy(data->name1, kName[1], arraysize(data->name1)); + } + scoped_ptr<ProgramInfoManager> program_info_manager_; + Program* program_; }; -TEST_F(ProgramInfoManagerTest, Basic) { +TEST_F(ProgramInfoManagerTest, UpdateES2) { + ProgramES2Data data; + SetupProgramES2Data(&data); + const std::string kNames[] = { data.uniform_name0, data.uniform_name1 }; + const int32_t* kLocs[] = { data.uniform_loc0, data.uniform_loc1 }; + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + EXPECT_FALSE(program_->IsCached(ProgramInfoManager::kES2)); + program_->UpdateES2(result); + EXPECT_TRUE(program_->IsCached(ProgramInfoManager::kES2)); + + GLint params = 0; + EXPECT_TRUE(program_->GetProgramiv(GL_LINK_STATUS, ¶ms)); + EXPECT_TRUE(params); + + params = 0; + EXPECT_TRUE(program_->GetProgramiv(GL_ACTIVE_ATTRIBUTES, ¶ms)); + EXPECT_EQ(data.header.num_attribs, static_cast<uint32_t>(params)); + params = 0; + EXPECT_TRUE(program_->GetProgramiv(GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, ¶ms)); + EXPECT_EQ(0, params); + + params = 0; + EXPECT_TRUE(program_->GetProgramiv(GL_ACTIVE_UNIFORMS, ¶ms)); + EXPECT_EQ(data.header.num_uniforms, static_cast<uint32_t>(params)); + GLint active_uniform_max_length = 0; + EXPECT_TRUE(program_->GetProgramiv( + GL_ACTIVE_UNIFORM_MAX_LENGTH, &active_uniform_max_length)); + + for (uint32_t ii = 0; ii < data.header.num_uniforms; ++ii) { + const Program::UniformInfo* info = program_->GetUniformInfo(ii); + EXPECT_TRUE(info != NULL); + EXPECT_EQ(data.uniforms[ii].type, info->type); + EXPECT_EQ(data.uniforms[ii].size, info->size); + EXPECT_LT(kNames[0].length(), + static_cast<size_t>(active_uniform_max_length)); + EXPECT_EQ(kNames[ii], info->name); + EXPECT_EQ(kNames[ii][kNames[ii].length() - 1] == ']', info->is_array); + EXPECT_EQ(data.uniforms[ii].size, + static_cast<int32_t>(info->element_locations.size())); + for (int32_t uu = 0; uu < data.uniforms[ii].size; ++uu) { + EXPECT_EQ(kLocs[ii][uu], info->element_locations[uu]); + } + } +} + +TEST_F(ProgramInfoManagerTest, UpdateES3UniformBlocks) { + UniformBlocksData data; + SetupUniformBlocksData(&data); + const std::string kName[] = { data.name0, data.name1 }; + const uint32_t* kIndices[] = { data.indices0, data.indices1 }; + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + EXPECT_FALSE(program_->IsCached(ProgramInfoManager::kES3UniformBlocks)); + program_->UpdateES3UniformBlocks(result); + EXPECT_TRUE(program_->IsCached(ProgramInfoManager::kES3UniformBlocks)); + + GLint uniform_block_count = 0; + EXPECT_TRUE(program_->GetProgramiv( + GL_ACTIVE_UNIFORM_BLOCKS, &uniform_block_count)); + EXPECT_EQ(data.header.num_uniform_blocks, + static_cast<uint32_t>(uniform_block_count)); + GLint max_name_length = 0; + EXPECT_TRUE(program_->GetProgramiv( + GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_name_length)); + for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) { + EXPECT_EQ(ii, program_->GetUniformBlockIndex(kName[ii])); + const Program::UniformBlock* info = program_->GetUniformBlock(ii); + EXPECT_TRUE(info != NULL); + EXPECT_EQ(data.entry[ii].binding, info->binding); + EXPECT_EQ(data.entry[ii].data_size, info->data_size); + EXPECT_EQ(data.entry[ii].active_uniforms, + info->active_uniform_indices.size()); + for (uint32_t uu = 0; uu < data.entry[ii].active_uniforms; ++uu) { + EXPECT_EQ(kIndices[ii][uu], info->active_uniform_indices[uu]); + } + EXPECT_EQ(data.entry[ii].referenced_by_vertex_shader, + static_cast<GLboolean>(info->referenced_by_vertex_shader)); + EXPECT_EQ(data.entry[ii].referenced_by_fragment_shader, + static_cast<GLboolean>(info->referenced_by_fragment_shader)); + EXPECT_EQ(kName[ii], info->name); + EXPECT_GE(max_name_length, static_cast<GLint>(info->name.size()) + 1); + } + + EXPECT_EQ(GL_INVALID_INDEX, program_->GetUniformBlockIndex("BadName")); + EXPECT_EQ(NULL, program_->GetUniformBlock(data.header.num_uniform_blocks)); +} + +TEST_F(ProgramInfoManagerTest, UpdateES3TransformFeedbackVaryings) { + TransformFeedbackVaryingsData data; + SetupTransformFeedbackVaryingsData(&data); + const std::string kName[] = { data.name0, data.name1 }; + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + EXPECT_FALSE(program_->IsCached( + ProgramInfoManager::kES3TransformFeedbackVaryings)); + program_->UpdateES3TransformFeedbackVaryings(result); + EXPECT_TRUE(program_->IsCached( + ProgramInfoManager::kES3TransformFeedbackVaryings)); + + GLint transform_feedback_varying_count = 0; + EXPECT_TRUE(program_->GetProgramiv( + GL_TRANSFORM_FEEDBACK_VARYINGS, &transform_feedback_varying_count)); + EXPECT_EQ(data.header.num_transform_feedback_varyings, + static_cast<uint32_t>(transform_feedback_varying_count)); + GLint max_name_length = 0; + EXPECT_TRUE(program_->GetProgramiv( + GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_name_length)); + for (uint32_t ii = 0; ii < data.header.num_transform_feedback_varyings; + ++ii) { + const Program::TransformFeedbackVarying* varying = + program_->GetTransformFeedbackVarying(ii); + EXPECT_TRUE(varying != NULL); + EXPECT_EQ(data.entry[ii].size, static_cast<uint32_t>(varying->size)); + EXPECT_EQ(data.entry[ii].type, varying->type); + EXPECT_EQ(kName[ii], varying->name); + EXPECT_GE(max_name_length, static_cast<GLint>(varying->name.size()) + 1); + } + EXPECT_EQ(NULL, program_->GetTransformFeedbackVarying( + data.header.num_transform_feedback_varyings)); +} + +TEST_F(ProgramInfoManagerTest, GetUniformBlockIndexCached) { + UniformBlocksData data; + SetupUniformBlocksData(&data); + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + program_->UpdateES3UniformBlocks(result); + + EXPECT_EQ(0u, program_info_manager_->GetUniformBlockIndex( + NULL, kClientProgramId, data.name0)); + EXPECT_EQ(1u, program_info_manager_->GetUniformBlockIndex( + NULL, kClientProgramId, data.name1)); + EXPECT_EQ(GL_INVALID_INDEX, program_info_manager_->GetUniformBlockIndex( + NULL, kClientProgramId, "BadName")); +} + +TEST_F(ProgramInfoManagerTest, GetActiveUniformBlockNameCached) { + UniformBlocksData data; + SetupUniformBlocksData(&data); + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + program_->UpdateES3UniformBlocks(result); + + GLsizei buf_size = std::max(strlen(data.name0), strlen(data.name1)) + 1; + std::vector<char> buffer(buf_size); + GLsizei length = 0; + EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( + NULL, kClientProgramId, 0, buf_size, &length, &buffer[0])); + EXPECT_EQ(static_cast<GLsizei>(strlen(data.name0)), length); + EXPECT_STREQ(data.name0, &buffer[0]); + + EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( + NULL, kClientProgramId, 1, buf_size, &length, &buffer[0])); + EXPECT_EQ(static_cast<GLsizei>(strlen(data.name1)), length); + EXPECT_STREQ(data.name1, &buffer[0]); + + // Test length == NULL. + EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( + NULL, kClientProgramId, 0, buf_size, NULL, &buffer[0])); + EXPECT_STREQ(data.name0, &buffer[0]); + + // Test buffer == NULL. + EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( + NULL, kClientProgramId, 0, buf_size, &length, NULL)); + EXPECT_EQ(0, length); + + // Test buf_size smaller than string size. + buf_size = strlen(data.name0); + EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( + NULL, kClientProgramId, 0, buf_size, &length, &buffer[0])); + EXPECT_EQ(buf_size, length + 1); + EXPECT_STREQ(std::string(data.name0).substr(0, length).c_str(), &buffer[0]); +} + +TEST_F(ProgramInfoManagerTest, GetActiveUniformBlockivCached) { + UniformBlocksData data; + SetupUniformBlocksData(&data); + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + program_->UpdateES3UniformBlocks(result); + const char* kName[] = { data.name0, data.name1 }; + const uint32_t* kIndices[] = { data.indices0, data.indices1 }; + + for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) { + ASSERT_GE(2u, data.entry[ii].active_uniforms); + GLint params[2]; + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, GL_UNIFORM_BLOCK_BINDING, params)); + EXPECT_EQ(data.entry[ii].binding, static_cast<uint32_t>(params[0])); + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, GL_UNIFORM_BLOCK_DATA_SIZE, params)); + EXPECT_EQ(data.entry[ii].data_size, static_cast<uint32_t>(params[0])); + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, GL_UNIFORM_BLOCK_NAME_LENGTH, params)); + EXPECT_EQ(strlen(kName[ii]) + 1, static_cast<uint32_t>(params[0])); + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, params)); + EXPECT_EQ(data.entry[ii].active_uniforms, static_cast<uint32_t>(params[0])); + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, params)); + for (uint32_t uu = 0; uu < data.entry[ii].active_uniforms; ++uu) { + EXPECT_EQ(kIndices[ii][uu], static_cast<uint32_t>(params[uu])); + } + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, + GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, params)); + EXPECT_EQ(data.entry[ii].referenced_by_vertex_shader, + static_cast<uint32_t>(params[0])); + + EXPECT_TRUE(program_info_manager_->GetActiveUniformBlockiv( + NULL, kClientProgramId, ii, + GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, params)); + EXPECT_EQ(data.entry[ii].referenced_by_fragment_shader, + static_cast<uint32_t>(params[0])); + } +} + +TEST_F(ProgramInfoManagerTest, GetTransformFeedbackVaryingCached) { + TransformFeedbackVaryingsData data; + SetupTransformFeedbackVaryingsData(&data); + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + program_->UpdateES3TransformFeedbackVaryings(result); + const char* kName[] = { data.name0, data.name1 }; + GLsizei buf_size = std::max(strlen(kName[0]), strlen(kName[1])) + 1; + for (uint32_t ii = 0; ii < data.header.num_transform_feedback_varyings; + ++ii) { + std::vector<char> buffer(buf_size); + GLsizei length = 0; + GLsizei size = 0; + GLenum type = 0; + EXPECT_EQ(true, program_info_manager_->GetTransformFeedbackVarying( + NULL, kClientProgramId, ii, buf_size, + &length, &size, &type, &buffer[0])); + EXPECT_EQ(data.entry[ii].size, static_cast<uint32_t>(size)); + EXPECT_EQ(data.entry[ii].type, static_cast<uint32_t>(type)); + EXPECT_STREQ(kName[ii], &buffer[0]); + EXPECT_EQ(strlen(kName[ii]), static_cast<size_t>(length)); + } +} + +TEST_F(ProgramInfoManagerTest, GetUniformIndices) { + ProgramES2Data data; + SetupProgramES2Data(&data); + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + program_->UpdateES2(result); + + { // Original order. + const char* kNames[] = { data.uniform_name0, data.uniform_name1 }; + const GLuint kIndices[] = { 0, 1 }; + const GLsizei kCount = 2; + GLuint indices[kCount]; + EXPECT_TRUE(program_info_manager_->GetUniformIndices( + NULL, kClientProgramId, kCount, kNames, indices)); + for (GLsizei ii = 0; ii < kCount; ++ii) { + EXPECT_EQ(kIndices[ii], indices[ii]); + } + } + + { // Switched order. + const char* kNames[] = { data.uniform_name1, data.uniform_name0 }; + const GLuint kIndices[] = { 1, 0 }; + const GLsizei kCount = 2; + GLuint indices[kCount]; + EXPECT_TRUE(program_info_manager_->GetUniformIndices( + NULL, kClientProgramId, kCount, kNames, indices)); + for (GLsizei ii = 0; ii < kCount; ++ii) { + EXPECT_EQ(kIndices[ii], indices[ii]); + } + } + + { // With bad names. + const char* kNames[] = { data.uniform_name1, "BadName" }; + const GLuint kIndices[] = { 1, GL_INVALID_INDEX }; + const GLsizei kCount = 2; + GLuint indices[kCount]; + EXPECT_TRUE(program_info_manager_->GetUniformIndices( + NULL, kClientProgramId, kCount, kNames, indices)); + for (GLsizei ii = 0; ii < kCount; ++ii) { + EXPECT_EQ(kIndices[ii], indices[ii]); + } + } + + { // Both "foo" and "foo[0]" are considered valid names for an array, + // but not "foo[1]". + const char* kNames[] = { "bull", "bull[0]", "bull[1]" }; + const GLuint kIndices[] = { 1, 1, GL_INVALID_INDEX }; + const GLsizei kCount = 3; + GLuint indices[kCount]; + EXPECT_TRUE(program_info_manager_->GetUniformIndices( + NULL, kClientProgramId, kCount, kNames, indices)); + for (GLsizei ii = 0; ii < kCount; ++ii) { + EXPECT_EQ(kIndices[ii], indices[ii]); + } + } +} + +TEST_F(ProgramInfoManagerTest, GetActiveUniformsivCached) { + // ES3 only parameters. + UniformsES3Data data_es3; + SetupUniformsES3Data(&data_es3); + std::vector<int8> result(sizeof(data_es3)); + memcpy(&result[0], &data_es3, sizeof(data_es3)); + EXPECT_FALSE(program_->IsCached(ProgramInfoManager::kES3Uniformsiv)); + program_->UpdateES3Uniformsiv(result); + EXPECT_TRUE(program_->IsCached(ProgramInfoManager::kES3Uniformsiv)); + + uint32_t count = data_es3.header.num_uniforms; + std::vector<GLuint> indices(count); + for (uint32_t ii = 0; ii < count; ++ii) { + indices[ii] = ii; + } + std::vector<GLint> block_index(count); + EXPECT_TRUE(program_info_manager_->GetActiveUniformsiv( + NULL, kClientProgramId, static_cast<GLsizei>(count), &indices[0], + GL_UNIFORM_BLOCK_INDEX, &block_index[0])); + std::vector<GLint> offset(count); + EXPECT_TRUE(program_info_manager_->GetActiveUniformsiv( + NULL, kClientProgramId, static_cast<GLsizei>(count), &indices[0], + GL_UNIFORM_OFFSET, &offset[0])); + std::vector<GLint> array_stride(count); + EXPECT_TRUE(program_info_manager_->GetActiveUniformsiv( + NULL, kClientProgramId, static_cast<GLsizei>(count), &indices[0], + GL_UNIFORM_ARRAY_STRIDE, &array_stride[0])); + std::vector<GLint> matrix_stride(count); + EXPECT_TRUE(program_info_manager_->GetActiveUniformsiv( + NULL, kClientProgramId, static_cast<GLsizei>(count), &indices[0], + GL_UNIFORM_MATRIX_STRIDE, &matrix_stride[0])); + std::vector<GLint> is_row_major(count); + EXPECT_TRUE(program_info_manager_->GetActiveUniformsiv( + NULL, kClientProgramId, static_cast<GLsizei>(count), &indices[0], + GL_UNIFORM_IS_ROW_MAJOR, &is_row_major[0])); + + for (uint32_t ii = 0; ii < count; ++ii) { + EXPECT_EQ(data_es3.entry[ii].block_index, block_index[ii]); + EXPECT_EQ(data_es3.entry[ii].offset, offset[ii]); + EXPECT_EQ(data_es3.entry[ii].array_stride, array_stride[ii]); + EXPECT_EQ(data_es3.entry[ii].matrix_stride, matrix_stride[ii]); + EXPECT_EQ(data_es3.entry[ii].is_row_major, is_row_major[ii]); + } + + // ES2 parameters. + ProgramES2Data data_es2; + SetupProgramES2Data(&data_es2); + result.resize(sizeof(data_es2)); + memcpy(&result[0], &data_es2, sizeof(data_es2)); + EXPECT_FALSE(program_->IsCached(ProgramInfoManager::kES2)); + program_->UpdateES2(result); + EXPECT_TRUE(program_->IsCached(ProgramInfoManager::kES2)); + + std::vector<GLint> size(count); + EXPECT_TRUE(program_info_manager_->GetActiveUniformsiv( + NULL, kClientProgramId, static_cast<GLsizei>(count), &indices[0], + GL_UNIFORM_SIZE, &size[0])); + std::vector<GLint> type(count); + EXPECT_TRUE(program_info_manager_->GetActiveUniformsiv( + NULL, kClientProgramId, static_cast<GLsizei>(count), &indices[0], + GL_UNIFORM_TYPE, &type[0])); + std::vector<GLint> name_length(count); + EXPECT_TRUE(program_info_manager_->GetActiveUniformsiv( + NULL, kClientProgramId, static_cast<GLsizei>(count), &indices[0], + GL_UNIFORM_NAME_LENGTH, &name_length[0])); + + for (uint32_t ii = 0; ii < count; ++ii) { + EXPECT_EQ(data_es2.uniforms[ii].size, size[ii]); + EXPECT_EQ(data_es2.uniforms[ii].type, static_cast<uint32_t>(type[ii])); + EXPECT_EQ(data_es2.uniforms[ii].name_length + 1, + static_cast<uint32_t>(name_length[ii])); + } } } // namespace gles2 } // namespace gpu - diff --git a/chromium/gpu/command_buffer/client/query_tracker.h b/chromium/gpu/command_buffer/client/query_tracker.h index 72e29e71c42..d7e65cadb7d 100644 --- a/chromium/gpu/command_buffer/client/query_tracker.h +++ b/chromium/gpu/command_buffer/client/query_tracker.h @@ -27,7 +27,7 @@ class GLES2Implementation; // Manages buckets of QuerySync instances in mapped memory. class GLES2_IMPL_EXPORT QuerySyncManager { public: - static const size_t kSyncsPerBucket = 4096; + static const size_t kSyncsPerBucket = 1024; struct Bucket { explicit Bucket(QuerySync* sync_mem) diff --git a/chromium/gpu/command_buffer/client/query_tracker_unittest.cc b/chromium/gpu/command_buffer/client/query_tracker_unittest.cc index 53f51954059..f6f48ecef2a 100644 --- a/chromium/gpu/command_buffer/client/query_tracker_unittest.cc +++ b/chromium/gpu/command_buffer/client/query_tracker_unittest.cc @@ -161,24 +161,23 @@ TEST_F(QueryTrackerTest, Query) { EXPECT_EQ(kToken, query->token()); EXPECT_EQ(1, query->submit_count()); - // Check CheckResultsAvailable. - EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); - EXPECT_FALSE(query->NeverUsed()); - EXPECT_TRUE(query->Pending()); - // Flush only once if no more flushes happened between a call to // EndQuery command and CheckResultsAvailable // Advance put_ so flush calls in CheckResultsAvailable go through // and updates flush_generation count helper_->Noop(1); - // Set Query in pending state_ to simulate EndQuery command is called - query->MarkAsPending(kToken); - EXPECT_TRUE(query->Pending()); + // Store FlushGeneration count after EndQuery is called uint32 gen1 = GetFlushGeneration(); + + // Check CheckResultsAvailable. EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); + EXPECT_FALSE(query->NeverUsed()); + EXPECT_TRUE(query->Pending()); + uint32 gen2 = GetFlushGeneration(); EXPECT_NE(gen1, gen2); + // Repeated calls to CheckResultsAvailable should not flush unnecessarily EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); gen1 = GetFlushGeneration(); diff --git a/chromium/gpu/command_buffer/client/ring_buffer_test.cc b/chromium/gpu/command_buffer/client/ring_buffer_test.cc index c1aab8837a8..ac5634aa236 100644 --- a/chromium/gpu/command_buffer/client/ring_buffer_test.cc +++ b/chromium/gpu/command_buffer/client/ring_buffer_test.cc @@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/message_loop/message_loop.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/command_buffer_service.h" @@ -17,10 +16,6 @@ #include "gpu/command_buffer/service/transfer_buffer_manager.h" #include "testing/gtest/include/gtest/gtest.h" -#if defined(OS_MACOSX) -#include "base/mac/scoped_nsautorelease_pool.h" -#endif - namespace gpu { using testing::Return; @@ -96,10 +91,6 @@ class BaseRingBufferTest : public testing::Test { return command_buffer_->GetLastState().token; } -#if defined(OS_MACOSX) - base::mac::ScopedNSAutoreleasePool autorelease_pool_; -#endif - base::MessageLoop message_loop_; scoped_ptr<AsyncAPIMock> api_mock_; scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; scoped_ptr<CommandBufferService> command_buffer_; diff --git a/chromium/gpu/command_buffer/client/share_group.cc b/chromium/gpu/command_buffer/client/share_group.cc index c7e3845607d..f5c9bf1144c 100644 --- a/chromium/gpu/command_buffer/client/share_group.cc +++ b/chromium/gpu/command_buffer/client/share_group.cc @@ -19,8 +19,8 @@ namespace gles2 { ShareGroupContextData::IdHandlerData::IdHandlerData() : flush_generation_(0) {} ShareGroupContextData::IdHandlerData::~IdHandlerData() {} -COMPILE_ASSERT(gpu::kInvalidResource == 0, - INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS); +static_assert(gpu::kInvalidResource == 0, + "GL expects kInvalidResource to be 0"); // The standard id handler. class IdHandler : public IdHandlerInterface { @@ -60,18 +60,41 @@ class IdHandler : public IdHandlerInterface { (gl_impl->*delete_fn)(n, ids); // We need to ensure that the delete call is evaluated on the service side // before any other contexts issue commands using these client ids. - // TODO(vmiura): Can remove this by virtualizing internal ids, however - // this code only affects PPAPI for now. - gl_impl->helper()->CommandBufferHelper::Flush(); + gl_impl->helper()->CommandBufferHelper::OrderingBarrier(); return true; } // Overridden from IdHandlerInterface. - bool MarkAsUsedForBind(GLuint id) override { - if (id == 0) - return true; + bool MarkAsUsedForBind(GLES2Implementation* gl_impl, + GLenum target, + GLuint id, + BindFn bind_fn) override { base::AutoLock auto_lock(lock_); - return id_allocator_.MarkAsUsed(id); + bool result = id ? id_allocator_.MarkAsUsed(id) : true; + (gl_impl->*bind_fn)(target, id); + return result; + } + bool MarkAsUsedForBind(GLES2Implementation* gl_impl, + GLenum target, + GLuint index, + GLuint id, + BindIndexedFn bind_fn) override { + base::AutoLock auto_lock(lock_); + bool result = id ? id_allocator_.MarkAsUsed(id) : true; + (gl_impl->*bind_fn)(target, index, id); + return result; + } + bool MarkAsUsedForBind(GLES2Implementation* gl_impl, + GLenum target, + GLuint index, + GLuint id, + GLintptr offset, + GLsizeiptr size, + BindIndexedRangeFn bind_fn) override { + base::AutoLock auto_lock(lock_); + bool result = id ? id_allocator_.MarkAsUsed(id) : true; + (gl_impl->*bind_fn)(target, index, id, offset, size); + return result; } void FreeContext(GLES2Implementation* gl_impl) override {} @@ -147,13 +170,56 @@ class StrictIdHandler : public IdHandlerInterface { } // Overridden from IdHandler. - bool MarkAsUsedForBind(GLuint id) override { + bool MarkAsUsedForBind(GLES2Implementation* gl_impl, + GLenum target, + GLuint id, + BindFn bind_fn) override { +#ifndef NDEBUG + if (id != 0) { + base::AutoLock auto_lock(lock_); + DCHECK(id_states_[id - 1] == kIdInUse); + } +#endif + // StrictIdHandler is used if |bind_generates_resource| is false. In that + // case, |bind_fn| will not use Flush() after helper->Bind*(), so it is OK + // to call |bind_fn| without holding the lock. + (gl_impl->*bind_fn)(target, id); + return true; + } + bool MarkAsUsedForBind(GLES2Implementation* gl_impl, + GLenum target, + GLuint index, + GLuint id, + BindIndexedFn bind_fn) override { +#ifndef NDEBUG + if (id != 0) { + base::AutoLock auto_lock(lock_); + DCHECK(id_states_[id - 1] == kIdInUse); + } +#endif + // StrictIdHandler is used if |bind_generates_resource| is false. In that + // case, |bind_fn| will not use Flush() after helper->Bind*(), so it is OK + // to call |bind_fn| without holding the lock. + (gl_impl->*bind_fn)(target, index, id); + return true; + } + bool MarkAsUsedForBind(GLES2Implementation* gl_impl, + GLenum target, + GLuint index, + GLuint id, + GLintptr offset, + GLsizeiptr size, + BindIndexedRangeFn bind_fn) override { #ifndef NDEBUG if (id != 0) { base::AutoLock auto_lock(lock_); DCHECK(id_states_[id - 1] == kIdInUse); } #endif + // StrictIdHandler is used if |bind_generates_resource| is false. In that + // case, |bind_fn| will not use Flush() after helper->Bind*(), so it is OK + // to call |bind_fn| without holding the lock. + (gl_impl->*bind_fn)(target, index, id, offset, size); return true; } @@ -218,7 +284,28 @@ class NonReusedIdHandler : public IdHandlerInterface { } // Overridden from IdHandlerInterface. - bool MarkAsUsedForBind(GLuint /* id */) override { + bool MarkAsUsedForBind(GLES2Implementation* /* gl_impl */, + GLenum /* target */, + GLuint /* id */, + BindFn /* bind_fn */) override { + // This is only used for Shaders and Programs which have no bind. + return false; + } + bool MarkAsUsedForBind(GLES2Implementation* /* gl_impl */, + GLenum /* target */, + GLuint /* index */, + GLuint /* id */, + BindIndexedFn /* bind_fn */) override { + // This is only used for Shaders and Programs which have no bind. + return false; + } + bool MarkAsUsedForBind(GLES2Implementation* /* gl_impl */, + GLenum /* target */, + GLuint /* index */, + GLuint /* id */, + GLintptr /* offset */, + GLsizeiptr /* size */, + BindIndexedRangeFn /* bind_fn */) override { // This is only used for Shaders and Programs which have no bind. return false; } @@ -249,7 +336,7 @@ ShareGroup::ShareGroup(bool bind_generates_resource) } } } - program_info_manager_.reset(ProgramInfoManager::Create(false)); + program_info_manager_.reset(new ProgramInfoManager); } void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) { diff --git a/chromium/gpu/command_buffer/client/share_group.h b/chromium/gpu/command_buffer/client/share_group.h index c66704b7fd6..c1500043190 100644 --- a/chromium/gpu/command_buffer/client/share_group.h +++ b/chromium/gpu/command_buffer/client/share_group.h @@ -19,6 +19,11 @@ class GLES2ImplementationTest; class ProgramInfoManager; typedef void (GLES2Implementation::*DeleteFn)(GLsizei n, const GLuint* ids); +typedef void (GLES2Implementation::*BindFn)(GLenum target, GLuint id); +typedef void (GLES2Implementation::*BindIndexedFn)( \ + GLenum target, GLuint index, GLuint id); +typedef void (GLES2Implementation::*BindIndexedRangeFn)( \ + GLenum target, GLuint index, GLuint id, GLintptr offset, GLsizeiptr size); class ShareGroupContextData { public: @@ -55,7 +60,27 @@ class IdHandlerInterface { DeleteFn delete_fn) = 0; // Marks an id as used for glBind functions. id = 0 does nothing. - virtual bool MarkAsUsedForBind(GLuint id) = 0; + virtual bool MarkAsUsedForBind( + GLES2Implementation* gl_impl, + GLenum target, + GLuint id, + BindFn bind_fn) = 0; + // This is for glBindBufferBase. + virtual bool MarkAsUsedForBind( + GLES2Implementation* gl_impl, + GLenum target, + GLuint index, + GLuint id, + BindIndexedFn bind_fn) = 0; + // This is for glBindBufferRange. + virtual bool MarkAsUsedForBind( + GLES2Implementation* gl_impl, + GLenum target, + GLuint index, + GLuint id, + GLintptr offset, + GLsizeiptr size, + BindIndexedRangeFn bind_fn) = 0; // Called when a context in the share group is destructed. virtual void FreeContext(GLES2Implementation* gl_impl) = 0; diff --git a/chromium/gpu/command_buffer/client/transfer_buffer.cc b/chromium/gpu/command_buffer/client/transfer_buffer.cc index da00d87d17e..cb02f15144e 100644 --- a/chromium/gpu/command_buffer/client/transfer_buffer.cc +++ b/chromium/gpu/command_buffer/client/transfer_buffer.cc @@ -7,8 +7,8 @@ #include "gpu/command_buffer/client/transfer_buffer.h" #include "base/bits.h" -#include "base/debug/trace_event.h" #include "base/logging.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" namespace gpu { diff --git a/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc b/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc index 7dac4f5d062..1a2a4b07dd1 100644 --- a/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc +++ b/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc @@ -82,6 +82,7 @@ void TransferBufferTest::TearDown() { .Times(1) .RetiresOnSaturation(); EXPECT_CALL(*command_buffer(), OnFlush()).Times(AtMost(1)); + EXPECT_CALL(*command_buffer(), Flush(_)).Times(AtMost(1)); transfer_buffer_.reset(); } diff --git a/chromium/gpu/command_buffer/client/vertex_array_object_manager.cc b/chromium/gpu/command_buffer/client/vertex_array_object_manager.cc index a1098e960f2..415abe610ce 100644 --- a/chromium/gpu/command_buffer/client/vertex_array_object_manager.cc +++ b/chromium/gpu/command_buffer/client/vertex_array_object_manager.cc @@ -47,7 +47,8 @@ class GLES2_IMPL_EXPORT VertexArrayObject { normalized_(GL_FALSE), pointer_(NULL), gl_stride_(0), - divisor_(0) { + divisor_(0), + integer_(GL_FALSE) { } bool enabled() const { @@ -94,19 +95,25 @@ class GLES2_IMPL_EXPORT VertexArrayObject { return divisor_; } + GLboolean integer() const { + return integer_; + } + void SetInfo( GLuint buffer_id, GLint size, GLenum type, GLboolean normalized, GLsizei gl_stride, - const GLvoid* pointer) { + const GLvoid* pointer, + GLboolean integer) { buffer_id_ = buffer_id; size_ = size; type_ = type; normalized_ = normalized; gl_stride_ = gl_stride; pointer_ = pointer; + integer_ = integer; } void SetDivisor(GLuint divisor) { @@ -138,6 +145,8 @@ class GLES2_IMPL_EXPORT VertexArrayObject { // Divisor, for geometry instancing. GLuint divisor_; + + GLboolean integer_; }; typedef std::vector<VertexAttrib> VertexAttribs; @@ -155,7 +164,7 @@ class GLES2_IMPL_EXPORT VertexArrayObject { void SetAttribPointer( GLuint buffer_id, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, - const void* ptr); + const void* ptr, GLboolean integer); bool GetVertexAttrib( GLuint index, GLenum pname, uint32* param) const; @@ -240,7 +249,8 @@ void VertexArrayObject::SetAttribPointer( GLenum type, GLboolean normalized, GLsizei stride, - const void* ptr) { + const void* ptr, + GLboolean integer) { if (index < vertex_attribs_.size()) { VertexAttrib& attrib = vertex_attribs_[index]; if (attrib.IsClientSide() && attrib.enabled()) { @@ -248,7 +258,7 @@ void VertexArrayObject::SetAttribPointer( DCHECK_GE(num_client_side_pointers_enabled_, 0); } - attrib.SetInfo(buffer_id, size, type, normalized, stride, ptr); + attrib.SetInfo(buffer_id, size, type, normalized, stride, ptr, integer); if (attrib.IsClientSide() && attrib.enabled()) { ++num_client_side_pointers_enabled_; @@ -282,9 +292,11 @@ bool VertexArrayObject::GetVertexAttrib( case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: *param = attrib->normalized(); break; + case GL_VERTEX_ATTRIB_ARRAY_INTEGER: + *param = attrib->integer(); + break; default: return false; // pass through to service side. - break; } return true; } @@ -429,13 +441,14 @@ bool VertexArrayObjectManager::SetAttribPointer( GLenum type, GLboolean normalized, GLsizei stride, - const void* ptr) { + const void* ptr, + GLboolean integer) { // Client side arrays are not allowed in vaos. if (buffer_id == 0 && !IsDefaultVAOBound()) { return false; } bound_vertex_array_object_->SetAttribPointer( - buffer_id, index, size, type, normalized, stride, ptr); + buffer_id, index, size, type, normalized, stride, ptr, integer); return true; } diff --git a/chromium/gpu/command_buffer/client/vertex_array_object_manager.h b/chromium/gpu/command_buffer/client/vertex_array_object_manager.h index 8638584343d..8714521f62d 100644 --- a/chromium/gpu/command_buffer/client/vertex_array_object_manager.h +++ b/chromium/gpu/command_buffer/client/vertex_array_object_manager.h @@ -88,7 +88,8 @@ class GLES2_IMPL_EXPORT VertexArrayObjectManager { GLenum type, GLboolean normalized, GLsizei stride, - const void* ptr); + const void* ptr, + GLboolean integer); void SetAttribDivisor(GLuint index, GLuint divisor); @@ -117,7 +118,7 @@ class GLES2_IMPL_EXPORT VertexArrayObjectManager { VertexArrayObject* bound_vertex_array_object_; VertexArrayObjectMap vertex_array_objects_; - bool support_client_side_arrays_; + const bool support_client_side_arrays_; DISALLOW_COPY_AND_ASSIGN(VertexArrayObjectManager); }; diff --git a/chromium/gpu/command_buffer/client/vertex_array_object_manager_unittest.cc b/chromium/gpu/command_buffer/client/vertex_array_object_manager_unittest.cc index e643baff250..927eafc001d 100644 --- a/chromium/gpu/command_buffer/client/vertex_array_object_manager_unittest.cc +++ b/chromium/gpu/command_buffer/client/vertex_array_object_manager_unittest.cc @@ -5,6 +5,7 @@ #include "gpu/command_buffer/client/vertex_array_object_manager.h" #include <GLES2/gl2ext.h> +#include <GLES3/gl3.h> #include "testing/gtest/include/gtest/gtest.h" namespace gpu { @@ -79,13 +80,13 @@ TEST_F(VertexArrayObjectManagerTest, UnbindBuffer) { for (size_t ii = 0; ii < arraysize(ids); ++ii) { EXPECT_TRUE(manager_->BindVertexArray(ids[ii], &changed)); EXPECT_TRUE(manager_->SetAttribPointer( - kBufferToUnbind, 0, 4, GL_FLOAT, false, 0, 0)); + kBufferToUnbind, 0, 4, GL_FLOAT, false, 0, 0, GL_FALSE)); EXPECT_TRUE(manager_->SetAttribPointer( - kBufferToRemain, 1, 4, GL_FLOAT, false, 0, 0)); + kBufferToRemain, 1, 4, GL_FLOAT, false, 0, 0, GL_FALSE)); EXPECT_TRUE(manager_->SetAttribPointer( - kBufferToUnbind, 2, 4, GL_FLOAT, false, 0, 0)); + kBufferToUnbind, 2, 4, GL_FLOAT, false, 0, 0, GL_FALSE)); EXPECT_TRUE(manager_->SetAttribPointer( - kBufferToRemain, 3, 4, GL_FLOAT, false, 0, 0)); + kBufferToRemain, 3, 4, GL_FLOAT, false, 0, 0, GL_FALSE)); for (size_t jj = 0; jj < 4u; ++jj) { manager_->SetAttribEnable(jj, true); } @@ -135,7 +136,7 @@ TEST_F(VertexArrayObjectManagerTest, GetSet) { const char* dummy = "dummy"; const void* p = reinterpret_cast<const void*>(dummy); manager_->SetAttribEnable(1, true); - manager_->SetAttribPointer(123, 1, 3, GL_BYTE, true, 3, p); + manager_->SetAttribPointer(123, 1, 3, GL_BYTE, true, 3, p, GL_TRUE); uint32 param; void* ptr; EXPECT_TRUE(manager_->GetVertexAttrib( @@ -153,6 +154,9 @@ TEST_F(VertexArrayObjectManagerTest, GetSet) { EXPECT_TRUE(manager_->GetVertexAttrib( 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, ¶m)); EXPECT_NE(0u, param); + EXPECT_TRUE(manager_->GetVertexAttrib( + 1, GL_VERTEX_ATTRIB_ARRAY_INTEGER, ¶m)); + EXPECT_EQ(1u, param); EXPECT_TRUE(manager_->GetAttribPointer( 1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr)); EXPECT_EQ(p, ptr); @@ -173,10 +177,10 @@ TEST_F(VertexArrayObjectManagerTest, HaveEnabledClientSideArrays) { EXPECT_FALSE(manager_->HaveEnabledClientSideBuffers()); // Check turning on an array and assigning a buffer. manager_->SetAttribEnable(1, true); - manager_->SetAttribPointer(123, 1, 3, GL_BYTE, true, 3, NULL); + manager_->SetAttribPointer(123, 1, 3, GL_BYTE, true, 3, NULL, GL_FALSE); EXPECT_FALSE(manager_->HaveEnabledClientSideBuffers()); // Check unassigning a buffer. - manager_->SetAttribPointer(0, 1, 3, GL_BYTE, true, 3, NULL); + manager_->SetAttribPointer(0, 1, 3, GL_BYTE, true, 3, NULL, GL_FALSE); EXPECT_TRUE(manager_->HaveEnabledClientSideBuffers()); // Check disabling the array. manager_->SetAttribEnable(1, false); diff --git a/chromium/gpu/command_buffer/cmd_buffer_functions.txt b/chromium/gpu/command_buffer/cmd_buffer_functions.txt index 92053e02d88..a7ec6cebbf1 100644 --- a/chromium/gpu/command_buffer/cmd_buffer_functions.txt +++ b/chromium/gpu/command_buffer/cmd_buffer_functions.txt @@ -8,9 +8,13 @@ GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); GL_APICALL void GL_APIENTRY glAttachShader (GLidProgram program, GLidShader shader); GL_APICALL void GL_APIENTRY glBindAttribLocation (GLidProgram program, GLuint index, const char* name); GL_APICALL void GL_APIENTRY glBindBuffer (GLenumBufferTarget target, GLidBindBuffer buffer); +GL_APICALL void GL_APIENTRY glBindBufferBase (GLenumIndexedBufferTarget target, GLuint index, GLidBindBuffer buffer); +GL_APICALL void GL_APIENTRY glBindBufferRange (GLenumIndexedBufferTarget target, GLuint index, GLidBindBuffer buffer, GLintptrNotNegative offset, GLsizeiptr size); GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenumFrameBufferTarget target, GLidBindFramebuffer framebuffer); GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenumRenderBufferTarget target, GLidBindRenderbuffer renderbuffer); +GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLidBindSampler sampler); GL_APICALL void GL_APIENTRY glBindTexture (GLenumTextureBindTarget target, GLidBindTexture texture); +GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenumTransformFeedbackBindTarget target, GLidBindTransformFeedback transformfeedback); GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); GL_APICALL void GL_APIENTRY glBlendEquation ( GLenumEquation mode ); GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenumEquation modeRGB, GLenumEquation modeAlpha); @@ -20,15 +24,24 @@ GL_APICALL void GL_APIENTRY glBufferData (GLenumBufferTarget target, GLs GL_APICALL void GL_APIENTRY glBufferSubData (GLenumBufferTarget target, GLintptrNotNegative offset, GLsizeiptr size, const void* data); GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenumFrameBufferTarget target); GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearBufferfi (GLenumBufferfv buffer, GLint drawbuffers, GLfloat depth, GLint stencil); +GL_APICALL void GL_APIENTRY glClearBufferfv (GLenumBufferfv buffer, GLint drawbuffers, const GLfloat* value); +GL_APICALL void GL_APIENTRY glClearBufferiv (GLenumBufferiv buffer, GLint drawbuffers, const GLint* value); +GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenumBufferuiv buffer, GLint drawbuffers, const GLuint* value); GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfieldSyncFlushFlags flags, GLuint64 timeout); GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); GL_APICALL void GL_APIENTRY glCompileShader (GLidShader shader); GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenumTextureTarget target, GLint level, GLenumCompressedTextureFormat internalformat, GLsizei width, GLsizei height, GLintTextureBorder border, GLsizei imageSize, const void* data); GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenumTextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenumCompressedTextureFormat format, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenumTexture3DTarget target, GLint level, GLenumCompressedTextureFormat internalformat, GLsizei width, GLsizei height, GLsizei depth, GLintTextureBorder border, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D (GLenumTexture3DTarget target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenumCompressedTextureFormat format, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenumBufferTarget readtarget, GLenumBufferTarget writetarget, GLintptrNotNegative readoffset, GLintptrNotNegative writeoffset, GLsizeiptr size); GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenumTextureTarget target, GLint level, GLenumTextureInternalFormat internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLintTextureBorder border); GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenumTextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenumTexture3DTarget target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenumShaderType type); GL_APICALL void GL_APIENTRY glCullFace (GLenumFaceType mode); @@ -36,8 +49,11 @@ GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizeiNotNegative n, const GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizeiNotNegative n, const GLuint* framebuffers); GL_APICALL void GL_APIENTRY glDeleteProgram (GLidProgram program); GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizeiNotNegative n, const GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizeiNotNegative n, const GLuint* samplers); +GL_APICALL void GL_APIENTRY glDeleteSync (GLidSync sync); GL_APICALL void GL_APIENTRY glDeleteShader (GLidShader shader); GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizeiNotNegative n, const GLuint* textures); +GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizeiNotNegative n, const GLuint* ids); GL_APICALL void GL_APIENTRY glDepthFunc (GLenumCmpFunction func); GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); @@ -46,65 +62,100 @@ GL_APICALL void GL_APIENTRY glDisable (GLenumCapability cap); GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); GL_APICALL void GL_APIENTRY glDrawArrays (GLenumDrawMode mode, GLint first, GLsizei count); GL_APICALL void GL_APIENTRY glDrawElements (GLenumDrawMode mode, GLsizei count, GLenumIndexType type, const void* indices); +GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenumDrawMode mode, GLuint start, GLuint end, GLsizei count, GLenumIndexType type, const void* indices); GL_APICALL void GL_APIENTRY glEnable (GLenumCapability cap); GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenumSyncCondition condition, GLbitfieldSyncFlags flags); GL_APICALL void GL_APIENTRY glFinish (void); GL_APICALL void GL_APIENTRY glFlush (void); GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenumFrameBufferTarget target, GLenumAttachment attachment, GLenumRenderBufferTarget renderbuffertarget, GLidRenderbuffer renderbuffer); GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenumFrameBufferTarget target, GLenumAttachment attachment, GLenumTextureTarget textarget, GLidTexture texture, GLintZeroOnly level); +GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenumFrameBufferTarget target, GLenumAttachment attachment, GLidTexture texture, GLint level, GLint layer); GL_APICALL void GL_APIENTRY glFrontFace (GLenumFaceMode mode); GL_APICALL void GL_APIENTRY glGenBuffers (GLsizeiNotNegative n, GLuint* buffers); GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenumTextureBindTarget target); GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizeiNotNegative n, GLuint* framebuffers); GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizeiNotNegative n, GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glGenSamplers (GLsizeiNotNegative n, GLuint* samplers); GL_APICALL void GL_APIENTRY glGenTextures (GLsizeiNotNegative n, GLuint* textures); +GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizeiNotNegative n, GLuint* ids); GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLidProgram program, GLuint index, GLsizeiNotNegative bufsize, GLsizeiOptional* length, GLint* size, GLenum* type, char* name); GL_APICALL void GL_APIENTRY glGetActiveUniform (GLidProgram program, GLuint index, GLsizeiNotNegative bufsize, GLsizeiOptional* length, GLint* size, GLenum* type, char* name); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLidProgram program, GLuint index, GLenumUniformBlockParameter pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLidProgram program, GLuint index, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* name); +GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLidProgram program, GLsizeiNotNegative count, const GLuint* indices, GLenumUniformParameter pname, GLint* params); GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLidProgram program, GLsizeiNotNegative maxcount, GLsizeiOptional* count, GLuint* shaders); GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLidProgram program, const char* name); GL_APICALL void GL_APIENTRY glGetBooleanv (GLenumGLState pname, GLboolean* params); GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenumBufferTarget target, GLenumBufferParameter pname, GLint* params); GL_APICALL GLenum GL_APIENTRY glGetError (void); GL_APICALL void GL_APIENTRY glGetFloatv (GLenumGLState pname, GLfloat* params); +GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLidProgram program, const char* name); GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenumFrameBufferTarget target, GLenumAttachment attachment, GLenumFrameBufferParameter pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetInteger64v (GLenumGLState pname, GLint64* params); +GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenumIndexedGLState pname, GLuint index, GLint* data); +GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenumIndexedGLState pname, GLuint index, GLint64* data); GL_APICALL void GL_APIENTRY glGetIntegerv (GLenumGLState pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenumRenderBufferTarget target, GLenumRenderBufferFormat format, GLenumInternalFormatParameter pname, GLsizeiNotNegative bufSize, GLint* params); GL_APICALL void GL_APIENTRY glGetProgramiv (GLidProgram program, GLenumProgramParameter pname, GLint* params); GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLidProgram program, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* infolog); GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenumRenderBufferTarget target, GLenumRenderBufferParameter pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLidSampler sampler, GLenumSamplerParameter pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLidSampler sampler, GLenumSamplerParameter pname, GLint* params); GL_APICALL void GL_APIENTRY glGetShaderiv (GLidShader shader, GLenumShaderParameter pname, GLint* params); GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLidShader shader, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* infolog); GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenumShaderType shadertype, GLenumShaderPrecision precisiontype, GLint* range, GLint* precision); GL_APICALL void GL_APIENTRY glGetShaderSource (GLidShader shader, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* source); GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenumStringType name); +GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenumSyncParameter pname, GLsizeiNotNegative bufsize, GLsizeiOptional* length, GLint* values); GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenumGetTexParamTarget target, GLenumTextureParameter pname, GLfloat* params); GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenumGetTexParamTarget target, GLenumTextureParameter pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLidProgram program, GLuint index, GLsizeiNotNegative bufsize, GLsizeiOptional* length, GLsizei* size, GLenum* type, char* name); +GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLidProgram program, const char* name); GL_APICALL void GL_APIENTRY glGetUniformfv (GLidProgram program, GLintUniformLocation location, GLfloat* params); GL_APICALL void GL_APIENTRY glGetUniformiv (GLidProgram program, GLintUniformLocation location, GLint* params); +GL_APICALL void GL_APIENTRY glGetUniformuiv (GLidProgram program, GLintUniformLocation location, GLuint* params); +GL_APICALL void GL_APIENTRY glGetUniformIndices (GLidProgram program, GLsizeiNotNegative count, const char* const* names, GLuint* indices); GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLidProgram program, const char* name); GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenumVertexAttribute pname, GLfloat* params); GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenumVertexAttribute pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenumVertexAttribute pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenumVertexAttribute pname, GLuint* params); GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenumVertexPointer pname, void** pointer); GL_APICALL void GL_APIENTRY glHint (GLenumHintTarget target, GLenumHintMode mode); +GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenumInvalidateFrameBufferTarget target, GLsizeiNotNegative count, const GLenum* attachments); +GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenumInvalidateFrameBufferTarget target, GLsizeiNotNegative count, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLidBuffer buffer); GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenumCapability cap); GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLidFramebuffer framebuffer); GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLidProgram program); GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLidRenderbuffer renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLidSampler sampler); GL_APICALL GLboolean GL_APIENTRY glIsShader (GLidShader shader); +GL_APICALL GLboolean GL_APIENTRY glIsSync (GLidSync sync); GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLidTexture texture); +GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLidTransformFeedback transformfeedback); GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); GL_APICALL void GL_APIENTRY glLinkProgram (GLidProgram program); +GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void); GL_APICALL void GL_APIENTRY glPixelStorei (GLenumPixelStore pname, GLintPixelStoreAlignment param); GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); -GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenumReadPixelFormat format, GLenumPixelType type, void* pixels); +GL_APICALL void GL_APIENTRY glReadBuffer (GLenum src); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenumReadPixelFormat format, GLenumReadPixelType type, void* pixels); GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenumRenderBufferTarget target, GLenumRenderBufferFormat internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void); GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); +GL_APICALL void GL_APIENTRY glSamplerParameterf (GLidBindSampler sampler, GLenumSamplerParameter pname, GLfloat param); +GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLidBindSampler sampler, GLenumSamplerParameter pname, const GLfloat* params); +GL_APICALL void GL_APIENTRY glSamplerParameteri (GLidBindSampler sampler, GLenumSamplerParameter pname, GLint param); +GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLidBindSampler sampler, GLenumSamplerParameter pname, const GLint* params); GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glShaderBinary (GLsizeiNotNegative n, const GLuint* shaders, GLenumShaderBinaryFormat binaryformat, const void* binary, GLsizeiNotNegative length); GL_APICALL void GL_APIENTRY glShaderSource (GLidShader shader, GLsizeiNotNegative count, const GLchar* const* str, const GLint* length); GL_APICALL void GL_APIENTRY glShallowFinishCHROMIUM (void); GL_APICALL void GL_APIENTRY glShallowFlushCHROMIUM (void); +GL_APICALL void GL_APIENTRY glOrderingBarrierCHROMIUM (void); GL_APICALL void GL_APIENTRY glStencilFunc (GLenumCmpFunction func, GLint ref, GLuint mask); GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenumFaceType face, GLenumCmpFunction func, GLint ref, GLuint mask); GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); @@ -112,30 +163,49 @@ GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenumFaceType face, GL_APICALL void GL_APIENTRY glStencilOp (GLenumStencilOp fail, GLenumStencilOp zfail, GLenumStencilOp zpass); GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenumFaceType face, GLenumStencilOp fail, GLenumStencilOp zfail, GLenumStencilOp zpass); GL_APICALL void GL_APIENTRY glTexImage2D (GLenumTextureTarget target, GLint level, GLintTextureInternalFormat internalformat, GLsizei width, GLsizei height, GLintTextureBorder border, GLenumTextureFormat format, GLenumPixelType type, const void* pixels); +GL_APICALL void GL_APIENTRY glTexImage3D (GLenumTexture3DTarget target, GLint level, GLintTextureInternalFormat internalformat, GLsizei width, GLsizei height, GLsizei depth, GLintTextureBorder border, GLenumTextureFormat format, GLenumPixelType type, const void* pixels); GL_APICALL void GL_APIENTRY glTexParameterf (GLenumTextureBindTarget target, GLenumTextureParameter pname, GLfloat param); GL_APICALL void GL_APIENTRY glTexParameterfv (GLenumTextureBindTarget target, GLenumTextureParameter pname, const GLfloat* params); GL_APICALL void GL_APIENTRY glTexParameteri (GLenumTextureBindTarget target, GLenumTextureParameter pname, GLint param); GL_APICALL void GL_APIENTRY glTexParameteriv (GLenumTextureBindTarget target, GLenumTextureParameter pname, const GLint* params); +GL_APICALL void GL_APIENTRY glTexStorage3D (GLenumTexture3DTarget target, GLsizei levels, GLenumTextureInternalFormatStorage internalFormat, GLsizei width, GLsizei height, GLsizei depth); GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenumTextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenumTextureFormat format, GLenumPixelType type, const void* pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3D (GLenumTexture3DTarget target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenumTextureFormat format, GLenumPixelType type, const void* pixels); +GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLidProgram program, GLsizeiNotNegative count, const char* const* varyings, GLenumBufferMode buffermode); GL_APICALL void GL_APIENTRY glUniform1f (GLintUniformLocation location, GLfloat x); GL_APICALL void GL_APIENTRY glUniform1fv (GLintUniformLocation location, GLsizeiNotNegative count, const GLfloat* v); GL_APICALL void GL_APIENTRY glUniform1i (GLintUniformLocation location, GLint x); GL_APICALL void GL_APIENTRY glUniform1iv (GLintUniformLocation location, GLsizeiNotNegative count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform1ui (GLintUniformLocation location, GLuint x); +GL_APICALL void GL_APIENTRY glUniform1uiv (GLintUniformLocation location, GLsizeiNotNegative count, const GLuint* v); GL_APICALL void GL_APIENTRY glUniform2f (GLintUniformLocation location, GLfloat x, GLfloat y); GL_APICALL void GL_APIENTRY glUniform2fv (GLintUniformLocation location, GLsizeiNotNegative count, const GLfloat* v); GL_APICALL void GL_APIENTRY glUniform2i (GLintUniformLocation location, GLint x, GLint y); GL_APICALL void GL_APIENTRY glUniform2iv (GLintUniformLocation location, GLsizeiNotNegative count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform2ui (GLintUniformLocation location, GLuint x, GLuint y); +GL_APICALL void GL_APIENTRY glUniform2uiv (GLintUniformLocation location, GLsizeiNotNegative count, const GLuint* v); GL_APICALL void GL_APIENTRY glUniform3f (GLintUniformLocation location, GLfloat x, GLfloat y, GLfloat z); GL_APICALL void GL_APIENTRY glUniform3fv (GLintUniformLocation location, GLsizeiNotNegative count, const GLfloat* v); GL_APICALL void GL_APIENTRY glUniform3i (GLintUniformLocation location, GLint x, GLint y, GLint z); GL_APICALL void GL_APIENTRY glUniform3iv (GLintUniformLocation location, GLsizeiNotNegative count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform3ui (GLintUniformLocation location, GLuint x, GLuint y, GLuint z); +GL_APICALL void GL_APIENTRY glUniform3uiv (GLintUniformLocation location, GLsizeiNotNegative count, const GLuint* v); GL_APICALL void GL_APIENTRY glUniform4f (GLintUniformLocation location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GL_APICALL void GL_APIENTRY glUniform4fv (GLintUniformLocation location, GLsizeiNotNegative count, const GLfloat* v); GL_APICALL void GL_APIENTRY glUniform4i (GLintUniformLocation location, GLint x, GLint y, GLint z, GLint w); GL_APICALL void GL_APIENTRY glUniform4iv (GLintUniformLocation location, GLsizeiNotNegative count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform4ui (GLintUniformLocation location, GLuint x, GLuint y, GLuint z, GLuint w); +GL_APICALL void GL_APIENTRY glUniform4uiv (GLintUniformLocation location, GLsizeiNotNegative count, const GLuint* v); +GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLidProgram program, GLuint index, GLuint binding); GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLintUniformLocation location, GLsizeiNotNegative count, GLbooleanFalseOnly transpose, const GLfloat* value); GL_APICALL void GL_APIENTRY glUseProgram (GLidZeroProgram program); GL_APICALL void GL_APIENTRY glValidateProgram (GLidProgram program); GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); @@ -146,8 +216,14 @@ GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GL GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint indx, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint indx, const GLint* values); +GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint indx, GLuint x, GLuint y, GLuint z, GLuint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint indx, const GLuint* values); +GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint indx, GLintVertexAttribSize size, GLenumVertexAttribIType type, GLsizei stride, const void* ptr); GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLintVertexAttribSize size, GLenumVertexAttribType type, GLboolean normalized, GLsizei stride, const void* ptr); GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfieldSyncFlushFlags flags, GLuint64 timeout); GL_APICALL void GL_APIENTRY glBlitFramebufferCHROMIUM (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenumBlitFilter filter); GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleCHROMIUM (GLenumRenderBufferTarget target, GLsizei samples, GLenumRenderBufferFormat internalformat, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenumRenderBufferTarget target, GLsizei samples, GLenumRenderBufferFormat internalformat, GLsizei width, GLsizei height); @@ -157,7 +233,9 @@ GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizeiNotNegative n, GLuin GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizeiNotNegative n, const GLuint* queries); GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLidQuery id); GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenumQueryTarget target, GLidQuery id); +GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenumTransformFeedbackPrimitiveMode primitivemode); GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenumQueryTarget target); +GL_APICALL void GL_APIENTRY glEndTransformFeedback (void); GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenumQueryTarget target, GLenumQueryParameter pname, GLint* params); GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLidQuery id, GLenumQueryObjectParameter pname, GLuint* params); GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar* marker); @@ -177,14 +255,18 @@ GL_APICALL void* GL_APIENTRY glMapBufferCHROMIUM (GLuint target, GLenum a GL_APICALL GLboolean GL_APIENTRY glUnmapBufferCHROMIUM (GLuint target); GL_APICALL void* GL_APIENTRY glMapBufferSubDataCHROMIUM (GLuint target, GLintptrNotNegative offset, GLsizeiptr size, GLenum access); GL_APICALL void GL_APIENTRY glUnmapBufferSubDataCHROMIUM (const void* mem); +GL_APICALL void* GL_APIENTRY glMapBufferRange (GLenumBufferTarget target, GLintptrNotNegative offset, GLsizeiptr size, GLbitfieldMapBufferAccess access); +GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenumBufferTarget target); GL_APICALL void* GL_APIENTRY glMapTexSubImage2DCHROMIUM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum access); GL_APICALL void GL_APIENTRY glUnmapTexSubImage2DCHROMIUM (const void* mem); GL_APICALL void GL_APIENTRY glResizeCHROMIUM (GLuint width, GLuint height, GLfloat scale_factor); GL_APICALL const GLchar* GL_APIENTRY glGetRequestableExtensionsCHROMIUM (void); GL_APICALL void GL_APIENTRY glRequestExtensionCHROMIUM (const char* extension); GL_APICALL void GL_APIENTRY glRateLimitOffscreenContextCHROMIUM (void); -GL_APICALL void GL_APIENTRY glGetMultipleIntegervCHROMIUM (const GLenum* pnames, GLuint count, GLint* results, GLsizeiptr size); GL_APICALL void GL_APIENTRY glGetProgramInfoCHROMIUM (GLidProgram program, GLsizeiNotNegative bufsize, GLsizei* size, void* info); +GL_APICALL void GL_APIENTRY glGetUniformBlocksCHROMIUM (GLidProgram program, GLsizeiNotNegative bufsize, GLsizei* size, void* info); +GL_APICALL void GL_APIENTRY glGetTransformFeedbackVaryingsCHROMIUM (GLidProgram program, GLsizeiNotNegative bufsize, GLsizei* size, void* info); +GL_APICALL void GL_APIENTRY glGetUniformsES3CHROMIUM (GLidProgram program, GLsizeiNotNegative bufsize, GLsizei* size, void* info); GL_APICALL GLuint GL_APIENTRY glCreateStreamTextureCHROMIUM (GLuint texture); GL_APICALL GLuint GL_APIENTRY glCreateImageCHROMIUM (ClientBuffer buffer, GLsizei width, GLsizei height, GLenum internalformat); GL_APICALL void GL_APIENTRY glDestroyImageCHROMIUM (GLuint image_id); @@ -192,7 +274,8 @@ GL_APICALL GLuint GL_APIENTRY glCreateGpuMemoryBufferImageCHROMIUM (GLsize GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLidShader shader, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* source); GL_APICALL void GL_APIENTRY glPostSubBufferCHROMIUM (GLint x, GLint y, GLint width, GLint height); GL_APICALL void GL_APIENTRY glTexImageIOSurface2DCHROMIUM (GLenumTextureBindTarget target, GLsizei width, GLsizei height, GLuint ioSurfaceId, GLuint plane); -GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLint level, GLintTextureInternalFormat internalformat, GLenumPixelType dest_type); +GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLintTextureInternalFormat internalformat, GLenumPixelType dest_type); +GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLint xoffset, GLint yoffset); GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenumDrawMode mode, GLint first, GLsizei count, GLsizei primcount); GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenumDrawMode mode, GLsizei count, GLenumIndexType type, const void* indices, GLsizei primcount); GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor); @@ -211,7 +294,7 @@ GL_APICALL void GL_APIENTRY glPopulateSubscribedValuesCHROMIUM (GLenumVa GL_APICALL void GL_APIENTRY glUniformValuebufferCHROMIUM (GLintUniformLocation location, GLenumValueBufferTarget target, GLenumSubscriptionTarget subscription); GL_APICALL void GL_APIENTRY glBindTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId); GL_APICALL void GL_APIENTRY glReleaseTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId); -GL_APICALL void GL_APIENTRY glTraceBeginCHROMIUM (const char* name); +GL_APICALL void GL_APIENTRY glTraceBeginCHROMIUM (const char* category_name, const char* trace_name); GL_APICALL void GL_APIENTRY glTraceEndCHROMIUM (void); GL_APICALL void GL_APIENTRY glAsyncTexSubImage2DCHROMIUM (GLenumTextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenumTextureFormat format, GLenumPixelType type, const void* data); GL_APICALL void GL_APIENTRY glAsyncTexImage2DCHROMIUM (GLenumTextureTarget target, GLint level, GLenumTextureInternalFormat internalformat, GLsizei width, GLsizei height, GLintTextureBorder border, GLenumTextureFormat format, GLenumPixelType type, const void* pixels); @@ -224,6 +307,7 @@ GL_APICALL void GL_APIENTRY glWaitSyncPointCHROMIUM (GLuint sync_point); GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei count, const GLenum* bufs); GL_APICALL void GL_APIENTRY glDiscardBackbufferCHROMIUM (void); GL_APICALL void GL_APIENTRY glScheduleOverlayPlaneCHROMIUM (GLint plane_z_order, GLenum plane_transform, GLuint overlay_texture_id, GLint bounds_x, GLint bounds_y, GLint bounds_width, GLint bounds_height, GLfloat uv_x, GLfloat uv_y, GLfloat uv_width, GLfloat uv_height); +GL_APICALL void GL_APIENTRY glSwapInterval (GLint interval); // Extension CHROMIUM_path_rendering. GL_APICALL void GL_APIENTRY glMatrixLoadfCHROMIUM (GLenumMatrixMode matrixMode, const GLfloat* m); diff --git a/chromium/gpu/command_buffer/command_buffer.gypi b/chromium/gpu/command_buffer/command_buffer.gypi index 473da92eebd..c355f2ce1bd 100644 --- a/chromium/gpu/command_buffer/command_buffer.gypi +++ b/chromium/gpu/command_buffer/command_buffer.gypi @@ -8,7 +8,6 @@ 'gles2_utils_target': 0, }, 'target_conditions': [ - # This part is shared between the targets defined below. ['gles2_utils_target==1', { 'defines': [ 'GLES2_UTILS_IMPLEMENTATION', diff --git a/chromium/gpu/command_buffer/command_buffer_nacl.gyp b/chromium/gpu/command_buffer/command_buffer_nacl.gyp index 319fc67711e..e05899968cf 100644 --- a/chromium/gpu/command_buffer/command_buffer_nacl.gyp +++ b/chromium/gpu/command_buffer/command_buffer_nacl.gyp @@ -27,7 +27,6 @@ 'build_nonsfi_helper': 1, }, 'dependencies': [ - '../../native_client/tools.gyp:prep_toolchain', '../../base/base_nacl.gyp:base_nacl', '../../base/base_nacl.gyp:base_nacl_nonsfi', '../../third_party/khronos/khronos.gyp:khronos_headers', diff --git a/chromium/gpu/command_buffer/common/BUILD.gn b/chromium/gpu/command_buffer/common/BUILD.gn index ad6d3200e91..6f3ec0c4bd2 100644 --- a/chromium/gpu/command_buffer/common/BUILD.gn +++ b/chromium/gpu/command_buffer/common/BUILD.gn @@ -2,7 +2,25 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -source_set("common") { +# The files here go into the "gpu" component in a component build (with +# "command_buffer_common" just forwarding) and goes into a static library in +# non-component build. This needs to match the GYP build which was likely an +# attempt to make larger components to help with loading. +group("common") { + if (is_component_build) { + public_deps = [ + "//gpu", + ] + } else { + public_deps = [ + ":common_sources", + ] + } +} + +source_set("common_sources") { + visibility = [ "//gpu/*" ] + sources = [ "bitfield_helpers.h", "buffer.cc", @@ -28,9 +46,11 @@ source_set("common") { "mailbox_holder.h", "thread_local.h", "time.h", + "value_state.cc", + "value_state.h", ] - defines = [ "GPU_IMPLEMENTATION" ] + configs += [ "//gpu:gpu_implementation" ] deps = [ ":gles2_utils", diff --git a/chromium/gpu/command_buffer/common/capabilities.cc b/chromium/gpu/command_buffer/common/capabilities.cc index f905f4e53d6..8dd208beca4 100644 --- a/chromium/gpu/command_buffer/common/capabilities.cc +++ b/chromium/gpu/command_buffer/common/capabilities.cc @@ -6,10 +6,58 @@ namespace gpu { +Capabilities::PerStagePrecisions::PerStagePrecisions() { +} + Capabilities::Capabilities() - : post_sub_buffer(false), + : max_combined_texture_image_units(0), + max_cube_map_texture_size(0), + max_fragment_uniform_vectors(0), + max_renderbuffer_size(0), + max_texture_image_units(0), + max_texture_size(0), + max_varying_vectors(0), + max_vertex_attribs(0), + max_vertex_texture_image_units(0), + max_vertex_uniform_vectors(0), + num_compressed_texture_formats(0), + num_shader_binary_formats(0), + bind_generates_resource_chromium(0), + max_3d_texture_size(0), + max_array_texture_layers(0), + max_color_attachments(0), + max_combined_fragment_uniform_components(0), + max_combined_uniform_blocks(0), + max_combined_vertex_uniform_components(0), + max_draw_buffers(0), + max_element_index(0), + max_elements_indices(0), + max_elements_vertices(0), + max_fragment_input_components(0), + max_fragment_uniform_blocks(0), + max_fragment_uniform_components(0), + max_program_texel_offset(0), + max_samples(0), + max_server_wait_timeout(0), + max_transform_feedback_interleaved_components(0), + max_transform_feedback_separate_attribs(0), + max_transform_feedback_separate_components(0), + max_uniform_block_size(0), + max_uniform_buffer_bindings(0), + max_varying_components(0), + max_vertex_output_components(0), + max_vertex_uniform_blocks(0), + max_vertex_uniform_components(0), + min_program_texel_offset(0), + num_extensions(0), + num_program_binary_formats(0), + uniform_buffer_offset_alignment(1), + post_sub_buffer(false), egl_image_external(false), + texture_format_atc(false), texture_format_bgra8888(false), + texture_format_dxt1(false), + texture_format_dxt5(false), texture_format_etc1(false), texture_format_etc1_npot(false), texture_rectangle(false), @@ -21,7 +69,10 @@ Capabilities::Capabilities() image(false), future_sync_points(false), blend_equation_advanced(false), - blend_equation_advanced_coherent(false) { + blend_equation_advanced_coherent(false), + texture_rg(false), + major_version(2), + minor_version(0) { } } // namespace gpu diff --git a/chromium/gpu/command_buffer/common/capabilities.h b/chromium/gpu/command_buffer/common/capabilities.h index fff1ef854e3..569d573ed62 100644 --- a/chromium/gpu/command_buffer/common/capabilities.h +++ b/chromium/gpu/command_buffer/common/capabilities.h @@ -7,12 +7,114 @@ #include "gpu/gpu_export.h" +// From gl2.h. We want to avoid including gl headers because client-side and +// service-side headers conflict. +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 + namespace gpu { +// NOTE: When adding members to this struct, also add corresponding +// entries in gpu/ipc/gpu_command_buffer_traits_multi.h. + struct GPU_EXPORT Capabilities { + struct ShaderPrecision { + ShaderPrecision() : min_range(0), max_range(0), precision(0) {} + int min_range; + int max_range; + int precision; + }; + + struct PerStagePrecisions { + PerStagePrecisions(); + + ShaderPrecision low_int; + ShaderPrecision medium_int; + ShaderPrecision high_int; + ShaderPrecision low_float; + ShaderPrecision medium_float; + ShaderPrecision high_float; + }; + + Capabilities(); + + template <typename T> + void VisitStagePrecisions(unsigned stage, + PerStagePrecisions* precisions, + const T& visitor) { + visitor(stage, GL_LOW_INT, &precisions->low_int); + visitor(stage, GL_MEDIUM_INT, &precisions->medium_int); + visitor(stage, GL_HIGH_INT, &precisions->high_int); + visitor(stage, GL_LOW_FLOAT, &precisions->low_float); + visitor(stage, GL_MEDIUM_FLOAT, &precisions->medium_float); + visitor(stage, GL_HIGH_FLOAT, &precisions->high_float); + } + + template <typename T> + void VisitPrecisions(const T& visitor) { + VisitStagePrecisions(GL_VERTEX_SHADER, &vertex_shader_precisions, visitor); + VisitStagePrecisions(GL_FRAGMENT_SHADER, &fragment_shader_precisions, + visitor); + } + + PerStagePrecisions vertex_shader_precisions; + PerStagePrecisions fragment_shader_precisions; + int max_combined_texture_image_units; + int max_cube_map_texture_size; + int max_fragment_uniform_vectors; + int max_renderbuffer_size; + int max_texture_image_units; + int max_texture_size; + int max_varying_vectors; + int max_vertex_attribs; + int max_vertex_texture_image_units; + int max_vertex_uniform_vectors; + int num_compressed_texture_formats; + int num_shader_binary_formats; + int bind_generates_resource_chromium; + + int max_3d_texture_size; + int max_array_texture_layers; + int max_color_attachments; + int max_combined_fragment_uniform_components; + int max_combined_uniform_blocks; + int max_combined_vertex_uniform_components; + int max_draw_buffers; + int max_element_index; + int max_elements_indices; + int max_elements_vertices; + int max_fragment_input_components; + int max_fragment_uniform_blocks; + int max_fragment_uniform_components; + int max_program_texel_offset; + int max_samples; + int max_server_wait_timeout; + int max_transform_feedback_interleaved_components; + int max_transform_feedback_separate_attribs; + int max_transform_feedback_separate_components; + int max_uniform_block_size; + int max_uniform_buffer_bindings; + int max_varying_components; + int max_vertex_output_components; + int max_vertex_uniform_blocks; + int max_vertex_uniform_components; + int min_program_texel_offset; + int num_extensions; + int num_program_binary_formats; + int uniform_buffer_offset_alignment; + bool post_sub_buffer; bool egl_image_external; + bool texture_format_atc; bool texture_format_bgra8888; + bool texture_format_dxt1; + bool texture_format_dxt5; bool texture_format_etc1; bool texture_format_etc1_npot; bool texture_rectangle; @@ -25,8 +127,10 @@ struct GPU_EXPORT Capabilities { bool future_sync_points; bool blend_equation_advanced; bool blend_equation_advanced_coherent; + bool texture_rg; - Capabilities(); + int major_version; + int minor_version; }; } // namespace gpu diff --git a/chromium/gpu/command_buffer/common/cmd_buffer_common.h b/chromium/gpu/command_buffer/common/cmd_buffer_common.h index 828731bfee1..a2b8c5a5478 100644 --- a/chromium/gpu/command_buffer/common/cmd_buffer_common.h +++ b/chromium/gpu/command_buffer/common/cmd_buffer_common.h @@ -57,14 +57,16 @@ struct CommandHeader { // variable sized commands like immediate commands or Noop. template <typename T> void SetCmd() { - COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); + static_assert(T::kArgFlags == cmd::kFixed, + "T::kArgFlags should equal cmd::kFixed"); Init(T::kCmdId, ComputeNumEntries(sizeof(T))); // NOLINT } // Sets the header by a size in bytes of the immediate data after the command. template <typename T> void SetCmdBySize(uint32_t size_of_data_in_bytes) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + static_assert(T::kArgFlags == cmd::kAtLeastN, + "T::kArgFlags should equal cmd::kAtLeastN"); Init(T::kCmdId, ComputeNumEntries(sizeof(T) + size_of_data_in_bytes)); // NOLINT } @@ -72,13 +74,15 @@ struct CommandHeader { // Sets the header by a size in bytes. template <typename T> void SetCmdByTotalSize(uint32_t size_in_bytes) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + static_assert(T::kArgFlags == cmd::kAtLeastN, + "T::kArgFlags should equal cmd::kAtLeastN"); DCHECK_GE(size_in_bytes, sizeof(T)); // NOLINT Init(T::kCmdId, ComputeNumEntries(size_in_bytes)); } }; -COMPILE_ASSERT(sizeof(CommandHeader) == 4, Sizeof_CommandHeader_is_not_4); +static_assert(sizeof(CommandHeader) == 4, + "size of CommandHeader should equal 4"); // Union that defines possible command buffer entries. union CommandBufferEntry { @@ -91,8 +95,9 @@ union CommandBufferEntry { #define GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT 4 const size_t kCommandBufferEntrySize = GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT; -COMPILE_ASSERT(sizeof(CommandBufferEntry) == kCommandBufferEntrySize, - Sizeof_CommandBufferEntry_is_not_4); +static_assert(sizeof(CommandBufferEntry) == kCommandBufferEntrySize, + "size of CommandBufferEntry should equal " + "kCommandBufferEntrySize"); // Command buffer is GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT byte aligned. #pragma pack(push, GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT) @@ -104,7 +109,8 @@ COMPILE_ASSERT(sizeof(CommandBufferEntry) == kCommandBufferEntrySize, // cmd: Address of command. template <typename T> void* ImmediateDataAddress(T* cmd) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + static_assert(T::kArgFlags == cmd::kAtLeastN, + "T::kArgFlags should equal cmd::kAtLeastN"); return reinterpret_cast<char*>(cmd) + sizeof(*cmd); } @@ -114,7 +120,8 @@ template <typename T> // Parameters: // cmd: Address of command. void* NextCmdAddress(void* cmd) { - COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); + static_assert(T::kArgFlags == cmd::kFixed, + "T::kArgFlags should equal cmd::kFixed"); return reinterpret_cast<char*>(cmd) + sizeof(T); } @@ -125,7 +132,8 @@ void* NextCmdAddress(void* cmd) { // size_of_data_in_bytes: Size of the data for the command. template <typename T> void* NextImmediateCmdAddress(void* cmd, uint32_t size_of_data_in_bytes) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + static_assert(T::kArgFlags == cmd::kAtLeastN, + "T::kArgFlags should equal cmd::kAtLeastN"); return reinterpret_cast<char*>(cmd) + sizeof(T) + // NOLINT RoundSizeToMultipleOfEntries(size_of_data_in_bytes); } @@ -138,7 +146,8 @@ void* NextImmediateCmdAddress(void* cmd, uint32_t size_of_data_in_bytes) { template <typename T> void* NextImmediateCmdAddressTotalSize(void* cmd, uint32_t total_size_in_bytes) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + static_assert(T::kArgFlags == cmd::kAtLeastN, + "T::kArgFlags should equal cmd::kAtLeastN"); DCHECK_GE(total_size_in_bytes, sizeof(T)); // NOLINT return reinterpret_cast<char*>(cmd) + RoundSizeToMultipleOfEntries(total_size_in_bytes); @@ -174,7 +183,7 @@ enum CommandId { kLastCommonId = 255 // reserve 256 spaces for common commands. }; -COMPILE_ASSERT(kNumCommands - 1 <= kLastCommonId, Too_many_common_commands); +static_assert(kNumCommands - 1 <= kLastCommonId, "too many commands"); const char* GetCommandName(CommandId id); @@ -203,8 +212,9 @@ struct Noop { CommandHeader header; }; -COMPILE_ASSERT(sizeof(Noop) == 4, Sizeof_Noop_is_not_4); -COMPILE_ASSERT(offsetof(Noop, header) == 0, Offsetof_Noop_header_not_0); +static_assert(sizeof(Noop) == 4, "size of Noop should equal 4"); +static_assert(offsetof(Noop, header) == 0, + "offset of Noop.header should equal 0"); // The SetToken command puts a token in the command stream that you can // use to check if that token has been passed in the command stream. @@ -231,11 +241,11 @@ struct SetToken { uint32_t token; }; -COMPILE_ASSERT(sizeof(SetToken) == 8, Sizeof_SetToken_is_not_8); -COMPILE_ASSERT(offsetof(SetToken, header) == 0, - Offsetof_SetToken_header_not_0); -COMPILE_ASSERT(offsetof(SetToken, token) == 4, - Offsetof_SetToken_token_not_4); +static_assert(sizeof(SetToken) == 8, "size of SetToken should equal 8"); +static_assert(offsetof(SetToken, header) == 0, + "offset of SetToken.header should equal 0"); +static_assert(offsetof(SetToken, token) == 4, + "offset of SetToken.token should equal 4"); // Sets the size of a bucket for collecting data on the service side. // This is a utility for gathering data on the service side so it can be used @@ -274,13 +284,14 @@ struct SetBucketSize { uint32_t size; }; -COMPILE_ASSERT(sizeof(SetBucketSize) == 12, Sizeof_SetBucketSize_is_not_8); -COMPILE_ASSERT(offsetof(SetBucketSize, header) == 0, - Offsetof_SetBucketSize_header_not_0); -COMPILE_ASSERT(offsetof(SetBucketSize, bucket_id) == 4, - Offsetof_SetBucketSize_bucket_id_4); -COMPILE_ASSERT(offsetof(SetBucketSize, size) == 8, - Offsetof_SetBucketSize_size_8); +static_assert(sizeof(SetBucketSize) == 12, + "size of SetBucketSize should equal 12"); +static_assert(offsetof(SetBucketSize, header) == 0, + "offset of SetBucketSize.header should equal 0"); +static_assert(offsetof(SetBucketSize, bucket_id) == 4, + "offset of SetBucketSize.bucket_id should equal 4"); +static_assert(offsetof(SetBucketSize, size) == 8, + "offset of SetBucketSize.size should equal 8"); // Sets the contents of a portion of a bucket on the service side from data in // shared memory. @@ -330,19 +341,20 @@ struct SetBucketData { uint32_t shared_memory_offset; }; -COMPILE_ASSERT(sizeof(SetBucketData) == 24, Sizeof_SetBucketData_is_not_24); -COMPILE_ASSERT(offsetof(SetBucketData, header) == 0, - Offsetof_SetBucketData_header_not_0); -COMPILE_ASSERT(offsetof(SetBucketData, bucket_id) == 4, - Offsetof_SetBucketData_bucket_id_not_4); -COMPILE_ASSERT(offsetof(SetBucketData, offset) == 8, - Offsetof_SetBucketData_offset_not_8); -COMPILE_ASSERT(offsetof(SetBucketData, size) == 12, - Offsetof_SetBucketData_size_not_12); -COMPILE_ASSERT(offsetof(SetBucketData, shared_memory_id) == 16, - Offsetof_SetBucketData_shared_memory_id_not_16); -COMPILE_ASSERT(offsetof(SetBucketData, shared_memory_offset) == 20, - Offsetof_SetBucketData_shared_memory_offset_not_20); +static_assert(sizeof(SetBucketData) == 24, + "size of SetBucketData should be 24"); +static_assert(offsetof(SetBucketData, header) == 0, + "offset of SetBucketData.header should be 0"); +static_assert(offsetof(SetBucketData, bucket_id) == 4, + "offset of SetBucketData.bucket_id should be 4"); +static_assert(offsetof(SetBucketData, offset) == 8, + "offset of SetBucketData.offset should be 8"); +static_assert(offsetof(SetBucketData, size) == 12, + "offset of SetBucketData.size should be 12"); +static_assert(offsetof(SetBucketData, shared_memory_id) == 16, + "offset of SetBucketData.shared_memory_id should be 16"); +static_assert(offsetof(SetBucketData, shared_memory_offset) == 20, + "offset of SetBucketData.shared_memory_offset should be 20"); // Sets the contents of a portion of a bucket on the service side from data in // the command buffer. @@ -382,16 +394,16 @@ struct SetBucketDataImmediate { uint32_t size; }; -COMPILE_ASSERT(sizeof(SetBucketDataImmediate) == 16, - Sizeof_SetBucketDataImmediate_is_not_24); -COMPILE_ASSERT(offsetof(SetBucketDataImmediate, header) == 0, - Offsetof_SetBucketDataImmediate_header_not_0); -COMPILE_ASSERT(offsetof(SetBucketDataImmediate, bucket_id) == 4, - Offsetof_SetBucketDataImmediate_bucket_id_not_4); -COMPILE_ASSERT(offsetof(SetBucketDataImmediate, offset) == 8, - Offsetof_SetBucketDataImmediate_offset_not_8); -COMPILE_ASSERT(offsetof(SetBucketDataImmediate, size) == 12, - Offsetof_SetBucketDataImmediate_size_not_12); +static_assert(sizeof(SetBucketDataImmediate) == 16, + "size of SetBucketDataImmediate should be 16"); +static_assert(offsetof(SetBucketDataImmediate, header) == 0, + "offset of SetBucketDataImmediate.header should be 0"); +static_assert(offsetof(SetBucketDataImmediate, bucket_id) == 4, + "offset of SetBucketDataImmediate.bucket_id should be 4"); +static_assert(offsetof(SetBucketDataImmediate, offset) == 8, + "offset of SetBucketDataImmediate.offset should be 8"); +static_assert(offsetof(SetBucketDataImmediate, size) == 12, + "offset of SetBucketDataImmediate.size should be 12"); // Gets the start of a bucket the service has available. Sending a variable size // result back to the client and the portion of that result that fits in the @@ -455,21 +467,22 @@ struct GetBucketStart { uint32_t data_memory_offset; }; -COMPILE_ASSERT(sizeof(GetBucketStart) == 28, Sizeof_GetBucketStart_is_not_28); -COMPILE_ASSERT(offsetof(GetBucketStart, header) == 0, - Offsetof_GetBucketStart_header_not_0); -COMPILE_ASSERT(offsetof(GetBucketStart, bucket_id) == 4, - Offsetof_GetBucketStart_bucket_id_not_4); -COMPILE_ASSERT(offsetof(GetBucketStart, result_memory_id) == 8, - Offsetof_GetBucketStart_result_memory_id_not_8); -COMPILE_ASSERT(offsetof(GetBucketStart, result_memory_offset) == 12, - Offsetof_GetBucketStart_result_memory_offset_not_12); -COMPILE_ASSERT(offsetof(GetBucketStart, data_memory_size) == 16, - Offsetof_GetBucketStart_data_memory_size_not_16); -COMPILE_ASSERT(offsetof(GetBucketStart, data_memory_id) == 20, - Offsetof_GetBucketStart_data_memory_id_not_20); -COMPILE_ASSERT(offsetof(GetBucketStart, data_memory_offset) == 24, - Offsetof_GetBucketStart_data_memory_offset_not_24); +static_assert(sizeof(GetBucketStart) == 28, + "size of GetBucketStart should be 28"); +static_assert(offsetof(GetBucketStart, header) == 0, + "offset of GetBucketStart.header should be 0"); +static_assert(offsetof(GetBucketStart, bucket_id) == 4, + "offset of GetBucketStart.bucket_id should be 4"); +static_assert(offsetof(GetBucketStart, result_memory_id) == 8, + "offset of GetBucketStart.result_memory_id should be 8"); +static_assert(offsetof(GetBucketStart, result_memory_offset) == 12, + "offset of GetBucketStart.result_memory_offset should be 12"); +static_assert(offsetof(GetBucketStart, data_memory_size) == 16, + "offset of GetBucketStart.data_memory_size should be 16"); +static_assert(offsetof(GetBucketStart, data_memory_id) == 20, + "offset of GetBucketStart.data_memory_id should be 20"); +static_assert(offsetof(GetBucketStart, data_memory_offset) == 24, + "offset of GetBucketStart.data_memory_offset should be 24"); // Gets a piece of a result the service as available. // See GetBucketSize. @@ -518,19 +531,20 @@ struct GetBucketData { uint32_t shared_memory_offset; }; -COMPILE_ASSERT(sizeof(GetBucketData) == 24, Sizeof_GetBucketData_is_not_20); -COMPILE_ASSERT(offsetof(GetBucketData, header) == 0, - Offsetof_GetBucketData_header_not_0); -COMPILE_ASSERT(offsetof(GetBucketData, bucket_id) == 4, - Offsetof_GetBucketData_bucket_id_not_4); -COMPILE_ASSERT(offsetof(GetBucketData, offset) == 8, - Offsetof_GetBucketData_offset_not_8); -COMPILE_ASSERT(offsetof(GetBucketData, size) == 12, - Offsetof_GetBucketData_size_not_12); -COMPILE_ASSERT(offsetof(GetBucketData, shared_memory_id) == 16, - Offsetof_GetBucketData_shared_memory_id_not_16); -COMPILE_ASSERT(offsetof(GetBucketData, shared_memory_offset) == 20, - Offsetof_GetBucketData_shared_memory_offset_not_20); +static_assert(sizeof(GetBucketData) == 24, + "size of GetBucketData should be 24"); +static_assert(offsetof(GetBucketData, header) == 0, + "offset of GetBucketData.header should be 0"); +static_assert(offsetof(GetBucketData, bucket_id) == 4, + "offset of GetBucketData.bucket_id should be 4"); +static_assert(offsetof(GetBucketData, offset) == 8, + "offset of GetBucketData.offset should be 8"); +static_assert(offsetof(GetBucketData, size) == 12, + "offset of GetBucketData.size should be 12"); +static_assert(offsetof(GetBucketData, shared_memory_id) == 16, + "offset of GetBucketData.shared_memory_id should be 16"); +static_assert(offsetof(GetBucketData, shared_memory_offset) == 20, + "offset of GetBucketData.shared_memory_offset should be 20"); } // namespace cmd diff --git a/chromium/gpu/command_buffer/common/command_buffer.h b/chromium/gpu/command_buffer/common/command_buffer.h index d846ec11a63..b69936320ec 100644 --- a/chromium/gpu/command_buffer/common/command_buffer.h +++ b/chromium/gpu/command_buffer/common/command_buffer.h @@ -90,6 +90,11 @@ class GPU_EXPORT CommandBuffer { // subsequent Flushes on the same GpuChannel. virtual void Flush(int32 put_offset) = 0; + // As Flush, ensures that on the service side, commands up to put_offset + // are processed but before subsequent commands on the same GpuChannel but + // flushing to the service may be deferred. + virtual void OrderingBarrier(int32 put_offset) = 0; + // The writer calls this to wait until the current token is within a // specific range, inclusive. Can return early if an error is generated. virtual void WaitForTokenInRange(int32 start, int32 end) = 0; diff --git a/chromium/gpu/command_buffer/common/command_buffer_mock.h b/chromium/gpu/command_buffer/common/command_buffer_mock.h index b7366f8c47f..9e1f7131e7a 100644 --- a/chromium/gpu/command_buffer/common/command_buffer_mock.h +++ b/chromium/gpu/command_buffer/common/command_buffer_mock.h @@ -25,6 +25,7 @@ class MockCommandBuffer : public CommandBufferServiceBase { MOCK_METHOD0(GetLastState, State()); MOCK_METHOD0(GetLastToken, int32()); MOCK_METHOD1(Flush, void(int32 put_offset)); + MOCK_METHOD1(OrderingBarrier, void(int32 put_offset)); MOCK_METHOD2(WaitForTokenInRange, void(int32 start, int32 end)); MOCK_METHOD2(WaitForGetOffsetInRange, void(int32 start, int32 end)); MOCK_METHOD1(SetGetBuffer, void(int32 transfer_buffer_id)); diff --git a/chromium/gpu/command_buffer/common/command_buffer_shared_test.cc b/chromium/gpu/command_buffer/common/command_buffer_shared_test.cc index 0615f7421d6..83aed36882b 100644 --- a/chromium/gpu/command_buffer/common/command_buffer_shared_test.cc +++ b/chromium/gpu/command_buffer/common/command_buffer_shared_test.cc @@ -5,8 +5,11 @@ // This file contains the tests for the CommandBufferSharedState class. #include "gpu/command_buffer/common/command_buffer_shared.h" + #include "base/bind.h" +#include "base/location.h" #include "base/memory/scoped_ptr.h" +#include "base/single_thread_task_runner.h" #include "base/threading/thread.h" #include "testing/gtest/include/gtest/gtest.h" @@ -60,9 +63,8 @@ TEST_F(CommandBufferSharedTest, TestConsistency) { memset(buffer.get(), 0, kSize * sizeof(int32)); consumer.Start(); - consumer.message_loop()->PostTask( - FROM_HERE, base::Bind(&WriteToState, buffer.get(), - shared_state_.get())); + consumer.task_runner()->PostTask( + FROM_HERE, base::Bind(&WriteToState, buffer.get(), shared_state_.get())); CommandBuffer::State last_state; while (1) { diff --git a/chromium/gpu/command_buffer/common/constants.h b/chromium/gpu/command_buffer/common/constants.h index 054708f4a60..d06836c0d71 100644 --- a/chromium/gpu/command_buffer/common/constants.h +++ b/chromium/gpu/command_buffer/common/constants.h @@ -23,7 +23,8 @@ namespace error { kInvalidArguments, kLostContext, kGenericError, - kDeferCommandUntilLater + kDeferCommandUntilLater, + kErrorLast = kDeferCommandUntilLater, }; // Return true if the given error code is an actual error. @@ -41,7 +42,17 @@ namespace error { // It is unknown whether this context provoked the loss of context. kUnknown, - kContextLostReasonLast = kUnknown + + // GL_OUT_OF_MEMORY caused this context to be lost. + kOutOfMemory, + + // A failure to make the context current caused it to be lost. + kMakeCurrentFailed, + + // The GPU channel was lost. This error is set client-side. + kGpuChannelLost, + + kContextLostReasonLast = kGpuChannelLost }; } diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format.h b/chromium/gpu/command_buffer/common/gles2_cmd_format.h index c0bc66309b8..db63594f250 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format.h @@ -19,6 +19,7 @@ #include "gpu/command_buffer/common/bitfield_helpers.h" #include "gpu/command_buffer/common/cmd_buffer_common.h" #include "gpu/command_buffer/common/gles2_cmd_ids.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" // GL types are forward declared to avoid including the GL headers. The problem // is determining which GL headers to include from code that is common to the @@ -41,6 +42,9 @@ typedef double GLclampd; typedef void GLvoid; typedef khronos_intptr_t GLintptr; typedef khronos_ssize_t GLsizeiptr; +typedef struct __GLsync *GLsync; +typedef int64_t GLint64; +typedef uint64_t GLuint64; namespace gpu { namespace gles2 { @@ -60,15 +64,18 @@ enum IdNamespaces { kQueries, kVertexArrays, kValuebuffers, + kSamplers, + kTransformFeedbacks, + kSyncs, kNumIdNamespaces }; // These numbers must not change -COMPILE_ASSERT(kBuffers == 0, kBuffers_is_not_0); -COMPILE_ASSERT(kFramebuffers == 1, kFramebuffers_is_not_1); -COMPILE_ASSERT(kProgramsAndShaders == 2, kProgramsAndShaders_is_not_2); -COMPILE_ASSERT(kRenderbuffers == 3, kRenderbuffers_is_not_3); -COMPILE_ASSERT(kTextures == 4, kTextures_is_not_4); +static_assert(kBuffers == 0, "kBuffers should equal 0"); +static_assert(kFramebuffers == 1, "kFramebuffers should equal 1"); +static_assert(kProgramsAndShaders == 2, "kProgramsAndShaders should equal 2"); +static_assert(kRenderbuffers == 3, "kRenderbuffers should equal 3"); +static_assert(kTextures == 4, "kTextures should equal 4"); } // namespace id_namespaces @@ -89,12 +96,6 @@ struct SizedResult { return sizeof(T) * num_results + sizeof(uint32_t); // NOLINT } - // Returns the total size in bytes of the SizedResult for a given size of - // results. - static size_t ComputeSizeFromBytes(size_t size_of_result_in_bytes) { - return size_of_result_in_bytes + sizeof(uint32_t); // NOLINT - } - // Returns the maximum number of results for a given buffer size. static uint32_t ComputeMaxResults(size_t size_of_buffer) { return (size_of_buffer >= sizeof(uint32_t)) ? @@ -120,11 +121,12 @@ struct SizedResult { int32_t data; // this is just here to get an offset. }; -COMPILE_ASSERT(sizeof(SizedResult<int8_t>) == 8, SizedResult_size_not_8); -COMPILE_ASSERT(offsetof(SizedResult<int8_t>, size) == 0, - OffsetOf_SizedResult_size_not_0); -COMPILE_ASSERT(offsetof(SizedResult<int8_t>, data) == 4, - OffsetOf_SizedResult_data_not_4); +static_assert(sizeof(SizedResult<int8_t>) == 8, + "size of SizedResult<int8_t> should be 8"); +static_assert(offsetof(SizedResult<int8_t>, size) == 0, + "offset of SizedResult<int8_t>.size should be 0"); +static_assert(offsetof(SizedResult<int8_t>, data) == 4, + "offset of SizedResult<int8_t>.data should be 4"); // The data for one attrib or uniform from GetProgramInfoCHROMIUM. struct ProgramInput { @@ -144,6 +146,58 @@ struct ProgramInfoHeader { // ProgramInput inputs[num_attribs + num_uniforms]; }; +// The data for one UniformBlock from GetProgramInfoCHROMIUM +struct UniformBlockInfo { + uint32_t binding; // UNIFORM_BLOCK_BINDING + uint32_t data_size; // UNIFORM_BLOCK_DATA_SIZE + uint32_t name_offset; // offset from UniformBlocksHeader to start of name. + uint32_t name_length; // UNIFORM_BLOCK_NAME_LENGTH + uint32_t active_uniforms; // UNIFORM_BLOCK_ACTIVE_UNIFORMS + // offset from UniformBlocksHeader to |active_uniforms| indices. + uint32_t active_uniform_offset; + // UNIFORM_BLOCK_REFERENDED_BY_VERTEX_SHADER + uint32_t referenced_by_vertex_shader; + // UNIFORM_BLOCK_REFERENDED_BY_FRAGMENT_SHADER + uint32_t referenced_by_fragment_shader; +}; + +// The format of the bucket filled out by GetUniformBlocksCHROMIUM +struct UniformBlocksHeader { + uint32_t num_uniform_blocks; + // UniformBlockInfo uniform_blocks[num_uniform_blocks]; +}; + +// The data for one TransformFeedbackVarying from +// GetTransformFeedbackVaringCHROMIUM. +struct TransformFeedbackVaryingInfo { + uint32_t size; + uint32_t type; + uint32_t name_offset; // offset from Header to start of name. + uint32_t name_length; // including the null terminator. +}; + +// The format of the bucket filled out by GetTransformFeedbackVaryingsCHROMIUM +struct TransformFeedbackVaryingsHeader { + uint32_t num_transform_feedback_varyings; + // TransformFeedbackVaryingInfo varyings[num_transform_feedback_varyings]; +}; + +// Parameters of a uniform that can be queried through glGetActiveUniformsiv, +// but not through glGetActiveUniform. +struct UniformES3Info { + int32_t block_index; + int32_t offset; + int32_t array_stride; + int32_t matrix_stride; + int32_t is_row_major; +}; + +// The format of the bucket filled out by GetUniformsivES3CHROMIUM +struct UniformsES3Header { + uint32_t num_uniforms; + // UniformES3Info uniforms[num_uniforms]; +}; + // The format of QuerySync used by EXT_occlusion_query_boolean struct QuerySync { void Reset() { @@ -174,25 +228,52 @@ struct AsyncUploadSync { base::subtle::Atomic32 async_upload_token; }; -COMPILE_ASSERT(sizeof(ProgramInput) == 20, ProgramInput_size_not_20); -COMPILE_ASSERT(offsetof(ProgramInput, type) == 0, - OffsetOf_ProgramInput_type_not_0); -COMPILE_ASSERT(offsetof(ProgramInput, size) == 4, - OffsetOf_ProgramInput_size_not_4); -COMPILE_ASSERT(offsetof(ProgramInput, location_offset) == 8, - OffsetOf_ProgramInput_location_offset_not_8); -COMPILE_ASSERT(offsetof(ProgramInput, name_offset) == 12, - OffsetOf_ProgramInput_name_offset_not_12); -COMPILE_ASSERT(offsetof(ProgramInput, name_length) == 16, - OffsetOf_ProgramInput_name_length_not_16); - -COMPILE_ASSERT(sizeof(ProgramInfoHeader) == 12, ProgramInfoHeader_size_not_12); -COMPILE_ASSERT(offsetof(ProgramInfoHeader, link_status) == 0, - OffsetOf_ProgramInfoHeader_link_status_not_0); -COMPILE_ASSERT(offsetof(ProgramInfoHeader, num_attribs) == 4, - OffsetOf_ProgramInfoHeader_num_attribs_not_4); -COMPILE_ASSERT(offsetof(ProgramInfoHeader, num_uniforms) == 8, - OffsetOf_ProgramInfoHeader_num_uniforms_not_8); +static_assert(sizeof(ProgramInput) == 20, "size of ProgramInput should be 20"); +static_assert(offsetof(ProgramInput, type) == 0, + "offset of ProgramInput.type should be 0"); +static_assert(offsetof(ProgramInput, size) == 4, + "offset of ProgramInput.size should be 4"); +static_assert(offsetof(ProgramInput, location_offset) == 8, + "offset of ProgramInput.location_offset should be 8"); +static_assert(offsetof(ProgramInput, name_offset) == 12, + "offset of ProgramInput.name_offset should be 12"); +static_assert(offsetof(ProgramInput, name_length) == 16, + "offset of ProgramInput.name_length should be 16"); + +static_assert(sizeof(ProgramInfoHeader) == 12, + "size of ProgramInfoHeader should be 12"); +static_assert(offsetof(ProgramInfoHeader, link_status) == 0, + "offset of ProgramInfoHeader.link_status should be 0"); +static_assert(offsetof(ProgramInfoHeader, num_attribs) == 4, + "offset of ProgramInfoHeader.num_attribs should be 4"); +static_assert(offsetof(ProgramInfoHeader, num_uniforms) == 8, + "offset of ProgramInfoHeader.num_uniforms should be 8"); + +static_assert(sizeof(UniformBlockInfo) == 32, + "size of UniformBlockInfo should be 32"); +static_assert(offsetof(UniformBlockInfo, binding) == 0, + "offset of UniformBlockInfo.binding should be 0"); +static_assert(offsetof(UniformBlockInfo, data_size) == 4, + "offset of UniformBlockInfo.data_size should be 4"); +static_assert(offsetof(UniformBlockInfo, name_offset) == 8, + "offset of UniformBlockInfo.name_offset should be 8"); +static_assert(offsetof(UniformBlockInfo, name_length) == 12, + "offset of UniformBlockInfo.name_length should be 12"); +static_assert(offsetof(UniformBlockInfo, active_uniforms) == 16, + "offset of UniformBlockInfo.active_uniforms should be 16"); +static_assert(offsetof(UniformBlockInfo, active_uniform_offset) == 20, + "offset of UniformBlockInfo.active_uniform_offset should be 20"); +static_assert(offsetof(UniformBlockInfo, referenced_by_vertex_shader) == 24, + "offset of UniformBlockInfo.referenced_by_vertex_shader " + "should be 24"); +static_assert(offsetof(UniformBlockInfo, referenced_by_fragment_shader) == 28, + "offset of UniformBlockInfo.referenced_by_fragment_shader " + "should be 28"); + +static_assert(sizeof(UniformBlocksHeader) == 4, + "size of UniformBlocksHeader should be 4"); +static_assert(offsetof(UniformBlocksHeader, num_uniform_blocks) == 0, + "offset of UniformBlocksHeader.num_uniform_blocks should be 0"); namespace cmds { @@ -257,15 +338,17 @@ struct CreateAndConsumeTextureCHROMIUMImmediate { uint32_t client_id; }; -COMPILE_ASSERT(sizeof(CreateAndConsumeTextureCHROMIUMImmediate) == 12, - Sizeof_CreateAndConsumeTextureCHROMIUMImmediate_is_not_12); -COMPILE_ASSERT(offsetof(CreateAndConsumeTextureCHROMIUMImmediate, header) == 0, - OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_header_not_0); -COMPILE_ASSERT(offsetof(CreateAndConsumeTextureCHROMIUMImmediate, target) == 4, - OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_target_not_4); -COMPILE_ASSERT( +static_assert(sizeof(CreateAndConsumeTextureCHROMIUMImmediate) == 12, + "size of CreateAndConsumeTextureCHROMIUMImmediate should be 12"); +static_assert(offsetof(CreateAndConsumeTextureCHROMIUMImmediate, header) == 0, + "offset of CreateAndConsumeTextureCHROMIUMImmediate.header " + "should be 0"); +static_assert(offsetof(CreateAndConsumeTextureCHROMIUMImmediate, target) == 4, + "offset of CreateAndConsumeTextureCHROMIUMImmediate.target " + "should be 4"); +static_assert( offsetof(CreateAndConsumeTextureCHROMIUMImmediate, client_id) == 8, - OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_client_id_not_8); + "offset of CreateAndConsumeTextureCHROMIUMImmediate.client_id should be 8"); #pragma pack(pop) diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 726a30c55be..c25d9d25c72 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -11,6 +11,9 @@ #ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_ +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 + struct ActiveTexture { typedef ActiveTexture ValueType; static const CommandId kCmdId = kActiveTexture; @@ -37,11 +40,11 @@ struct ActiveTexture { uint32_t texture; }; -COMPILE_ASSERT(sizeof(ActiveTexture) == 8, Sizeof_ActiveTexture_is_not_8); -COMPILE_ASSERT(offsetof(ActiveTexture, header) == 0, - OffsetOf_ActiveTexture_header_not_0); -COMPILE_ASSERT(offsetof(ActiveTexture, texture) == 4, - OffsetOf_ActiveTexture_texture_not_4); +static_assert(sizeof(ActiveTexture) == 8, "size of ActiveTexture should be 8"); +static_assert(offsetof(ActiveTexture, header) == 0, + "offset of ActiveTexture header should be 0"); +static_assert(offsetof(ActiveTexture, texture) == 4, + "offset of ActiveTexture texture should be 4"); struct AttachShader { typedef AttachShader ValueType; @@ -71,13 +74,13 @@ struct AttachShader { uint32_t shader; }; -COMPILE_ASSERT(sizeof(AttachShader) == 12, Sizeof_AttachShader_is_not_12); -COMPILE_ASSERT(offsetof(AttachShader, header) == 0, - OffsetOf_AttachShader_header_not_0); -COMPILE_ASSERT(offsetof(AttachShader, program) == 4, - OffsetOf_AttachShader_program_not_4); -COMPILE_ASSERT(offsetof(AttachShader, shader) == 8, - OffsetOf_AttachShader_shader_not_8); +static_assert(sizeof(AttachShader) == 12, "size of AttachShader should be 12"); +static_assert(offsetof(AttachShader, header) == 0, + "offset of AttachShader header should be 0"); +static_assert(offsetof(AttachShader, program) == 4, + "offset of AttachShader program should be 4"); +static_assert(offsetof(AttachShader, shader) == 8, + "offset of AttachShader shader should be 8"); struct BindAttribLocationBucket { typedef BindAttribLocationBucket ValueType; @@ -112,16 +115,16 @@ struct BindAttribLocationBucket { uint32_t name_bucket_id; }; -COMPILE_ASSERT(sizeof(BindAttribLocationBucket) == 16, - Sizeof_BindAttribLocationBucket_is_not_16); -COMPILE_ASSERT(offsetof(BindAttribLocationBucket, header) == 0, - OffsetOf_BindAttribLocationBucket_header_not_0); -COMPILE_ASSERT(offsetof(BindAttribLocationBucket, program) == 4, - OffsetOf_BindAttribLocationBucket_program_not_4); -COMPILE_ASSERT(offsetof(BindAttribLocationBucket, index) == 8, - OffsetOf_BindAttribLocationBucket_index_not_8); -COMPILE_ASSERT(offsetof(BindAttribLocationBucket, name_bucket_id) == 12, - OffsetOf_BindAttribLocationBucket_name_bucket_id_not_12); +static_assert(sizeof(BindAttribLocationBucket) == 16, + "size of BindAttribLocationBucket should be 16"); +static_assert(offsetof(BindAttribLocationBucket, header) == 0, + "offset of BindAttribLocationBucket header should be 0"); +static_assert(offsetof(BindAttribLocationBucket, program) == 4, + "offset of BindAttribLocationBucket program should be 4"); +static_assert(offsetof(BindAttribLocationBucket, index) == 8, + "offset of BindAttribLocationBucket index should be 8"); +static_assert(offsetof(BindAttribLocationBucket, name_bucket_id) == 12, + "offset of BindAttribLocationBucket name_bucket_id should be 12"); struct BindBuffer { typedef BindBuffer ValueType; @@ -151,13 +154,113 @@ struct BindBuffer { uint32_t buffer; }; -COMPILE_ASSERT(sizeof(BindBuffer) == 12, Sizeof_BindBuffer_is_not_12); -COMPILE_ASSERT(offsetof(BindBuffer, header) == 0, - OffsetOf_BindBuffer_header_not_0); -COMPILE_ASSERT(offsetof(BindBuffer, target) == 4, - OffsetOf_BindBuffer_target_not_4); -COMPILE_ASSERT(offsetof(BindBuffer, buffer) == 8, - OffsetOf_BindBuffer_buffer_not_8); +static_assert(sizeof(BindBuffer) == 12, "size of BindBuffer should be 12"); +static_assert(offsetof(BindBuffer, header) == 0, + "offset of BindBuffer header should be 0"); +static_assert(offsetof(BindBuffer, target) == 4, + "offset of BindBuffer target should be 4"); +static_assert(offsetof(BindBuffer, buffer) == 8, + "offset of BindBuffer buffer should be 8"); + +struct BindBufferBase { + typedef BindBufferBase ValueType; + static const CommandId kCmdId = kBindBufferBase; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, GLuint _index, GLuint _buffer) { + SetHeader(); + target = _target; + index = _index; + buffer = _buffer; + } + + void* Set(void* cmd, GLenum _target, GLuint _index, GLuint _buffer) { + static_cast<ValueType*>(cmd)->Init(_target, _index, _buffer); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + uint32_t index; + uint32_t buffer; +}; + +static_assert(sizeof(BindBufferBase) == 16, + "size of BindBufferBase should be 16"); +static_assert(offsetof(BindBufferBase, header) == 0, + "offset of BindBufferBase header should be 0"); +static_assert(offsetof(BindBufferBase, target) == 4, + "offset of BindBufferBase target should be 4"); +static_assert(offsetof(BindBufferBase, index) == 8, + "offset of BindBufferBase index should be 8"); +static_assert(offsetof(BindBufferBase, buffer) == 12, + "offset of BindBufferBase buffer should be 12"); + +struct BindBufferRange { + typedef BindBufferRange ValueType; + static const CommandId kCmdId = kBindBufferRange; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLuint _index, + GLuint _buffer, + GLintptr _offset, + GLsizeiptr _size) { + SetHeader(); + target = _target; + index = _index; + buffer = _buffer; + offset = _offset; + size = _size; + } + + void* Set(void* cmd, + GLenum _target, + GLuint _index, + GLuint _buffer, + GLintptr _offset, + GLsizeiptr _size) { + static_cast<ValueType*>(cmd) + ->Init(_target, _index, _buffer, _offset, _size); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + uint32_t index; + uint32_t buffer; + int32_t offset; + int32_t size; +}; + +static_assert(sizeof(BindBufferRange) == 24, + "size of BindBufferRange should be 24"); +static_assert(offsetof(BindBufferRange, header) == 0, + "offset of BindBufferRange header should be 0"); +static_assert(offsetof(BindBufferRange, target) == 4, + "offset of BindBufferRange target should be 4"); +static_assert(offsetof(BindBufferRange, index) == 8, + "offset of BindBufferRange index should be 8"); +static_assert(offsetof(BindBufferRange, buffer) == 12, + "offset of BindBufferRange buffer should be 12"); +static_assert(offsetof(BindBufferRange, offset) == 16, + "offset of BindBufferRange offset should be 16"); +static_assert(offsetof(BindBufferRange, size) == 20, + "offset of BindBufferRange size should be 20"); struct BindFramebuffer { typedef BindFramebuffer ValueType; @@ -187,13 +290,14 @@ struct BindFramebuffer { uint32_t framebuffer; }; -COMPILE_ASSERT(sizeof(BindFramebuffer) == 12, Sizeof_BindFramebuffer_is_not_12); -COMPILE_ASSERT(offsetof(BindFramebuffer, header) == 0, - OffsetOf_BindFramebuffer_header_not_0); -COMPILE_ASSERT(offsetof(BindFramebuffer, target) == 4, - OffsetOf_BindFramebuffer_target_not_4); -COMPILE_ASSERT(offsetof(BindFramebuffer, framebuffer) == 8, - OffsetOf_BindFramebuffer_framebuffer_not_8); +static_assert(sizeof(BindFramebuffer) == 12, + "size of BindFramebuffer should be 12"); +static_assert(offsetof(BindFramebuffer, header) == 0, + "offset of BindFramebuffer header should be 0"); +static_assert(offsetof(BindFramebuffer, target) == 4, + "offset of BindFramebuffer target should be 4"); +static_assert(offsetof(BindFramebuffer, framebuffer) == 8, + "offset of BindFramebuffer framebuffer should be 8"); struct BindRenderbuffer { typedef BindRenderbuffer ValueType; @@ -223,14 +327,50 @@ struct BindRenderbuffer { uint32_t renderbuffer; }; -COMPILE_ASSERT(sizeof(BindRenderbuffer) == 12, - Sizeof_BindRenderbuffer_is_not_12); -COMPILE_ASSERT(offsetof(BindRenderbuffer, header) == 0, - OffsetOf_BindRenderbuffer_header_not_0); -COMPILE_ASSERT(offsetof(BindRenderbuffer, target) == 4, - OffsetOf_BindRenderbuffer_target_not_4); -COMPILE_ASSERT(offsetof(BindRenderbuffer, renderbuffer) == 8, - OffsetOf_BindRenderbuffer_renderbuffer_not_8); +static_assert(sizeof(BindRenderbuffer) == 12, + "size of BindRenderbuffer should be 12"); +static_assert(offsetof(BindRenderbuffer, header) == 0, + "offset of BindRenderbuffer header should be 0"); +static_assert(offsetof(BindRenderbuffer, target) == 4, + "offset of BindRenderbuffer target should be 4"); +static_assert(offsetof(BindRenderbuffer, renderbuffer) == 8, + "offset of BindRenderbuffer renderbuffer should be 8"); + +struct BindSampler { + typedef BindSampler ValueType; + static const CommandId kCmdId = kBindSampler; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _unit, GLuint _sampler) { + SetHeader(); + unit = _unit; + sampler = _sampler; + } + + void* Set(void* cmd, GLuint _unit, GLuint _sampler) { + static_cast<ValueType*>(cmd)->Init(_unit, _sampler); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t unit; + uint32_t sampler; +}; + +static_assert(sizeof(BindSampler) == 12, "size of BindSampler should be 12"); +static_assert(offsetof(BindSampler, header) == 0, + "offset of BindSampler header should be 0"); +static_assert(offsetof(BindSampler, unit) == 4, + "offset of BindSampler unit should be 4"); +static_assert(offsetof(BindSampler, sampler) == 8, + "offset of BindSampler sampler should be 8"); struct BindTexture { typedef BindTexture ValueType; @@ -260,13 +400,50 @@ struct BindTexture { uint32_t texture; }; -COMPILE_ASSERT(sizeof(BindTexture) == 12, Sizeof_BindTexture_is_not_12); -COMPILE_ASSERT(offsetof(BindTexture, header) == 0, - OffsetOf_BindTexture_header_not_0); -COMPILE_ASSERT(offsetof(BindTexture, target) == 4, - OffsetOf_BindTexture_target_not_4); -COMPILE_ASSERT(offsetof(BindTexture, texture) == 8, - OffsetOf_BindTexture_texture_not_8); +static_assert(sizeof(BindTexture) == 12, "size of BindTexture should be 12"); +static_assert(offsetof(BindTexture, header) == 0, + "offset of BindTexture header should be 0"); +static_assert(offsetof(BindTexture, target) == 4, + "offset of BindTexture target should be 4"); +static_assert(offsetof(BindTexture, texture) == 8, + "offset of BindTexture texture should be 8"); + +struct BindTransformFeedback { + typedef BindTransformFeedback ValueType; + static const CommandId kCmdId = kBindTransformFeedback; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, GLuint _transformfeedback) { + SetHeader(); + target = _target; + transformfeedback = _transformfeedback; + } + + void* Set(void* cmd, GLenum _target, GLuint _transformfeedback) { + static_cast<ValueType*>(cmd)->Init(_target, _transformfeedback); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + uint32_t transformfeedback; +}; + +static_assert(sizeof(BindTransformFeedback) == 12, + "size of BindTransformFeedback should be 12"); +static_assert(offsetof(BindTransformFeedback, header) == 0, + "offset of BindTransformFeedback header should be 0"); +static_assert(offsetof(BindTransformFeedback, target) == 4, + "offset of BindTransformFeedback target should be 4"); +static_assert(offsetof(BindTransformFeedback, transformfeedback) == 8, + "offset of BindTransformFeedback transformfeedback should be 8"); struct BlendColor { typedef BlendColor ValueType; @@ -304,16 +481,17 @@ struct BlendColor { float alpha; }; -COMPILE_ASSERT(sizeof(BlendColor) == 20, Sizeof_BlendColor_is_not_20); -COMPILE_ASSERT(offsetof(BlendColor, header) == 0, - OffsetOf_BlendColor_header_not_0); -COMPILE_ASSERT(offsetof(BlendColor, red) == 4, OffsetOf_BlendColor_red_not_4); -COMPILE_ASSERT(offsetof(BlendColor, green) == 8, - OffsetOf_BlendColor_green_not_8); -COMPILE_ASSERT(offsetof(BlendColor, blue) == 12, - OffsetOf_BlendColor_blue_not_12); -COMPILE_ASSERT(offsetof(BlendColor, alpha) == 16, - OffsetOf_BlendColor_alpha_not_16); +static_assert(sizeof(BlendColor) == 20, "size of BlendColor should be 20"); +static_assert(offsetof(BlendColor, header) == 0, + "offset of BlendColor header should be 0"); +static_assert(offsetof(BlendColor, red) == 4, + "offset of BlendColor red should be 4"); +static_assert(offsetof(BlendColor, green) == 8, + "offset of BlendColor green should be 8"); +static_assert(offsetof(BlendColor, blue) == 12, + "offset of BlendColor blue should be 12"); +static_assert(offsetof(BlendColor, alpha) == 16, + "offset of BlendColor alpha should be 16"); struct BlendEquation { typedef BlendEquation ValueType; @@ -341,11 +519,11 @@ struct BlendEquation { uint32_t mode; }; -COMPILE_ASSERT(sizeof(BlendEquation) == 8, Sizeof_BlendEquation_is_not_8); -COMPILE_ASSERT(offsetof(BlendEquation, header) == 0, - OffsetOf_BlendEquation_header_not_0); -COMPILE_ASSERT(offsetof(BlendEquation, mode) == 4, - OffsetOf_BlendEquation_mode_not_4); +static_assert(sizeof(BlendEquation) == 8, "size of BlendEquation should be 8"); +static_assert(offsetof(BlendEquation, header) == 0, + "offset of BlendEquation header should be 0"); +static_assert(offsetof(BlendEquation, mode) == 4, + "offset of BlendEquation mode should be 4"); struct BlendEquationSeparate { typedef BlendEquationSeparate ValueType; @@ -375,14 +553,14 @@ struct BlendEquationSeparate { uint32_t modeAlpha; }; -COMPILE_ASSERT(sizeof(BlendEquationSeparate) == 12, - Sizeof_BlendEquationSeparate_is_not_12); -COMPILE_ASSERT(offsetof(BlendEquationSeparate, header) == 0, - OffsetOf_BlendEquationSeparate_header_not_0); -COMPILE_ASSERT(offsetof(BlendEquationSeparate, modeRGB) == 4, - OffsetOf_BlendEquationSeparate_modeRGB_not_4); -COMPILE_ASSERT(offsetof(BlendEquationSeparate, modeAlpha) == 8, - OffsetOf_BlendEquationSeparate_modeAlpha_not_8); +static_assert(sizeof(BlendEquationSeparate) == 12, + "size of BlendEquationSeparate should be 12"); +static_assert(offsetof(BlendEquationSeparate, header) == 0, + "offset of BlendEquationSeparate header should be 0"); +static_assert(offsetof(BlendEquationSeparate, modeRGB) == 4, + "offset of BlendEquationSeparate modeRGB should be 4"); +static_assert(offsetof(BlendEquationSeparate, modeAlpha) == 8, + "offset of BlendEquationSeparate modeAlpha should be 8"); struct BlendFunc { typedef BlendFunc ValueType; @@ -412,13 +590,13 @@ struct BlendFunc { uint32_t dfactor; }; -COMPILE_ASSERT(sizeof(BlendFunc) == 12, Sizeof_BlendFunc_is_not_12); -COMPILE_ASSERT(offsetof(BlendFunc, header) == 0, - OffsetOf_BlendFunc_header_not_0); -COMPILE_ASSERT(offsetof(BlendFunc, sfactor) == 4, - OffsetOf_BlendFunc_sfactor_not_4); -COMPILE_ASSERT(offsetof(BlendFunc, dfactor) == 8, - OffsetOf_BlendFunc_dfactor_not_8); +static_assert(sizeof(BlendFunc) == 12, "size of BlendFunc should be 12"); +static_assert(offsetof(BlendFunc, header) == 0, + "offset of BlendFunc header should be 0"); +static_assert(offsetof(BlendFunc, sfactor) == 4, + "offset of BlendFunc sfactor should be 4"); +static_assert(offsetof(BlendFunc, dfactor) == 8, + "offset of BlendFunc dfactor should be 8"); struct BlendFuncSeparate { typedef BlendFuncSeparate ValueType; @@ -459,18 +637,18 @@ struct BlendFuncSeparate { uint32_t dstAlpha; }; -COMPILE_ASSERT(sizeof(BlendFuncSeparate) == 20, - Sizeof_BlendFuncSeparate_is_not_20); -COMPILE_ASSERT(offsetof(BlendFuncSeparate, header) == 0, - OffsetOf_BlendFuncSeparate_header_not_0); -COMPILE_ASSERT(offsetof(BlendFuncSeparate, srcRGB) == 4, - OffsetOf_BlendFuncSeparate_srcRGB_not_4); -COMPILE_ASSERT(offsetof(BlendFuncSeparate, dstRGB) == 8, - OffsetOf_BlendFuncSeparate_dstRGB_not_8); -COMPILE_ASSERT(offsetof(BlendFuncSeparate, srcAlpha) == 12, - OffsetOf_BlendFuncSeparate_srcAlpha_not_12); -COMPILE_ASSERT(offsetof(BlendFuncSeparate, dstAlpha) == 16, - OffsetOf_BlendFuncSeparate_dstAlpha_not_16); +static_assert(sizeof(BlendFuncSeparate) == 20, + "size of BlendFuncSeparate should be 20"); +static_assert(offsetof(BlendFuncSeparate, header) == 0, + "offset of BlendFuncSeparate header should be 0"); +static_assert(offsetof(BlendFuncSeparate, srcRGB) == 4, + "offset of BlendFuncSeparate srcRGB should be 4"); +static_assert(offsetof(BlendFuncSeparate, dstRGB) == 8, + "offset of BlendFuncSeparate dstRGB should be 8"); +static_assert(offsetof(BlendFuncSeparate, srcAlpha) == 12, + "offset of BlendFuncSeparate srcAlpha should be 12"); +static_assert(offsetof(BlendFuncSeparate, dstAlpha) == 16, + "offset of BlendFuncSeparate dstAlpha should be 16"); struct BufferData { typedef BufferData ValueType; @@ -516,18 +694,19 @@ struct BufferData { uint32_t usage; }; -COMPILE_ASSERT(sizeof(BufferData) == 24, Sizeof_BufferData_is_not_24); -COMPILE_ASSERT(offsetof(BufferData, header) == 0, - OffsetOf_BufferData_header_not_0); -COMPILE_ASSERT(offsetof(BufferData, target) == 4, - OffsetOf_BufferData_target_not_4); -COMPILE_ASSERT(offsetof(BufferData, size) == 8, OffsetOf_BufferData_size_not_8); -COMPILE_ASSERT(offsetof(BufferData, data_shm_id) == 12, - OffsetOf_BufferData_data_shm_id_not_12); -COMPILE_ASSERT(offsetof(BufferData, data_shm_offset) == 16, - OffsetOf_BufferData_data_shm_offset_not_16); -COMPILE_ASSERT(offsetof(BufferData, usage) == 20, - OffsetOf_BufferData_usage_not_20); +static_assert(sizeof(BufferData) == 24, "size of BufferData should be 24"); +static_assert(offsetof(BufferData, header) == 0, + "offset of BufferData header should be 0"); +static_assert(offsetof(BufferData, target) == 4, + "offset of BufferData target should be 4"); +static_assert(offsetof(BufferData, size) == 8, + "offset of BufferData size should be 8"); +static_assert(offsetof(BufferData, data_shm_id) == 12, + "offset of BufferData data_shm_id should be 12"); +static_assert(offsetof(BufferData, data_shm_offset) == 16, + "offset of BufferData data_shm_offset should be 16"); +static_assert(offsetof(BufferData, usage) == 20, + "offset of BufferData usage should be 20"); struct BufferSubData { typedef BufferSubData ValueType; @@ -573,19 +752,20 @@ struct BufferSubData { uint32_t data_shm_offset; }; -COMPILE_ASSERT(sizeof(BufferSubData) == 24, Sizeof_BufferSubData_is_not_24); -COMPILE_ASSERT(offsetof(BufferSubData, header) == 0, - OffsetOf_BufferSubData_header_not_0); -COMPILE_ASSERT(offsetof(BufferSubData, target) == 4, - OffsetOf_BufferSubData_target_not_4); -COMPILE_ASSERT(offsetof(BufferSubData, offset) == 8, - OffsetOf_BufferSubData_offset_not_8); -COMPILE_ASSERT(offsetof(BufferSubData, size) == 12, - OffsetOf_BufferSubData_size_not_12); -COMPILE_ASSERT(offsetof(BufferSubData, data_shm_id) == 16, - OffsetOf_BufferSubData_data_shm_id_not_16); -COMPILE_ASSERT(offsetof(BufferSubData, data_shm_offset) == 20, - OffsetOf_BufferSubData_data_shm_offset_not_20); +static_assert(sizeof(BufferSubData) == 24, + "size of BufferSubData should be 24"); +static_assert(offsetof(BufferSubData, header) == 0, + "offset of BufferSubData header should be 0"); +static_assert(offsetof(BufferSubData, target) == 4, + "offset of BufferSubData target should be 4"); +static_assert(offsetof(BufferSubData, offset) == 8, + "offset of BufferSubData offset should be 8"); +static_assert(offsetof(BufferSubData, size) == 12, + "offset of BufferSubData size should be 12"); +static_assert(offsetof(BufferSubData, data_shm_id) == 16, + "offset of BufferSubData data_shm_id should be 16"); +static_assert(offsetof(BufferSubData, data_shm_offset) == 20, + "offset of BufferSubData data_shm_offset should be 20"); struct CheckFramebufferStatus { typedef CheckFramebufferStatus ValueType; @@ -625,16 +805,17 @@ struct CheckFramebufferStatus { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(CheckFramebufferStatus) == 16, - Sizeof_CheckFramebufferStatus_is_not_16); -COMPILE_ASSERT(offsetof(CheckFramebufferStatus, header) == 0, - OffsetOf_CheckFramebufferStatus_header_not_0); -COMPILE_ASSERT(offsetof(CheckFramebufferStatus, target) == 4, - OffsetOf_CheckFramebufferStatus_target_not_4); -COMPILE_ASSERT(offsetof(CheckFramebufferStatus, result_shm_id) == 8, - OffsetOf_CheckFramebufferStatus_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(CheckFramebufferStatus, result_shm_offset) == 12, - OffsetOf_CheckFramebufferStatus_result_shm_offset_not_12); +static_assert(sizeof(CheckFramebufferStatus) == 16, + "size of CheckFramebufferStatus should be 16"); +static_assert(offsetof(CheckFramebufferStatus, header) == 0, + "offset of CheckFramebufferStatus header should be 0"); +static_assert(offsetof(CheckFramebufferStatus, target) == 4, + "offset of CheckFramebufferStatus target should be 4"); +static_assert(offsetof(CheckFramebufferStatus, result_shm_id) == 8, + "offset of CheckFramebufferStatus result_shm_id should be 8"); +static_assert( + offsetof(CheckFramebufferStatus, result_shm_offset) == 12, + "offset of CheckFramebufferStatus result_shm_offset should be 12"); struct Clear { typedef Clear ValueType; @@ -662,9 +843,220 @@ struct Clear { uint32_t mask; }; -COMPILE_ASSERT(sizeof(Clear) == 8, Sizeof_Clear_is_not_8); -COMPILE_ASSERT(offsetof(Clear, header) == 0, OffsetOf_Clear_header_not_0); -COMPILE_ASSERT(offsetof(Clear, mask) == 4, OffsetOf_Clear_mask_not_4); +static_assert(sizeof(Clear) == 8, "size of Clear should be 8"); +static_assert(offsetof(Clear, header) == 0, + "offset of Clear header should be 0"); +static_assert(offsetof(Clear, mask) == 4, "offset of Clear mask should be 4"); + +struct ClearBufferfi { + typedef ClearBufferfi ValueType; + static const CommandId kCmdId = kClearBufferfi; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _buffer, + GLint _drawbuffers, + GLfloat _depth, + GLint _stencil) { + SetHeader(); + buffer = _buffer; + drawbuffers = _drawbuffers; + depth = _depth; + stencil = _stencil; + } + + void* Set(void* cmd, + GLenum _buffer, + GLint _drawbuffers, + GLfloat _depth, + GLint _stencil) { + static_cast<ValueType*>(cmd)->Init(_buffer, _drawbuffers, _depth, _stencil); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t buffer; + int32_t drawbuffers; + float depth; + int32_t stencil; +}; + +static_assert(sizeof(ClearBufferfi) == 20, + "size of ClearBufferfi should be 20"); +static_assert(offsetof(ClearBufferfi, header) == 0, + "offset of ClearBufferfi header should be 0"); +static_assert(offsetof(ClearBufferfi, buffer) == 4, + "offset of ClearBufferfi buffer should be 4"); +static_assert(offsetof(ClearBufferfi, drawbuffers) == 8, + "offset of ClearBufferfi drawbuffers should be 8"); +static_assert(offsetof(ClearBufferfi, depth) == 12, + "offset of ClearBufferfi depth should be 12"); +static_assert(offsetof(ClearBufferfi, stencil) == 16, + "offset of ClearBufferfi stencil should be 16"); + +struct ClearBufferfvImmediate { + typedef ClearBufferfvImmediate ValueType; + static const CommandId kCmdId = kClearBufferfvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize() { + return static_cast<uint32_t>(sizeof(GLfloat) * 4); + } + + static uint32_t ComputeEffectiveDataSize(GLenum buffer) { + return static_cast<uint32_t>(sizeof(GLfloat) * + GLES2Util::CalcClearBufferfvDataCount(buffer)); + } + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); + } + + void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } + + void Init(GLenum _buffer, GLint _drawbuffers, const GLfloat* _value) { + SetHeader(); + buffer = _buffer; + drawbuffers = _drawbuffers; + memcpy(ImmediateDataAddress(this), _value, + ComputeEffectiveDataSize(buffer)); + DCHECK_GE(ComputeDataSize(), ComputeEffectiveDataSize(buffer)); + char* pointer = reinterpret_cast<char*>(ImmediateDataAddress(this)) + + ComputeEffectiveDataSize(buffer); + memset(pointer, 0, ComputeDataSize() - ComputeEffectiveDataSize(buffer)); + } + + void* Set(void* cmd, + GLenum _buffer, + GLint _drawbuffers, + const GLfloat* _value) { + static_cast<ValueType*>(cmd)->Init(_buffer, _drawbuffers, _value); + const uint32_t size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + uint32_t buffer; + int32_t drawbuffers; +}; + +static_assert(sizeof(ClearBufferfvImmediate) == 12, + "size of ClearBufferfvImmediate should be 12"); +static_assert(offsetof(ClearBufferfvImmediate, header) == 0, + "offset of ClearBufferfvImmediate header should be 0"); +static_assert(offsetof(ClearBufferfvImmediate, buffer) == 4, + "offset of ClearBufferfvImmediate buffer should be 4"); +static_assert(offsetof(ClearBufferfvImmediate, drawbuffers) == 8, + "offset of ClearBufferfvImmediate drawbuffers should be 8"); + +struct ClearBufferivImmediate { + typedef ClearBufferivImmediate ValueType; + static const CommandId kCmdId = kClearBufferivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize() { + return static_cast<uint32_t>(sizeof(GLint) * 4); + } + + static uint32_t ComputeEffectiveDataSize(GLenum buffer) { + return static_cast<uint32_t>(sizeof(GLint) * + GLES2Util::CalcClearBufferivDataCount(buffer)); + } + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); + } + + void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } + + void Init(GLenum _buffer, GLint _drawbuffers, const GLint* _value) { + SetHeader(); + buffer = _buffer; + drawbuffers = _drawbuffers; + memcpy(ImmediateDataAddress(this), _value, + ComputeEffectiveDataSize(buffer)); + DCHECK_GE(ComputeDataSize(), ComputeEffectiveDataSize(buffer)); + char* pointer = reinterpret_cast<char*>(ImmediateDataAddress(this)) + + ComputeEffectiveDataSize(buffer); + memset(pointer, 0, ComputeDataSize() - ComputeEffectiveDataSize(buffer)); + } + + void* Set(void* cmd, + GLenum _buffer, + GLint _drawbuffers, + const GLint* _value) { + static_cast<ValueType*>(cmd)->Init(_buffer, _drawbuffers, _value); + const uint32_t size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + uint32_t buffer; + int32_t drawbuffers; +}; + +static_assert(sizeof(ClearBufferivImmediate) == 12, + "size of ClearBufferivImmediate should be 12"); +static_assert(offsetof(ClearBufferivImmediate, header) == 0, + "offset of ClearBufferivImmediate header should be 0"); +static_assert(offsetof(ClearBufferivImmediate, buffer) == 4, + "offset of ClearBufferivImmediate buffer should be 4"); +static_assert(offsetof(ClearBufferivImmediate, drawbuffers) == 8, + "offset of ClearBufferivImmediate drawbuffers should be 8"); + +struct ClearBufferuivImmediate { + typedef ClearBufferuivImmediate ValueType; + static const CommandId kCmdId = kClearBufferuivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize() { + return static_cast<uint32_t>(sizeof(GLuint) * 4); + } + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); + } + + void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } + + void Init(GLenum _buffer, GLint _drawbuffers, const GLuint* _value) { + SetHeader(); + buffer = _buffer; + drawbuffers = _drawbuffers; + memcpy(ImmediateDataAddress(this), _value, ComputeDataSize()); + } + + void* Set(void* cmd, + GLenum _buffer, + GLint _drawbuffers, + const GLuint* _value) { + static_cast<ValueType*>(cmd)->Init(_buffer, _drawbuffers, _value); + const uint32_t size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + uint32_t buffer; + int32_t drawbuffers; +}; + +static_assert(sizeof(ClearBufferuivImmediate) == 12, + "size of ClearBufferuivImmediate should be 12"); +static_assert(offsetof(ClearBufferuivImmediate, header) == 0, + "offset of ClearBufferuivImmediate header should be 0"); +static_assert(offsetof(ClearBufferuivImmediate, buffer) == 4, + "offset of ClearBufferuivImmediate buffer should be 4"); +static_assert(offsetof(ClearBufferuivImmediate, drawbuffers) == 8, + "offset of ClearBufferuivImmediate drawbuffers should be 8"); struct ClearColor { typedef ClearColor ValueType; @@ -702,16 +1094,17 @@ struct ClearColor { float alpha; }; -COMPILE_ASSERT(sizeof(ClearColor) == 20, Sizeof_ClearColor_is_not_20); -COMPILE_ASSERT(offsetof(ClearColor, header) == 0, - OffsetOf_ClearColor_header_not_0); -COMPILE_ASSERT(offsetof(ClearColor, red) == 4, OffsetOf_ClearColor_red_not_4); -COMPILE_ASSERT(offsetof(ClearColor, green) == 8, - OffsetOf_ClearColor_green_not_8); -COMPILE_ASSERT(offsetof(ClearColor, blue) == 12, - OffsetOf_ClearColor_blue_not_12); -COMPILE_ASSERT(offsetof(ClearColor, alpha) == 16, - OffsetOf_ClearColor_alpha_not_16); +static_assert(sizeof(ClearColor) == 20, "size of ClearColor should be 20"); +static_assert(offsetof(ClearColor, header) == 0, + "offset of ClearColor header should be 0"); +static_assert(offsetof(ClearColor, red) == 4, + "offset of ClearColor red should be 4"); +static_assert(offsetof(ClearColor, green) == 8, + "offset of ClearColor green should be 8"); +static_assert(offsetof(ClearColor, blue) == 12, + "offset of ClearColor blue should be 12"); +static_assert(offsetof(ClearColor, alpha) == 16, + "offset of ClearColor alpha should be 16"); struct ClearDepthf { typedef ClearDepthf ValueType; @@ -739,11 +1132,11 @@ struct ClearDepthf { float depth; }; -COMPILE_ASSERT(sizeof(ClearDepthf) == 8, Sizeof_ClearDepthf_is_not_8); -COMPILE_ASSERT(offsetof(ClearDepthf, header) == 0, - OffsetOf_ClearDepthf_header_not_0); -COMPILE_ASSERT(offsetof(ClearDepthf, depth) == 4, - OffsetOf_ClearDepthf_depth_not_4); +static_assert(sizeof(ClearDepthf) == 8, "size of ClearDepthf should be 8"); +static_assert(offsetof(ClearDepthf, header) == 0, + "offset of ClearDepthf header should be 0"); +static_assert(offsetof(ClearDepthf, depth) == 4, + "offset of ClearDepthf depth should be 4"); struct ClearStencil { typedef ClearStencil ValueType; @@ -771,10 +1164,78 @@ struct ClearStencil { int32_t s; }; -COMPILE_ASSERT(sizeof(ClearStencil) == 8, Sizeof_ClearStencil_is_not_8); -COMPILE_ASSERT(offsetof(ClearStencil, header) == 0, - OffsetOf_ClearStencil_header_not_0); -COMPILE_ASSERT(offsetof(ClearStencil, s) == 4, OffsetOf_ClearStencil_s_not_4); +static_assert(sizeof(ClearStencil) == 8, "size of ClearStencil should be 8"); +static_assert(offsetof(ClearStencil, header) == 0, + "offset of ClearStencil header should be 0"); +static_assert(offsetof(ClearStencil, s) == 4, + "offset of ClearStencil s should be 4"); + +struct ClientWaitSync { + typedef ClientWaitSync ValueType; + static const CommandId kCmdId = kClientWaitSync; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef GLenum Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _sync, + GLbitfield _flags, + GLuint _timeout_0, + GLuint _timeout_1, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + SetHeader(); + sync = _sync; + flags = _flags; + timeout_0 = _timeout_0; + timeout_1 = _timeout_1; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set(void* cmd, + GLuint _sync, + GLbitfield _flags, + GLuint _timeout_0, + GLuint _timeout_1, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_sync, _flags, _timeout_0, _timeout_1, + _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t sync; + uint32_t flags; + uint32_t timeout_0; + uint32_t timeout_1; + uint32_t result_shm_id; + uint32_t result_shm_offset; +}; + +static_assert(sizeof(ClientWaitSync) == 28, + "size of ClientWaitSync should be 28"); +static_assert(offsetof(ClientWaitSync, header) == 0, + "offset of ClientWaitSync header should be 0"); +static_assert(offsetof(ClientWaitSync, sync) == 4, + "offset of ClientWaitSync sync should be 4"); +static_assert(offsetof(ClientWaitSync, flags) == 8, + "offset of ClientWaitSync flags should be 8"); +static_assert(offsetof(ClientWaitSync, timeout_0) == 12, + "offset of ClientWaitSync timeout_0 should be 12"); +static_assert(offsetof(ClientWaitSync, timeout_1) == 16, + "offset of ClientWaitSync timeout_1 should be 16"); +static_assert(offsetof(ClientWaitSync, result_shm_id) == 20, + "offset of ClientWaitSync result_shm_id should be 20"); +static_assert(offsetof(ClientWaitSync, result_shm_offset) == 24, + "offset of ClientWaitSync result_shm_offset should be 24"); struct ColorMask { typedef ColorMask ValueType; @@ -815,14 +1276,17 @@ struct ColorMask { uint32_t alpha; }; -COMPILE_ASSERT(sizeof(ColorMask) == 20, Sizeof_ColorMask_is_not_20); -COMPILE_ASSERT(offsetof(ColorMask, header) == 0, - OffsetOf_ColorMask_header_not_0); -COMPILE_ASSERT(offsetof(ColorMask, red) == 4, OffsetOf_ColorMask_red_not_4); -COMPILE_ASSERT(offsetof(ColorMask, green) == 8, OffsetOf_ColorMask_green_not_8); -COMPILE_ASSERT(offsetof(ColorMask, blue) == 12, OffsetOf_ColorMask_blue_not_12); -COMPILE_ASSERT(offsetof(ColorMask, alpha) == 16, - OffsetOf_ColorMask_alpha_not_16); +static_assert(sizeof(ColorMask) == 20, "size of ColorMask should be 20"); +static_assert(offsetof(ColorMask, header) == 0, + "offset of ColorMask header should be 0"); +static_assert(offsetof(ColorMask, red) == 4, + "offset of ColorMask red should be 4"); +static_assert(offsetof(ColorMask, green) == 8, + "offset of ColorMask green should be 8"); +static_assert(offsetof(ColorMask, blue) == 12, + "offset of ColorMask blue should be 12"); +static_assert(offsetof(ColorMask, alpha) == 16, + "offset of ColorMask alpha should be 16"); struct CompileShader { typedef CompileShader ValueType; @@ -850,11 +1314,11 @@ struct CompileShader { uint32_t shader; }; -COMPILE_ASSERT(sizeof(CompileShader) == 8, Sizeof_CompileShader_is_not_8); -COMPILE_ASSERT(offsetof(CompileShader, header) == 0, - OffsetOf_CompileShader_header_not_0); -COMPILE_ASSERT(offsetof(CompileShader, shader) == 4, - OffsetOf_CompileShader_shader_not_4); +static_assert(sizeof(CompileShader) == 8, "size of CompileShader should be 8"); +static_assert(offsetof(CompileShader, header) == 0, + "offset of CompileShader header should be 0"); +static_assert(offsetof(CompileShader, shader) == 4, + "offset of CompileShader shader should be 4"); struct CompressedTexImage2DBucket { typedef CompressedTexImage2DBucket ValueType; @@ -905,22 +1369,23 @@ struct CompressedTexImage2DBucket { static const int32_t border = 0; }; -COMPILE_ASSERT(sizeof(CompressedTexImage2DBucket) == 28, - Sizeof_CompressedTexImage2DBucket_is_not_28); -COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, header) == 0, - OffsetOf_CompressedTexImage2DBucket_header_not_0); -COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, target) == 4, - OffsetOf_CompressedTexImage2DBucket_target_not_4); -COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, level) == 8, - OffsetOf_CompressedTexImage2DBucket_level_not_8); -COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, internalformat) == 12, - OffsetOf_CompressedTexImage2DBucket_internalformat_not_12); -COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, width) == 16, - OffsetOf_CompressedTexImage2DBucket_width_not_16); -COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, height) == 20, - OffsetOf_CompressedTexImage2DBucket_height_not_20); -COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, bucket_id) == 24, - OffsetOf_CompressedTexImage2DBucket_bucket_id_not_24); +static_assert(sizeof(CompressedTexImage2DBucket) == 28, + "size of CompressedTexImage2DBucket should be 28"); +static_assert(offsetof(CompressedTexImage2DBucket, header) == 0, + "offset of CompressedTexImage2DBucket header should be 0"); +static_assert(offsetof(CompressedTexImage2DBucket, target) == 4, + "offset of CompressedTexImage2DBucket target should be 4"); +static_assert(offsetof(CompressedTexImage2DBucket, level) == 8, + "offset of CompressedTexImage2DBucket level should be 8"); +static_assert( + offsetof(CompressedTexImage2DBucket, internalformat) == 12, + "offset of CompressedTexImage2DBucket internalformat should be 12"); +static_assert(offsetof(CompressedTexImage2DBucket, width) == 16, + "offset of CompressedTexImage2DBucket width should be 16"); +static_assert(offsetof(CompressedTexImage2DBucket, height) == 20, + "offset of CompressedTexImage2DBucket height should be 20"); +static_assert(offsetof(CompressedTexImage2DBucket, bucket_id) == 24, + "offset of CompressedTexImage2DBucket bucket_id should be 24"); struct CompressedTexImage2D { typedef CompressedTexImage2D ValueType; @@ -980,26 +1445,26 @@ struct CompressedTexImage2D { static const int32_t border = 0; }; -COMPILE_ASSERT(sizeof(CompressedTexImage2D) == 36, - Sizeof_CompressedTexImage2D_is_not_36); -COMPILE_ASSERT(offsetof(CompressedTexImage2D, header) == 0, - OffsetOf_CompressedTexImage2D_header_not_0); -COMPILE_ASSERT(offsetof(CompressedTexImage2D, target) == 4, - OffsetOf_CompressedTexImage2D_target_not_4); -COMPILE_ASSERT(offsetof(CompressedTexImage2D, level) == 8, - OffsetOf_CompressedTexImage2D_level_not_8); -COMPILE_ASSERT(offsetof(CompressedTexImage2D, internalformat) == 12, - OffsetOf_CompressedTexImage2D_internalformat_not_12); -COMPILE_ASSERT(offsetof(CompressedTexImage2D, width) == 16, - OffsetOf_CompressedTexImage2D_width_not_16); -COMPILE_ASSERT(offsetof(CompressedTexImage2D, height) == 20, - OffsetOf_CompressedTexImage2D_height_not_20); -COMPILE_ASSERT(offsetof(CompressedTexImage2D, imageSize) == 24, - OffsetOf_CompressedTexImage2D_imageSize_not_24); -COMPILE_ASSERT(offsetof(CompressedTexImage2D, data_shm_id) == 28, - OffsetOf_CompressedTexImage2D_data_shm_id_not_28); -COMPILE_ASSERT(offsetof(CompressedTexImage2D, data_shm_offset) == 32, - OffsetOf_CompressedTexImage2D_data_shm_offset_not_32); +static_assert(sizeof(CompressedTexImage2D) == 36, + "size of CompressedTexImage2D should be 36"); +static_assert(offsetof(CompressedTexImage2D, header) == 0, + "offset of CompressedTexImage2D header should be 0"); +static_assert(offsetof(CompressedTexImage2D, target) == 4, + "offset of CompressedTexImage2D target should be 4"); +static_assert(offsetof(CompressedTexImage2D, level) == 8, + "offset of CompressedTexImage2D level should be 8"); +static_assert(offsetof(CompressedTexImage2D, internalformat) == 12, + "offset of CompressedTexImage2D internalformat should be 12"); +static_assert(offsetof(CompressedTexImage2D, width) == 16, + "offset of CompressedTexImage2D width should be 16"); +static_assert(offsetof(CompressedTexImage2D, height) == 20, + "offset of CompressedTexImage2D height should be 20"); +static_assert(offsetof(CompressedTexImage2D, imageSize) == 24, + "offset of CompressedTexImage2D imageSize should be 24"); +static_assert(offsetof(CompressedTexImage2D, data_shm_id) == 28, + "offset of CompressedTexImage2D data_shm_id should be 28"); +static_assert(offsetof(CompressedTexImage2D, data_shm_offset) == 32, + "offset of CompressedTexImage2D data_shm_offset should be 32"); struct CompressedTexSubImage2DBucket { typedef CompressedTexSubImage2DBucket ValueType; @@ -1057,26 +1522,26 @@ struct CompressedTexSubImage2DBucket { uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(CompressedTexSubImage2DBucket) == 36, - Sizeof_CompressedTexSubImage2DBucket_is_not_36); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, header) == 0, - OffsetOf_CompressedTexSubImage2DBucket_header_not_0); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, target) == 4, - OffsetOf_CompressedTexSubImage2DBucket_target_not_4); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, level) == 8, - OffsetOf_CompressedTexSubImage2DBucket_level_not_8); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, xoffset) == 12, - OffsetOf_CompressedTexSubImage2DBucket_xoffset_not_12); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, yoffset) == 16, - OffsetOf_CompressedTexSubImage2DBucket_yoffset_not_16); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, width) == 20, - OffsetOf_CompressedTexSubImage2DBucket_width_not_20); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, height) == 24, - OffsetOf_CompressedTexSubImage2DBucket_height_not_24); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, format) == 28, - OffsetOf_CompressedTexSubImage2DBucket_format_not_28); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, bucket_id) == 32, - OffsetOf_CompressedTexSubImage2DBucket_bucket_id_not_32); +static_assert(sizeof(CompressedTexSubImage2DBucket) == 36, + "size of CompressedTexSubImage2DBucket should be 36"); +static_assert(offsetof(CompressedTexSubImage2DBucket, header) == 0, + "offset of CompressedTexSubImage2DBucket header should be 0"); +static_assert(offsetof(CompressedTexSubImage2DBucket, target) == 4, + "offset of CompressedTexSubImage2DBucket target should be 4"); +static_assert(offsetof(CompressedTexSubImage2DBucket, level) == 8, + "offset of CompressedTexSubImage2DBucket level should be 8"); +static_assert(offsetof(CompressedTexSubImage2DBucket, xoffset) == 12, + "offset of CompressedTexSubImage2DBucket xoffset should be 12"); +static_assert(offsetof(CompressedTexSubImage2DBucket, yoffset) == 16, + "offset of CompressedTexSubImage2DBucket yoffset should be 16"); +static_assert(offsetof(CompressedTexSubImage2DBucket, width) == 20, + "offset of CompressedTexSubImage2DBucket width should be 20"); +static_assert(offsetof(CompressedTexSubImage2DBucket, height) == 24, + "offset of CompressedTexSubImage2DBucket height should be 24"); +static_assert(offsetof(CompressedTexSubImage2DBucket, format) == 28, + "offset of CompressedTexSubImage2DBucket format should be 28"); +static_assert(offsetof(CompressedTexSubImage2DBucket, bucket_id) == 32, + "offset of CompressedTexSubImage2DBucket bucket_id should be 32"); struct CompressedTexSubImage2D { typedef CompressedTexSubImage2D ValueType; @@ -1143,30 +1608,439 @@ struct CompressedTexSubImage2D { uint32_t data_shm_offset; }; -COMPILE_ASSERT(sizeof(CompressedTexSubImage2D) == 44, - Sizeof_CompressedTexSubImage2D_is_not_44); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, header) == 0, - OffsetOf_CompressedTexSubImage2D_header_not_0); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, target) == 4, - OffsetOf_CompressedTexSubImage2D_target_not_4); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, level) == 8, - OffsetOf_CompressedTexSubImage2D_level_not_8); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, xoffset) == 12, - OffsetOf_CompressedTexSubImage2D_xoffset_not_12); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, yoffset) == 16, - OffsetOf_CompressedTexSubImage2D_yoffset_not_16); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, width) == 20, - OffsetOf_CompressedTexSubImage2D_width_not_20); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, height) == 24, - OffsetOf_CompressedTexSubImage2D_height_not_24); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, format) == 28, - OffsetOf_CompressedTexSubImage2D_format_not_28); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, imageSize) == 32, - OffsetOf_CompressedTexSubImage2D_imageSize_not_32); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, data_shm_id) == 36, - OffsetOf_CompressedTexSubImage2D_data_shm_id_not_36); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, data_shm_offset) == 40, - OffsetOf_CompressedTexSubImage2D_data_shm_offset_not_40); +static_assert(sizeof(CompressedTexSubImage2D) == 44, + "size of CompressedTexSubImage2D should be 44"); +static_assert(offsetof(CompressedTexSubImage2D, header) == 0, + "offset of CompressedTexSubImage2D header should be 0"); +static_assert(offsetof(CompressedTexSubImage2D, target) == 4, + "offset of CompressedTexSubImage2D target should be 4"); +static_assert(offsetof(CompressedTexSubImage2D, level) == 8, + "offset of CompressedTexSubImage2D level should be 8"); +static_assert(offsetof(CompressedTexSubImage2D, xoffset) == 12, + "offset of CompressedTexSubImage2D xoffset should be 12"); +static_assert(offsetof(CompressedTexSubImage2D, yoffset) == 16, + "offset of CompressedTexSubImage2D yoffset should be 16"); +static_assert(offsetof(CompressedTexSubImage2D, width) == 20, + "offset of CompressedTexSubImage2D width should be 20"); +static_assert(offsetof(CompressedTexSubImage2D, height) == 24, + "offset of CompressedTexSubImage2D height should be 24"); +static_assert(offsetof(CompressedTexSubImage2D, format) == 28, + "offset of CompressedTexSubImage2D format should be 28"); +static_assert(offsetof(CompressedTexSubImage2D, imageSize) == 32, + "offset of CompressedTexSubImage2D imageSize should be 32"); +static_assert(offsetof(CompressedTexSubImage2D, data_shm_id) == 36, + "offset of CompressedTexSubImage2D data_shm_id should be 36"); +static_assert(offsetof(CompressedTexSubImage2D, data_shm_offset) == 40, + "offset of CompressedTexSubImage2D data_shm_offset should be 40"); + +struct CompressedTexImage3DBucket { + typedef CompressedTexImage3DBucket ValueType; + static const CommandId kCmdId = kCompressedTexImage3DBucket; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLint _level, + GLenum _internalformat, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLuint _bucket_id) { + SetHeader(); + target = _target; + level = _level; + internalformat = _internalformat; + width = _width; + height = _height; + depth = _depth; + bucket_id = _bucket_id; + } + + void* Set(void* cmd, + GLenum _target, + GLint _level, + GLenum _internalformat, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLuint _bucket_id) { + static_cast<ValueType*>(cmd)->Init(_target, _level, _internalformat, _width, + _height, _depth, _bucket_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t level; + uint32_t internalformat; + int32_t width; + int32_t height; + int32_t depth; + uint32_t bucket_id; + static const int32_t border = 0; +}; + +static_assert(sizeof(CompressedTexImage3DBucket) == 32, + "size of CompressedTexImage3DBucket should be 32"); +static_assert(offsetof(CompressedTexImage3DBucket, header) == 0, + "offset of CompressedTexImage3DBucket header should be 0"); +static_assert(offsetof(CompressedTexImage3DBucket, target) == 4, + "offset of CompressedTexImage3DBucket target should be 4"); +static_assert(offsetof(CompressedTexImage3DBucket, level) == 8, + "offset of CompressedTexImage3DBucket level should be 8"); +static_assert( + offsetof(CompressedTexImage3DBucket, internalformat) == 12, + "offset of CompressedTexImage3DBucket internalformat should be 12"); +static_assert(offsetof(CompressedTexImage3DBucket, width) == 16, + "offset of CompressedTexImage3DBucket width should be 16"); +static_assert(offsetof(CompressedTexImage3DBucket, height) == 20, + "offset of CompressedTexImage3DBucket height should be 20"); +static_assert(offsetof(CompressedTexImage3DBucket, depth) == 24, + "offset of CompressedTexImage3DBucket depth should be 24"); +static_assert(offsetof(CompressedTexImage3DBucket, bucket_id) == 28, + "offset of CompressedTexImage3DBucket bucket_id should be 28"); + +struct CompressedTexImage3D { + typedef CompressedTexImage3D ValueType; + static const CommandId kCmdId = kCompressedTexImage3D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLint _level, + GLenum _internalformat, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLsizei _imageSize, + uint32_t _data_shm_id, + uint32_t _data_shm_offset) { + SetHeader(); + target = _target; + level = _level; + internalformat = _internalformat; + width = _width; + height = _height; + depth = _depth; + imageSize = _imageSize; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + } + + void* Set(void* cmd, + GLenum _target, + GLint _level, + GLenum _internalformat, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLsizei _imageSize, + uint32_t _data_shm_id, + uint32_t _data_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_target, _level, _internalformat, _width, + _height, _depth, _imageSize, + _data_shm_id, _data_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t level; + uint32_t internalformat; + int32_t width; + int32_t height; + int32_t depth; + int32_t imageSize; + uint32_t data_shm_id; + uint32_t data_shm_offset; + static const int32_t border = 0; +}; + +static_assert(sizeof(CompressedTexImage3D) == 40, + "size of CompressedTexImage3D should be 40"); +static_assert(offsetof(CompressedTexImage3D, header) == 0, + "offset of CompressedTexImage3D header should be 0"); +static_assert(offsetof(CompressedTexImage3D, target) == 4, + "offset of CompressedTexImage3D target should be 4"); +static_assert(offsetof(CompressedTexImage3D, level) == 8, + "offset of CompressedTexImage3D level should be 8"); +static_assert(offsetof(CompressedTexImage3D, internalformat) == 12, + "offset of CompressedTexImage3D internalformat should be 12"); +static_assert(offsetof(CompressedTexImage3D, width) == 16, + "offset of CompressedTexImage3D width should be 16"); +static_assert(offsetof(CompressedTexImage3D, height) == 20, + "offset of CompressedTexImage3D height should be 20"); +static_assert(offsetof(CompressedTexImage3D, depth) == 24, + "offset of CompressedTexImage3D depth should be 24"); +static_assert(offsetof(CompressedTexImage3D, imageSize) == 28, + "offset of CompressedTexImage3D imageSize should be 28"); +static_assert(offsetof(CompressedTexImage3D, data_shm_id) == 32, + "offset of CompressedTexImage3D data_shm_id should be 32"); +static_assert(offsetof(CompressedTexImage3D, data_shm_offset) == 36, + "offset of CompressedTexImage3D data_shm_offset should be 36"); + +struct CompressedTexSubImage3DBucket { + typedef CompressedTexSubImage3DBucket ValueType; + static const CommandId kCmdId = kCompressedTexSubImage3DBucket; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLint _level, + GLint _xoffset, + GLint _yoffset, + GLint _zoffset, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLenum _format, + GLuint _bucket_id) { + SetHeader(); + target = _target; + level = _level; + xoffset = _xoffset; + yoffset = _yoffset; + zoffset = _zoffset; + width = _width; + height = _height; + depth = _depth; + format = _format; + bucket_id = _bucket_id; + } + + void* Set(void* cmd, + GLenum _target, + GLint _level, + GLint _xoffset, + GLint _yoffset, + GLint _zoffset, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLenum _format, + GLuint _bucket_id) { + static_cast<ValueType*>(cmd)->Init(_target, _level, _xoffset, _yoffset, + _zoffset, _width, _height, _depth, + _format, _bucket_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t level; + int32_t xoffset; + int32_t yoffset; + int32_t zoffset; + int32_t width; + int32_t height; + int32_t depth; + uint32_t format; + uint32_t bucket_id; +}; + +static_assert(sizeof(CompressedTexSubImage3DBucket) == 44, + "size of CompressedTexSubImage3DBucket should be 44"); +static_assert(offsetof(CompressedTexSubImage3DBucket, header) == 0, + "offset of CompressedTexSubImage3DBucket header should be 0"); +static_assert(offsetof(CompressedTexSubImage3DBucket, target) == 4, + "offset of CompressedTexSubImage3DBucket target should be 4"); +static_assert(offsetof(CompressedTexSubImage3DBucket, level) == 8, + "offset of CompressedTexSubImage3DBucket level should be 8"); +static_assert(offsetof(CompressedTexSubImage3DBucket, xoffset) == 12, + "offset of CompressedTexSubImage3DBucket xoffset should be 12"); +static_assert(offsetof(CompressedTexSubImage3DBucket, yoffset) == 16, + "offset of CompressedTexSubImage3DBucket yoffset should be 16"); +static_assert(offsetof(CompressedTexSubImage3DBucket, zoffset) == 20, + "offset of CompressedTexSubImage3DBucket zoffset should be 20"); +static_assert(offsetof(CompressedTexSubImage3DBucket, width) == 24, + "offset of CompressedTexSubImage3DBucket width should be 24"); +static_assert(offsetof(CompressedTexSubImage3DBucket, height) == 28, + "offset of CompressedTexSubImage3DBucket height should be 28"); +static_assert(offsetof(CompressedTexSubImage3DBucket, depth) == 32, + "offset of CompressedTexSubImage3DBucket depth should be 32"); +static_assert(offsetof(CompressedTexSubImage3DBucket, format) == 36, + "offset of CompressedTexSubImage3DBucket format should be 36"); +static_assert(offsetof(CompressedTexSubImage3DBucket, bucket_id) == 40, + "offset of CompressedTexSubImage3DBucket bucket_id should be 40"); + +struct CompressedTexSubImage3D { + typedef CompressedTexSubImage3D ValueType; + static const CommandId kCmdId = kCompressedTexSubImage3D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLint _level, + GLint _xoffset, + GLint _yoffset, + GLint _zoffset, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLenum _format, + GLsizei _imageSize, + uint32_t _data_shm_id, + uint32_t _data_shm_offset) { + SetHeader(); + target = _target; + level = _level; + xoffset = _xoffset; + yoffset = _yoffset; + zoffset = _zoffset; + width = _width; + height = _height; + depth = _depth; + format = _format; + imageSize = _imageSize; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + } + + void* Set(void* cmd, + GLenum _target, + GLint _level, + GLint _xoffset, + GLint _yoffset, + GLint _zoffset, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLenum _format, + GLsizei _imageSize, + uint32_t _data_shm_id, + uint32_t _data_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_target, _level, _xoffset, _yoffset, _zoffset, _width, _height, + _depth, _format, _imageSize, _data_shm_id, _data_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t level; + int32_t xoffset; + int32_t yoffset; + int32_t zoffset; + int32_t width; + int32_t height; + int32_t depth; + uint32_t format; + int32_t imageSize; + uint32_t data_shm_id; + uint32_t data_shm_offset; +}; + +static_assert(sizeof(CompressedTexSubImage3D) == 52, + "size of CompressedTexSubImage3D should be 52"); +static_assert(offsetof(CompressedTexSubImage3D, header) == 0, + "offset of CompressedTexSubImage3D header should be 0"); +static_assert(offsetof(CompressedTexSubImage3D, target) == 4, + "offset of CompressedTexSubImage3D target should be 4"); +static_assert(offsetof(CompressedTexSubImage3D, level) == 8, + "offset of CompressedTexSubImage3D level should be 8"); +static_assert(offsetof(CompressedTexSubImage3D, xoffset) == 12, + "offset of CompressedTexSubImage3D xoffset should be 12"); +static_assert(offsetof(CompressedTexSubImage3D, yoffset) == 16, + "offset of CompressedTexSubImage3D yoffset should be 16"); +static_assert(offsetof(CompressedTexSubImage3D, zoffset) == 20, + "offset of CompressedTexSubImage3D zoffset should be 20"); +static_assert(offsetof(CompressedTexSubImage3D, width) == 24, + "offset of CompressedTexSubImage3D width should be 24"); +static_assert(offsetof(CompressedTexSubImage3D, height) == 28, + "offset of CompressedTexSubImage3D height should be 28"); +static_assert(offsetof(CompressedTexSubImage3D, depth) == 32, + "offset of CompressedTexSubImage3D depth should be 32"); +static_assert(offsetof(CompressedTexSubImage3D, format) == 36, + "offset of CompressedTexSubImage3D format should be 36"); +static_assert(offsetof(CompressedTexSubImage3D, imageSize) == 40, + "offset of CompressedTexSubImage3D imageSize should be 40"); +static_assert(offsetof(CompressedTexSubImage3D, data_shm_id) == 44, + "offset of CompressedTexSubImage3D data_shm_id should be 44"); +static_assert(offsetof(CompressedTexSubImage3D, data_shm_offset) == 48, + "offset of CompressedTexSubImage3D data_shm_offset should be 48"); + +struct CopyBufferSubData { + typedef CopyBufferSubData ValueType; + static const CommandId kCmdId = kCopyBufferSubData; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _readtarget, + GLenum _writetarget, + GLintptr _readoffset, + GLintptr _writeoffset, + GLsizeiptr _size) { + SetHeader(); + readtarget = _readtarget; + writetarget = _writetarget; + readoffset = _readoffset; + writeoffset = _writeoffset; + size = _size; + } + + void* Set(void* cmd, + GLenum _readtarget, + GLenum _writetarget, + GLintptr _readoffset, + GLintptr _writeoffset, + GLsizeiptr _size) { + static_cast<ValueType*>(cmd) + ->Init(_readtarget, _writetarget, _readoffset, _writeoffset, _size); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t readtarget; + uint32_t writetarget; + int32_t readoffset; + int32_t writeoffset; + int32_t size; +}; + +static_assert(sizeof(CopyBufferSubData) == 24, + "size of CopyBufferSubData should be 24"); +static_assert(offsetof(CopyBufferSubData, header) == 0, + "offset of CopyBufferSubData header should be 0"); +static_assert(offsetof(CopyBufferSubData, readtarget) == 4, + "offset of CopyBufferSubData readtarget should be 4"); +static_assert(offsetof(CopyBufferSubData, writetarget) == 8, + "offset of CopyBufferSubData writetarget should be 8"); +static_assert(offsetof(CopyBufferSubData, readoffset) == 12, + "offset of CopyBufferSubData readoffset should be 12"); +static_assert(offsetof(CopyBufferSubData, writeoffset) == 16, + "offset of CopyBufferSubData writeoffset should be 16"); +static_assert(offsetof(CopyBufferSubData, size) == 20, + "offset of CopyBufferSubData size should be 20"); struct CopyTexImage2D { typedef CopyTexImage2D ValueType; @@ -1221,23 +2095,24 @@ struct CopyTexImage2D { static const int32_t border = 0; }; -COMPILE_ASSERT(sizeof(CopyTexImage2D) == 32, Sizeof_CopyTexImage2D_is_not_32); -COMPILE_ASSERT(offsetof(CopyTexImage2D, header) == 0, - OffsetOf_CopyTexImage2D_header_not_0); -COMPILE_ASSERT(offsetof(CopyTexImage2D, target) == 4, - OffsetOf_CopyTexImage2D_target_not_4); -COMPILE_ASSERT(offsetof(CopyTexImage2D, level) == 8, - OffsetOf_CopyTexImage2D_level_not_8); -COMPILE_ASSERT(offsetof(CopyTexImage2D, internalformat) == 12, - OffsetOf_CopyTexImage2D_internalformat_not_12); -COMPILE_ASSERT(offsetof(CopyTexImage2D, x) == 16, - OffsetOf_CopyTexImage2D_x_not_16); -COMPILE_ASSERT(offsetof(CopyTexImage2D, y) == 20, - OffsetOf_CopyTexImage2D_y_not_20); -COMPILE_ASSERT(offsetof(CopyTexImage2D, width) == 24, - OffsetOf_CopyTexImage2D_width_not_24); -COMPILE_ASSERT(offsetof(CopyTexImage2D, height) == 28, - OffsetOf_CopyTexImage2D_height_not_28); +static_assert(sizeof(CopyTexImage2D) == 32, + "size of CopyTexImage2D should be 32"); +static_assert(offsetof(CopyTexImage2D, header) == 0, + "offset of CopyTexImage2D header should be 0"); +static_assert(offsetof(CopyTexImage2D, target) == 4, + "offset of CopyTexImage2D target should be 4"); +static_assert(offsetof(CopyTexImage2D, level) == 8, + "offset of CopyTexImage2D level should be 8"); +static_assert(offsetof(CopyTexImage2D, internalformat) == 12, + "offset of CopyTexImage2D internalformat should be 12"); +static_assert(offsetof(CopyTexImage2D, x) == 16, + "offset of CopyTexImage2D x should be 16"); +static_assert(offsetof(CopyTexImage2D, y) == 20, + "offset of CopyTexImage2D y should be 20"); +static_assert(offsetof(CopyTexImage2D, width) == 24, + "offset of CopyTexImage2D width should be 24"); +static_assert(offsetof(CopyTexImage2D, height) == 28, + "offset of CopyTexImage2D height should be 28"); struct CopyTexSubImage2D { typedef CopyTexSubImage2D ValueType; @@ -1295,26 +2170,109 @@ struct CopyTexSubImage2D { int32_t height; }; -COMPILE_ASSERT(sizeof(CopyTexSubImage2D) == 36, - Sizeof_CopyTexSubImage2D_is_not_36); -COMPILE_ASSERT(offsetof(CopyTexSubImage2D, header) == 0, - OffsetOf_CopyTexSubImage2D_header_not_0); -COMPILE_ASSERT(offsetof(CopyTexSubImage2D, target) == 4, - OffsetOf_CopyTexSubImage2D_target_not_4); -COMPILE_ASSERT(offsetof(CopyTexSubImage2D, level) == 8, - OffsetOf_CopyTexSubImage2D_level_not_8); -COMPILE_ASSERT(offsetof(CopyTexSubImage2D, xoffset) == 12, - OffsetOf_CopyTexSubImage2D_xoffset_not_12); -COMPILE_ASSERT(offsetof(CopyTexSubImage2D, yoffset) == 16, - OffsetOf_CopyTexSubImage2D_yoffset_not_16); -COMPILE_ASSERT(offsetof(CopyTexSubImage2D, x) == 20, - OffsetOf_CopyTexSubImage2D_x_not_20); -COMPILE_ASSERT(offsetof(CopyTexSubImage2D, y) == 24, - OffsetOf_CopyTexSubImage2D_y_not_24); -COMPILE_ASSERT(offsetof(CopyTexSubImage2D, width) == 28, - OffsetOf_CopyTexSubImage2D_width_not_28); -COMPILE_ASSERT(offsetof(CopyTexSubImage2D, height) == 32, - OffsetOf_CopyTexSubImage2D_height_not_32); +static_assert(sizeof(CopyTexSubImage2D) == 36, + "size of CopyTexSubImage2D should be 36"); +static_assert(offsetof(CopyTexSubImage2D, header) == 0, + "offset of CopyTexSubImage2D header should be 0"); +static_assert(offsetof(CopyTexSubImage2D, target) == 4, + "offset of CopyTexSubImage2D target should be 4"); +static_assert(offsetof(CopyTexSubImage2D, level) == 8, + "offset of CopyTexSubImage2D level should be 8"); +static_assert(offsetof(CopyTexSubImage2D, xoffset) == 12, + "offset of CopyTexSubImage2D xoffset should be 12"); +static_assert(offsetof(CopyTexSubImage2D, yoffset) == 16, + "offset of CopyTexSubImage2D yoffset should be 16"); +static_assert(offsetof(CopyTexSubImage2D, x) == 20, + "offset of CopyTexSubImage2D x should be 20"); +static_assert(offsetof(CopyTexSubImage2D, y) == 24, + "offset of CopyTexSubImage2D y should be 24"); +static_assert(offsetof(CopyTexSubImage2D, width) == 28, + "offset of CopyTexSubImage2D width should be 28"); +static_assert(offsetof(CopyTexSubImage2D, height) == 32, + "offset of CopyTexSubImage2D height should be 32"); + +struct CopyTexSubImage3D { + typedef CopyTexSubImage3D ValueType; + static const CommandId kCmdId = kCopyTexSubImage3D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLint _level, + GLint _xoffset, + GLint _yoffset, + GLint _zoffset, + GLint _x, + GLint _y, + GLsizei _width, + GLsizei _height) { + SetHeader(); + target = _target; + level = _level; + xoffset = _xoffset; + yoffset = _yoffset; + zoffset = _zoffset; + x = _x; + y = _y; + width = _width; + height = _height; + } + + void* Set(void* cmd, + GLenum _target, + GLint _level, + GLint _xoffset, + GLint _yoffset, + GLint _zoffset, + GLint _x, + GLint _y, + GLsizei _width, + GLsizei _height) { + static_cast<ValueType*>(cmd)->Init(_target, _level, _xoffset, _yoffset, + _zoffset, _x, _y, _width, _height); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t level; + int32_t xoffset; + int32_t yoffset; + int32_t zoffset; + int32_t x; + int32_t y; + int32_t width; + int32_t height; +}; + +static_assert(sizeof(CopyTexSubImage3D) == 40, + "size of CopyTexSubImage3D should be 40"); +static_assert(offsetof(CopyTexSubImage3D, header) == 0, + "offset of CopyTexSubImage3D header should be 0"); +static_assert(offsetof(CopyTexSubImage3D, target) == 4, + "offset of CopyTexSubImage3D target should be 4"); +static_assert(offsetof(CopyTexSubImage3D, level) == 8, + "offset of CopyTexSubImage3D level should be 8"); +static_assert(offsetof(CopyTexSubImage3D, xoffset) == 12, + "offset of CopyTexSubImage3D xoffset should be 12"); +static_assert(offsetof(CopyTexSubImage3D, yoffset) == 16, + "offset of CopyTexSubImage3D yoffset should be 16"); +static_assert(offsetof(CopyTexSubImage3D, zoffset) == 20, + "offset of CopyTexSubImage3D zoffset should be 20"); +static_assert(offsetof(CopyTexSubImage3D, x) == 24, + "offset of CopyTexSubImage3D x should be 24"); +static_assert(offsetof(CopyTexSubImage3D, y) == 28, + "offset of CopyTexSubImage3D y should be 28"); +static_assert(offsetof(CopyTexSubImage3D, width) == 32, + "offset of CopyTexSubImage3D width should be 32"); +static_assert(offsetof(CopyTexSubImage3D, height) == 36, + "offset of CopyTexSubImage3D height should be 36"); struct CreateProgram { typedef CreateProgram ValueType; @@ -1342,11 +2300,11 @@ struct CreateProgram { uint32_t client_id; }; -COMPILE_ASSERT(sizeof(CreateProgram) == 8, Sizeof_CreateProgram_is_not_8); -COMPILE_ASSERT(offsetof(CreateProgram, header) == 0, - OffsetOf_CreateProgram_header_not_0); -COMPILE_ASSERT(offsetof(CreateProgram, client_id) == 4, - OffsetOf_CreateProgram_client_id_not_4); +static_assert(sizeof(CreateProgram) == 8, "size of CreateProgram should be 8"); +static_assert(offsetof(CreateProgram, header) == 0, + "offset of CreateProgram header should be 0"); +static_assert(offsetof(CreateProgram, client_id) == 4, + "offset of CreateProgram client_id should be 4"); struct CreateShader { typedef CreateShader ValueType; @@ -1376,13 +2334,13 @@ struct CreateShader { uint32_t client_id; }; -COMPILE_ASSERT(sizeof(CreateShader) == 12, Sizeof_CreateShader_is_not_12); -COMPILE_ASSERT(offsetof(CreateShader, header) == 0, - OffsetOf_CreateShader_header_not_0); -COMPILE_ASSERT(offsetof(CreateShader, type) == 4, - OffsetOf_CreateShader_type_not_4); -COMPILE_ASSERT(offsetof(CreateShader, client_id) == 8, - OffsetOf_CreateShader_client_id_not_8); +static_assert(sizeof(CreateShader) == 12, "size of CreateShader should be 12"); +static_assert(offsetof(CreateShader, header) == 0, + "offset of CreateShader header should be 0"); +static_assert(offsetof(CreateShader, type) == 4, + "offset of CreateShader type should be 4"); +static_assert(offsetof(CreateShader, client_id) == 8, + "offset of CreateShader client_id should be 8"); struct CullFace { typedef CullFace ValueType; @@ -1410,9 +2368,11 @@ struct CullFace { uint32_t mode; }; -COMPILE_ASSERT(sizeof(CullFace) == 8, Sizeof_CullFace_is_not_8); -COMPILE_ASSERT(offsetof(CullFace, header) == 0, OffsetOf_CullFace_header_not_0); -COMPILE_ASSERT(offsetof(CullFace, mode) == 4, OffsetOf_CullFace_mode_not_4); +static_assert(sizeof(CullFace) == 8, "size of CullFace should be 8"); +static_assert(offsetof(CullFace, header) == 0, + "offset of CullFace header should be 0"); +static_assert(offsetof(CullFace, mode) == 4, + "offset of CullFace mode should be 4"); struct DeleteBuffersImmediate { typedef DeleteBuffersImmediate ValueType; @@ -1449,12 +2409,12 @@ struct DeleteBuffersImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(DeleteBuffersImmediate) == 8, - Sizeof_DeleteBuffersImmediate_is_not_8); -COMPILE_ASSERT(offsetof(DeleteBuffersImmediate, header) == 0, - OffsetOf_DeleteBuffersImmediate_header_not_0); -COMPILE_ASSERT(offsetof(DeleteBuffersImmediate, n) == 4, - OffsetOf_DeleteBuffersImmediate_n_not_4); +static_assert(sizeof(DeleteBuffersImmediate) == 8, + "size of DeleteBuffersImmediate should be 8"); +static_assert(offsetof(DeleteBuffersImmediate, header) == 0, + "offset of DeleteBuffersImmediate header should be 0"); +static_assert(offsetof(DeleteBuffersImmediate, n) == 4, + "offset of DeleteBuffersImmediate n should be 4"); struct DeleteFramebuffersImmediate { typedef DeleteFramebuffersImmediate ValueType; @@ -1491,12 +2451,12 @@ struct DeleteFramebuffersImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(DeleteFramebuffersImmediate) == 8, - Sizeof_DeleteFramebuffersImmediate_is_not_8); -COMPILE_ASSERT(offsetof(DeleteFramebuffersImmediate, header) == 0, - OffsetOf_DeleteFramebuffersImmediate_header_not_0); -COMPILE_ASSERT(offsetof(DeleteFramebuffersImmediate, n) == 4, - OffsetOf_DeleteFramebuffersImmediate_n_not_4); +static_assert(sizeof(DeleteFramebuffersImmediate) == 8, + "size of DeleteFramebuffersImmediate should be 8"); +static_assert(offsetof(DeleteFramebuffersImmediate, header) == 0, + "offset of DeleteFramebuffersImmediate header should be 0"); +static_assert(offsetof(DeleteFramebuffersImmediate, n) == 4, + "offset of DeleteFramebuffersImmediate n should be 4"); struct DeleteProgram { typedef DeleteProgram ValueType; @@ -1524,11 +2484,11 @@ struct DeleteProgram { uint32_t program; }; -COMPILE_ASSERT(sizeof(DeleteProgram) == 8, Sizeof_DeleteProgram_is_not_8); -COMPILE_ASSERT(offsetof(DeleteProgram, header) == 0, - OffsetOf_DeleteProgram_header_not_0); -COMPILE_ASSERT(offsetof(DeleteProgram, program) == 4, - OffsetOf_DeleteProgram_program_not_4); +static_assert(sizeof(DeleteProgram) == 8, "size of DeleteProgram should be 8"); +static_assert(offsetof(DeleteProgram, header) == 0, + "offset of DeleteProgram header should be 0"); +static_assert(offsetof(DeleteProgram, program) == 4, + "offset of DeleteProgram program should be 4"); struct DeleteRenderbuffersImmediate { typedef DeleteRenderbuffersImmediate ValueType; @@ -1565,12 +2525,86 @@ struct DeleteRenderbuffersImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(DeleteRenderbuffersImmediate) == 8, - Sizeof_DeleteRenderbuffersImmediate_is_not_8); -COMPILE_ASSERT(offsetof(DeleteRenderbuffersImmediate, header) == 0, - OffsetOf_DeleteRenderbuffersImmediate_header_not_0); -COMPILE_ASSERT(offsetof(DeleteRenderbuffersImmediate, n) == 4, - OffsetOf_DeleteRenderbuffersImmediate_n_not_4); +static_assert(sizeof(DeleteRenderbuffersImmediate) == 8, + "size of DeleteRenderbuffersImmediate should be 8"); +static_assert(offsetof(DeleteRenderbuffersImmediate, header) == 0, + "offset of DeleteRenderbuffersImmediate header should be 0"); +static_assert(offsetof(DeleteRenderbuffersImmediate, n) == 4, + "offset of DeleteRenderbuffersImmediate n should be 4"); + +struct DeleteSamplersImmediate { + typedef DeleteSamplersImmediate ValueType; + static const CommandId kCmdId = kDeleteSamplersImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei n) { + return static_cast<uint32_t>(sizeof(GLuint) * n); // NOLINT + } + + static uint32_t ComputeSize(GLsizei n) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, const GLuint* _samplers) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), _samplers, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, const GLuint* _samplers) { + static_cast<ValueType*>(cmd)->Init(_n, _samplers); + const uint32_t size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t n; +}; + +static_assert(sizeof(DeleteSamplersImmediate) == 8, + "size of DeleteSamplersImmediate should be 8"); +static_assert(offsetof(DeleteSamplersImmediate, header) == 0, + "offset of DeleteSamplersImmediate header should be 0"); +static_assert(offsetof(DeleteSamplersImmediate, n) == 4, + "offset of DeleteSamplersImmediate n should be 4"); + +struct DeleteSync { + typedef DeleteSync ValueType; + static const CommandId kCmdId = kDeleteSync; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _sync) { + SetHeader(); + sync = _sync; + } + + void* Set(void* cmd, GLuint _sync) { + static_cast<ValueType*>(cmd)->Init(_sync); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t sync; +}; + +static_assert(sizeof(DeleteSync) == 8, "size of DeleteSync should be 8"); +static_assert(offsetof(DeleteSync, header) == 0, + "offset of DeleteSync header should be 0"); +static_assert(offsetof(DeleteSync, sync) == 4, + "offset of DeleteSync sync should be 4"); struct DeleteShader { typedef DeleteShader ValueType; @@ -1598,11 +2632,11 @@ struct DeleteShader { uint32_t shader; }; -COMPILE_ASSERT(sizeof(DeleteShader) == 8, Sizeof_DeleteShader_is_not_8); -COMPILE_ASSERT(offsetof(DeleteShader, header) == 0, - OffsetOf_DeleteShader_header_not_0); -COMPILE_ASSERT(offsetof(DeleteShader, shader) == 4, - OffsetOf_DeleteShader_shader_not_4); +static_assert(sizeof(DeleteShader) == 8, "size of DeleteShader should be 8"); +static_assert(offsetof(DeleteShader, header) == 0, + "offset of DeleteShader header should be 0"); +static_assert(offsetof(DeleteShader, shader) == 4, + "offset of DeleteShader shader should be 4"); struct DeleteTexturesImmediate { typedef DeleteTexturesImmediate ValueType; @@ -1639,12 +2673,54 @@ struct DeleteTexturesImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(DeleteTexturesImmediate) == 8, - Sizeof_DeleteTexturesImmediate_is_not_8); -COMPILE_ASSERT(offsetof(DeleteTexturesImmediate, header) == 0, - OffsetOf_DeleteTexturesImmediate_header_not_0); -COMPILE_ASSERT(offsetof(DeleteTexturesImmediate, n) == 4, - OffsetOf_DeleteTexturesImmediate_n_not_4); +static_assert(sizeof(DeleteTexturesImmediate) == 8, + "size of DeleteTexturesImmediate should be 8"); +static_assert(offsetof(DeleteTexturesImmediate, header) == 0, + "offset of DeleteTexturesImmediate header should be 0"); +static_assert(offsetof(DeleteTexturesImmediate, n) == 4, + "offset of DeleteTexturesImmediate n should be 4"); + +struct DeleteTransformFeedbacksImmediate { + typedef DeleteTransformFeedbacksImmediate ValueType; + static const CommandId kCmdId = kDeleteTransformFeedbacksImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei n) { + return static_cast<uint32_t>(sizeof(GLuint) * n); // NOLINT + } + + static uint32_t ComputeSize(GLsizei n) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, const GLuint* _ids) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), _ids, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, const GLuint* _ids) { + static_cast<ValueType*>(cmd)->Init(_n, _ids); + const uint32_t size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t n; +}; + +static_assert(sizeof(DeleteTransformFeedbacksImmediate) == 8, + "size of DeleteTransformFeedbacksImmediate should be 8"); +static_assert(offsetof(DeleteTransformFeedbacksImmediate, header) == 0, + "offset of DeleteTransformFeedbacksImmediate header should be 0"); +static_assert(offsetof(DeleteTransformFeedbacksImmediate, n) == 4, + "offset of DeleteTransformFeedbacksImmediate n should be 4"); struct DepthFunc { typedef DepthFunc ValueType; @@ -1672,10 +2748,11 @@ struct DepthFunc { uint32_t func; }; -COMPILE_ASSERT(sizeof(DepthFunc) == 8, Sizeof_DepthFunc_is_not_8); -COMPILE_ASSERT(offsetof(DepthFunc, header) == 0, - OffsetOf_DepthFunc_header_not_0); -COMPILE_ASSERT(offsetof(DepthFunc, func) == 4, OffsetOf_DepthFunc_func_not_4); +static_assert(sizeof(DepthFunc) == 8, "size of DepthFunc should be 8"); +static_assert(offsetof(DepthFunc, header) == 0, + "offset of DepthFunc header should be 0"); +static_assert(offsetof(DepthFunc, func) == 4, + "offset of DepthFunc func should be 4"); struct DepthMask { typedef DepthMask ValueType; @@ -1703,10 +2780,11 @@ struct DepthMask { uint32_t flag; }; -COMPILE_ASSERT(sizeof(DepthMask) == 8, Sizeof_DepthMask_is_not_8); -COMPILE_ASSERT(offsetof(DepthMask, header) == 0, - OffsetOf_DepthMask_header_not_0); -COMPILE_ASSERT(offsetof(DepthMask, flag) == 4, OffsetOf_DepthMask_flag_not_4); +static_assert(sizeof(DepthMask) == 8, "size of DepthMask should be 8"); +static_assert(offsetof(DepthMask, header) == 0, + "offset of DepthMask header should be 0"); +static_assert(offsetof(DepthMask, flag) == 4, + "offset of DepthMask flag should be 4"); struct DepthRangef { typedef DepthRangef ValueType; @@ -1736,13 +2814,13 @@ struct DepthRangef { float zFar; }; -COMPILE_ASSERT(sizeof(DepthRangef) == 12, Sizeof_DepthRangef_is_not_12); -COMPILE_ASSERT(offsetof(DepthRangef, header) == 0, - OffsetOf_DepthRangef_header_not_0); -COMPILE_ASSERT(offsetof(DepthRangef, zNear) == 4, - OffsetOf_DepthRangef_zNear_not_4); -COMPILE_ASSERT(offsetof(DepthRangef, zFar) == 8, - OffsetOf_DepthRangef_zFar_not_8); +static_assert(sizeof(DepthRangef) == 12, "size of DepthRangef should be 12"); +static_assert(offsetof(DepthRangef, header) == 0, + "offset of DepthRangef header should be 0"); +static_assert(offsetof(DepthRangef, zNear) == 4, + "offset of DepthRangef zNear should be 4"); +static_assert(offsetof(DepthRangef, zFar) == 8, + "offset of DepthRangef zFar should be 8"); struct DetachShader { typedef DetachShader ValueType; @@ -1772,13 +2850,13 @@ struct DetachShader { uint32_t shader; }; -COMPILE_ASSERT(sizeof(DetachShader) == 12, Sizeof_DetachShader_is_not_12); -COMPILE_ASSERT(offsetof(DetachShader, header) == 0, - OffsetOf_DetachShader_header_not_0); -COMPILE_ASSERT(offsetof(DetachShader, program) == 4, - OffsetOf_DetachShader_program_not_4); -COMPILE_ASSERT(offsetof(DetachShader, shader) == 8, - OffsetOf_DetachShader_shader_not_8); +static_assert(sizeof(DetachShader) == 12, "size of DetachShader should be 12"); +static_assert(offsetof(DetachShader, header) == 0, + "offset of DetachShader header should be 0"); +static_assert(offsetof(DetachShader, program) == 4, + "offset of DetachShader program should be 4"); +static_assert(offsetof(DetachShader, shader) == 8, + "offset of DetachShader shader should be 8"); struct Disable { typedef Disable ValueType; @@ -1806,9 +2884,10 @@ struct Disable { uint32_t cap; }; -COMPILE_ASSERT(sizeof(Disable) == 8, Sizeof_Disable_is_not_8); -COMPILE_ASSERT(offsetof(Disable, header) == 0, OffsetOf_Disable_header_not_0); -COMPILE_ASSERT(offsetof(Disable, cap) == 4, OffsetOf_Disable_cap_not_4); +static_assert(sizeof(Disable) == 8, "size of Disable should be 8"); +static_assert(offsetof(Disable, header) == 0, + "offset of Disable header should be 0"); +static_assert(offsetof(Disable, cap) == 4, "offset of Disable cap should be 4"); struct DisableVertexAttribArray { typedef DisableVertexAttribArray ValueType; @@ -1836,12 +2915,12 @@ struct DisableVertexAttribArray { uint32_t index; }; -COMPILE_ASSERT(sizeof(DisableVertexAttribArray) == 8, - Sizeof_DisableVertexAttribArray_is_not_8); -COMPILE_ASSERT(offsetof(DisableVertexAttribArray, header) == 0, - OffsetOf_DisableVertexAttribArray_header_not_0); -COMPILE_ASSERT(offsetof(DisableVertexAttribArray, index) == 4, - OffsetOf_DisableVertexAttribArray_index_not_4); +static_assert(sizeof(DisableVertexAttribArray) == 8, + "size of DisableVertexAttribArray should be 8"); +static_assert(offsetof(DisableVertexAttribArray, header) == 0, + "offset of DisableVertexAttribArray header should be 0"); +static_assert(offsetof(DisableVertexAttribArray, index) == 4, + "offset of DisableVertexAttribArray index should be 4"); struct DrawArrays { typedef DrawArrays ValueType; @@ -1873,14 +2952,15 @@ struct DrawArrays { int32_t count; }; -COMPILE_ASSERT(sizeof(DrawArrays) == 16, Sizeof_DrawArrays_is_not_16); -COMPILE_ASSERT(offsetof(DrawArrays, header) == 0, - OffsetOf_DrawArrays_header_not_0); -COMPILE_ASSERT(offsetof(DrawArrays, mode) == 4, OffsetOf_DrawArrays_mode_not_4); -COMPILE_ASSERT(offsetof(DrawArrays, first) == 8, - OffsetOf_DrawArrays_first_not_8); -COMPILE_ASSERT(offsetof(DrawArrays, count) == 12, - OffsetOf_DrawArrays_count_not_12); +static_assert(sizeof(DrawArrays) == 16, "size of DrawArrays should be 16"); +static_assert(offsetof(DrawArrays, header) == 0, + "offset of DrawArrays header should be 0"); +static_assert(offsetof(DrawArrays, mode) == 4, + "offset of DrawArrays mode should be 4"); +static_assert(offsetof(DrawArrays, first) == 8, + "offset of DrawArrays first should be 8"); +static_assert(offsetof(DrawArrays, count) == 12, + "offset of DrawArrays count should be 12"); struct DrawElements { typedef DrawElements ValueType; @@ -1918,17 +2998,17 @@ struct DrawElements { uint32_t index_offset; }; -COMPILE_ASSERT(sizeof(DrawElements) == 20, Sizeof_DrawElements_is_not_20); -COMPILE_ASSERT(offsetof(DrawElements, header) == 0, - OffsetOf_DrawElements_header_not_0); -COMPILE_ASSERT(offsetof(DrawElements, mode) == 4, - OffsetOf_DrawElements_mode_not_4); -COMPILE_ASSERT(offsetof(DrawElements, count) == 8, - OffsetOf_DrawElements_count_not_8); -COMPILE_ASSERT(offsetof(DrawElements, type) == 12, - OffsetOf_DrawElements_type_not_12); -COMPILE_ASSERT(offsetof(DrawElements, index_offset) == 16, - OffsetOf_DrawElements_index_offset_not_16); +static_assert(sizeof(DrawElements) == 20, "size of DrawElements should be 20"); +static_assert(offsetof(DrawElements, header) == 0, + "offset of DrawElements header should be 0"); +static_assert(offsetof(DrawElements, mode) == 4, + "offset of DrawElements mode should be 4"); +static_assert(offsetof(DrawElements, count) == 8, + "offset of DrawElements count should be 8"); +static_assert(offsetof(DrawElements, type) == 12, + "offset of DrawElements type should be 12"); +static_assert(offsetof(DrawElements, index_offset) == 16, + "offset of DrawElements index_offset should be 16"); struct Enable { typedef Enable ValueType; @@ -1956,9 +3036,10 @@ struct Enable { uint32_t cap; }; -COMPILE_ASSERT(sizeof(Enable) == 8, Sizeof_Enable_is_not_8); -COMPILE_ASSERT(offsetof(Enable, header) == 0, OffsetOf_Enable_header_not_0); -COMPILE_ASSERT(offsetof(Enable, cap) == 4, OffsetOf_Enable_cap_not_4); +static_assert(sizeof(Enable) == 8, "size of Enable should be 8"); +static_assert(offsetof(Enable, header) == 0, + "offset of Enable header should be 0"); +static_assert(offsetof(Enable, cap) == 4, "offset of Enable cap should be 4"); struct EnableVertexAttribArray { typedef EnableVertexAttribArray ValueType; @@ -1986,12 +3067,46 @@ struct EnableVertexAttribArray { uint32_t index; }; -COMPILE_ASSERT(sizeof(EnableVertexAttribArray) == 8, - Sizeof_EnableVertexAttribArray_is_not_8); -COMPILE_ASSERT(offsetof(EnableVertexAttribArray, header) == 0, - OffsetOf_EnableVertexAttribArray_header_not_0); -COMPILE_ASSERT(offsetof(EnableVertexAttribArray, index) == 4, - OffsetOf_EnableVertexAttribArray_index_not_4); +static_assert(sizeof(EnableVertexAttribArray) == 8, + "size of EnableVertexAttribArray should be 8"); +static_assert(offsetof(EnableVertexAttribArray, header) == 0, + "offset of EnableVertexAttribArray header should be 0"); +static_assert(offsetof(EnableVertexAttribArray, index) == 4, + "offset of EnableVertexAttribArray index should be 4"); + +struct FenceSync { + typedef FenceSync ValueType; + static const CommandId kCmdId = kFenceSync; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(uint32_t _client_id) { + SetHeader(); + client_id = _client_id; + } + + void* Set(void* cmd, uint32_t _client_id) { + static_cast<ValueType*>(cmd)->Init(_client_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t client_id; + static const uint32_t condition = GL_SYNC_GPU_COMMANDS_COMPLETE; + static const uint32_t flags = 0; +}; + +static_assert(sizeof(FenceSync) == 8, "size of FenceSync should be 8"); +static_assert(offsetof(FenceSync, header) == 0, + "offset of FenceSync header should be 0"); +static_assert(offsetof(FenceSync, client_id) == 4, + "offset of FenceSync client_id should be 4"); struct Finish { typedef Finish ValueType; @@ -2015,8 +3130,9 @@ struct Finish { gpu::CommandHeader header; }; -COMPILE_ASSERT(sizeof(Finish) == 4, Sizeof_Finish_is_not_4); -COMPILE_ASSERT(offsetof(Finish, header) == 0, OffsetOf_Finish_header_not_0); +static_assert(sizeof(Finish) == 4, "size of Finish should be 4"); +static_assert(offsetof(Finish, header) == 0, + "offset of Finish header should be 0"); struct Flush { typedef Flush ValueType; @@ -2040,8 +3156,9 @@ struct Flush { gpu::CommandHeader header; }; -COMPILE_ASSERT(sizeof(Flush) == 4, Sizeof_Flush_is_not_4); -COMPILE_ASSERT(offsetof(Flush, header) == 0, OffsetOf_Flush_header_not_0); +static_assert(sizeof(Flush) == 4, "size of Flush should be 4"); +static_assert(offsetof(Flush, header) == 0, + "offset of Flush header should be 0"); struct FramebufferRenderbuffer { typedef FramebufferRenderbuffer ValueType; @@ -2083,18 +3200,19 @@ struct FramebufferRenderbuffer { uint32_t renderbuffer; }; -COMPILE_ASSERT(sizeof(FramebufferRenderbuffer) == 20, - Sizeof_FramebufferRenderbuffer_is_not_20); -COMPILE_ASSERT(offsetof(FramebufferRenderbuffer, header) == 0, - OffsetOf_FramebufferRenderbuffer_header_not_0); -COMPILE_ASSERT(offsetof(FramebufferRenderbuffer, target) == 4, - OffsetOf_FramebufferRenderbuffer_target_not_4); -COMPILE_ASSERT(offsetof(FramebufferRenderbuffer, attachment) == 8, - OffsetOf_FramebufferRenderbuffer_attachment_not_8); -COMPILE_ASSERT(offsetof(FramebufferRenderbuffer, renderbuffertarget) == 12, - OffsetOf_FramebufferRenderbuffer_renderbuffertarget_not_12); -COMPILE_ASSERT(offsetof(FramebufferRenderbuffer, renderbuffer) == 16, - OffsetOf_FramebufferRenderbuffer_renderbuffer_not_16); +static_assert(sizeof(FramebufferRenderbuffer) == 20, + "size of FramebufferRenderbuffer should be 20"); +static_assert(offsetof(FramebufferRenderbuffer, header) == 0, + "offset of FramebufferRenderbuffer header should be 0"); +static_assert(offsetof(FramebufferRenderbuffer, target) == 4, + "offset of FramebufferRenderbuffer target should be 4"); +static_assert(offsetof(FramebufferRenderbuffer, attachment) == 8, + "offset of FramebufferRenderbuffer attachment should be 8"); +static_assert( + offsetof(FramebufferRenderbuffer, renderbuffertarget) == 12, + "offset of FramebufferRenderbuffer renderbuffertarget should be 12"); +static_assert(offsetof(FramebufferRenderbuffer, renderbuffer) == 16, + "offset of FramebufferRenderbuffer renderbuffer should be 16"); struct FramebufferTexture2D { typedef FramebufferTexture2D ValueType; @@ -2137,18 +3255,77 @@ struct FramebufferTexture2D { static const int32_t level = 0; }; -COMPILE_ASSERT(sizeof(FramebufferTexture2D) == 20, - Sizeof_FramebufferTexture2D_is_not_20); -COMPILE_ASSERT(offsetof(FramebufferTexture2D, header) == 0, - OffsetOf_FramebufferTexture2D_header_not_0); -COMPILE_ASSERT(offsetof(FramebufferTexture2D, target) == 4, - OffsetOf_FramebufferTexture2D_target_not_4); -COMPILE_ASSERT(offsetof(FramebufferTexture2D, attachment) == 8, - OffsetOf_FramebufferTexture2D_attachment_not_8); -COMPILE_ASSERT(offsetof(FramebufferTexture2D, textarget) == 12, - OffsetOf_FramebufferTexture2D_textarget_not_12); -COMPILE_ASSERT(offsetof(FramebufferTexture2D, texture) == 16, - OffsetOf_FramebufferTexture2D_texture_not_16); +static_assert(sizeof(FramebufferTexture2D) == 20, + "size of FramebufferTexture2D should be 20"); +static_assert(offsetof(FramebufferTexture2D, header) == 0, + "offset of FramebufferTexture2D header should be 0"); +static_assert(offsetof(FramebufferTexture2D, target) == 4, + "offset of FramebufferTexture2D target should be 4"); +static_assert(offsetof(FramebufferTexture2D, attachment) == 8, + "offset of FramebufferTexture2D attachment should be 8"); +static_assert(offsetof(FramebufferTexture2D, textarget) == 12, + "offset of FramebufferTexture2D textarget should be 12"); +static_assert(offsetof(FramebufferTexture2D, texture) == 16, + "offset of FramebufferTexture2D texture should be 16"); + +struct FramebufferTextureLayer { + typedef FramebufferTextureLayer ValueType; + static const CommandId kCmdId = kFramebufferTextureLayer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLenum _attachment, + GLuint _texture, + GLint _level, + GLint _layer) { + SetHeader(); + target = _target; + attachment = _attachment; + texture = _texture; + level = _level; + layer = _layer; + } + + void* Set(void* cmd, + GLenum _target, + GLenum _attachment, + GLuint _texture, + GLint _level, + GLint _layer) { + static_cast<ValueType*>(cmd) + ->Init(_target, _attachment, _texture, _level, _layer); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + uint32_t attachment; + uint32_t texture; + int32_t level; + int32_t layer; +}; + +static_assert(sizeof(FramebufferTextureLayer) == 24, + "size of FramebufferTextureLayer should be 24"); +static_assert(offsetof(FramebufferTextureLayer, header) == 0, + "offset of FramebufferTextureLayer header should be 0"); +static_assert(offsetof(FramebufferTextureLayer, target) == 4, + "offset of FramebufferTextureLayer target should be 4"); +static_assert(offsetof(FramebufferTextureLayer, attachment) == 8, + "offset of FramebufferTextureLayer attachment should be 8"); +static_assert(offsetof(FramebufferTextureLayer, texture) == 12, + "offset of FramebufferTextureLayer texture should be 12"); +static_assert(offsetof(FramebufferTextureLayer, level) == 16, + "offset of FramebufferTextureLayer level should be 16"); +static_assert(offsetof(FramebufferTextureLayer, layer) == 20, + "offset of FramebufferTextureLayer layer should be 20"); struct FrontFace { typedef FrontFace ValueType; @@ -2176,10 +3353,11 @@ struct FrontFace { uint32_t mode; }; -COMPILE_ASSERT(sizeof(FrontFace) == 8, Sizeof_FrontFace_is_not_8); -COMPILE_ASSERT(offsetof(FrontFace, header) == 0, - OffsetOf_FrontFace_header_not_0); -COMPILE_ASSERT(offsetof(FrontFace, mode) == 4, OffsetOf_FrontFace_mode_not_4); +static_assert(sizeof(FrontFace) == 8, "size of FrontFace should be 8"); +static_assert(offsetof(FrontFace, header) == 0, + "offset of FrontFace header should be 0"); +static_assert(offsetof(FrontFace, mode) == 4, + "offset of FrontFace mode should be 4"); struct GenBuffersImmediate { typedef GenBuffersImmediate ValueType; @@ -2216,12 +3394,12 @@ struct GenBuffersImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(GenBuffersImmediate) == 8, - Sizeof_GenBuffersImmediate_is_not_8); -COMPILE_ASSERT(offsetof(GenBuffersImmediate, header) == 0, - OffsetOf_GenBuffersImmediate_header_not_0); -COMPILE_ASSERT(offsetof(GenBuffersImmediate, n) == 4, - OffsetOf_GenBuffersImmediate_n_not_4); +static_assert(sizeof(GenBuffersImmediate) == 8, + "size of GenBuffersImmediate should be 8"); +static_assert(offsetof(GenBuffersImmediate, header) == 0, + "offset of GenBuffersImmediate header should be 0"); +static_assert(offsetof(GenBuffersImmediate, n) == 4, + "offset of GenBuffersImmediate n should be 4"); struct GenerateMipmap { typedef GenerateMipmap ValueType; @@ -2249,11 +3427,12 @@ struct GenerateMipmap { uint32_t target; }; -COMPILE_ASSERT(sizeof(GenerateMipmap) == 8, Sizeof_GenerateMipmap_is_not_8); -COMPILE_ASSERT(offsetof(GenerateMipmap, header) == 0, - OffsetOf_GenerateMipmap_header_not_0); -COMPILE_ASSERT(offsetof(GenerateMipmap, target) == 4, - OffsetOf_GenerateMipmap_target_not_4); +static_assert(sizeof(GenerateMipmap) == 8, + "size of GenerateMipmap should be 8"); +static_assert(offsetof(GenerateMipmap, header) == 0, + "offset of GenerateMipmap header should be 0"); +static_assert(offsetof(GenerateMipmap, target) == 4, + "offset of GenerateMipmap target should be 4"); struct GenFramebuffersImmediate { typedef GenFramebuffersImmediate ValueType; @@ -2290,12 +3469,12 @@ struct GenFramebuffersImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(GenFramebuffersImmediate) == 8, - Sizeof_GenFramebuffersImmediate_is_not_8); -COMPILE_ASSERT(offsetof(GenFramebuffersImmediate, header) == 0, - OffsetOf_GenFramebuffersImmediate_header_not_0); -COMPILE_ASSERT(offsetof(GenFramebuffersImmediate, n) == 4, - OffsetOf_GenFramebuffersImmediate_n_not_4); +static_assert(sizeof(GenFramebuffersImmediate) == 8, + "size of GenFramebuffersImmediate should be 8"); +static_assert(offsetof(GenFramebuffersImmediate, header) == 0, + "offset of GenFramebuffersImmediate header should be 0"); +static_assert(offsetof(GenFramebuffersImmediate, n) == 4, + "offset of GenFramebuffersImmediate n should be 4"); struct GenRenderbuffersImmediate { typedef GenRenderbuffersImmediate ValueType; @@ -2332,12 +3511,54 @@ struct GenRenderbuffersImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(GenRenderbuffersImmediate) == 8, - Sizeof_GenRenderbuffersImmediate_is_not_8); -COMPILE_ASSERT(offsetof(GenRenderbuffersImmediate, header) == 0, - OffsetOf_GenRenderbuffersImmediate_header_not_0); -COMPILE_ASSERT(offsetof(GenRenderbuffersImmediate, n) == 4, - OffsetOf_GenRenderbuffersImmediate_n_not_4); +static_assert(sizeof(GenRenderbuffersImmediate) == 8, + "size of GenRenderbuffersImmediate should be 8"); +static_assert(offsetof(GenRenderbuffersImmediate, header) == 0, + "offset of GenRenderbuffersImmediate header should be 0"); +static_assert(offsetof(GenRenderbuffersImmediate, n) == 4, + "offset of GenRenderbuffersImmediate n should be 4"); + +struct GenSamplersImmediate { + typedef GenSamplersImmediate ValueType; + static const CommandId kCmdId = kGenSamplersImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei n) { + return static_cast<uint32_t>(sizeof(GLuint) * n); // NOLINT + } + + static uint32_t ComputeSize(GLsizei n) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, GLuint* _samplers) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), _samplers, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, GLuint* _samplers) { + static_cast<ValueType*>(cmd)->Init(_n, _samplers); + const uint32_t size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t n; +}; + +static_assert(sizeof(GenSamplersImmediate) == 8, + "size of GenSamplersImmediate should be 8"); +static_assert(offsetof(GenSamplersImmediate, header) == 0, + "offset of GenSamplersImmediate header should be 0"); +static_assert(offsetof(GenSamplersImmediate, n) == 4, + "offset of GenSamplersImmediate n should be 4"); struct GenTexturesImmediate { typedef GenTexturesImmediate ValueType; @@ -2374,12 +3595,54 @@ struct GenTexturesImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(GenTexturesImmediate) == 8, - Sizeof_GenTexturesImmediate_is_not_8); -COMPILE_ASSERT(offsetof(GenTexturesImmediate, header) == 0, - OffsetOf_GenTexturesImmediate_header_not_0); -COMPILE_ASSERT(offsetof(GenTexturesImmediate, n) == 4, - OffsetOf_GenTexturesImmediate_n_not_4); +static_assert(sizeof(GenTexturesImmediate) == 8, + "size of GenTexturesImmediate should be 8"); +static_assert(offsetof(GenTexturesImmediate, header) == 0, + "offset of GenTexturesImmediate header should be 0"); +static_assert(offsetof(GenTexturesImmediate, n) == 4, + "offset of GenTexturesImmediate n should be 4"); + +struct GenTransformFeedbacksImmediate { + typedef GenTransformFeedbacksImmediate ValueType; + static const CommandId kCmdId = kGenTransformFeedbacksImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei n) { + return static_cast<uint32_t>(sizeof(GLuint) * n); // NOLINT + } + + static uint32_t ComputeSize(GLsizei n) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, GLuint* _ids) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), _ids, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, GLuint* _ids) { + static_cast<ValueType*>(cmd)->Init(_n, _ids); + const uint32_t size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t n; +}; + +static_assert(sizeof(GenTransformFeedbacksImmediate) == 8, + "size of GenTransformFeedbacksImmediate should be 8"); +static_assert(offsetof(GenTransformFeedbacksImmediate, header) == 0, + "offset of GenTransformFeedbacksImmediate header should be 0"); +static_assert(offsetof(GenTransformFeedbacksImmediate, n) == 4, + "offset of GenTransformFeedbacksImmediate n should be 4"); struct GetActiveAttrib { typedef GetActiveAttrib ValueType; @@ -2431,25 +3694,29 @@ struct GetActiveAttrib { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(GetActiveAttrib) == 24, Sizeof_GetActiveAttrib_is_not_24); -COMPILE_ASSERT(offsetof(GetActiveAttrib, header) == 0, - OffsetOf_GetActiveAttrib_header_not_0); -COMPILE_ASSERT(offsetof(GetActiveAttrib, program) == 4, - OffsetOf_GetActiveAttrib_program_not_4); -COMPILE_ASSERT(offsetof(GetActiveAttrib, index) == 8, - OffsetOf_GetActiveAttrib_index_not_8); -COMPILE_ASSERT(offsetof(GetActiveAttrib, name_bucket_id) == 12, - OffsetOf_GetActiveAttrib_name_bucket_id_not_12); -COMPILE_ASSERT(offsetof(GetActiveAttrib, result_shm_id) == 16, - OffsetOf_GetActiveAttrib_result_shm_id_not_16); -COMPILE_ASSERT(offsetof(GetActiveAttrib, result_shm_offset) == 20, - OffsetOf_GetActiveAttrib_result_shm_offset_not_20); -COMPILE_ASSERT(offsetof(GetActiveAttrib::Result, success) == 0, - OffsetOf_GetActiveAttrib_Result_success_not_0); -COMPILE_ASSERT(offsetof(GetActiveAttrib::Result, size) == 4, - OffsetOf_GetActiveAttrib_Result_size_not_4); -COMPILE_ASSERT(offsetof(GetActiveAttrib::Result, type) == 8, - OffsetOf_GetActiveAttrib_Result_type_not_8); +static_assert(sizeof(GetActiveAttrib) == 24, + "size of GetActiveAttrib should be 24"); +static_assert(offsetof(GetActiveAttrib, header) == 0, + "offset of GetActiveAttrib header should be 0"); +static_assert(offsetof(GetActiveAttrib, program) == 4, + "offset of GetActiveAttrib program should be 4"); +static_assert(offsetof(GetActiveAttrib, index) == 8, + "offset of GetActiveAttrib index should be 8"); +static_assert(offsetof(GetActiveAttrib, name_bucket_id) == 12, + "offset of GetActiveAttrib name_bucket_id should be 12"); +static_assert(offsetof(GetActiveAttrib, result_shm_id) == 16, + "offset of GetActiveAttrib result_shm_id should be 16"); +static_assert(offsetof(GetActiveAttrib, result_shm_offset) == 20, + "offset of GetActiveAttrib result_shm_offset should be 20"); +static_assert(offsetof(GetActiveAttrib::Result, success) == 0, + "offset of GetActiveAttrib Result success should be " + "0"); +static_assert(offsetof(GetActiveAttrib::Result, size) == 4, + "offset of GetActiveAttrib Result size should be " + "4"); +static_assert(offsetof(GetActiveAttrib::Result, type) == 8, + "offset of GetActiveAttrib Result type should be " + "8"); struct GetActiveUniform { typedef GetActiveUniform ValueType; @@ -2501,26 +3768,215 @@ struct GetActiveUniform { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(GetActiveUniform) == 24, - Sizeof_GetActiveUniform_is_not_24); -COMPILE_ASSERT(offsetof(GetActiveUniform, header) == 0, - OffsetOf_GetActiveUniform_header_not_0); -COMPILE_ASSERT(offsetof(GetActiveUniform, program) == 4, - OffsetOf_GetActiveUniform_program_not_4); -COMPILE_ASSERT(offsetof(GetActiveUniform, index) == 8, - OffsetOf_GetActiveUniform_index_not_8); -COMPILE_ASSERT(offsetof(GetActiveUniform, name_bucket_id) == 12, - OffsetOf_GetActiveUniform_name_bucket_id_not_12); -COMPILE_ASSERT(offsetof(GetActiveUniform, result_shm_id) == 16, - OffsetOf_GetActiveUniform_result_shm_id_not_16); -COMPILE_ASSERT(offsetof(GetActiveUniform, result_shm_offset) == 20, - OffsetOf_GetActiveUniform_result_shm_offset_not_20); -COMPILE_ASSERT(offsetof(GetActiveUniform::Result, success) == 0, - OffsetOf_GetActiveUniform_Result_success_not_0); -COMPILE_ASSERT(offsetof(GetActiveUniform::Result, size) == 4, - OffsetOf_GetActiveUniform_Result_size_not_4); -COMPILE_ASSERT(offsetof(GetActiveUniform::Result, type) == 8, - OffsetOf_GetActiveUniform_Result_type_not_8); +static_assert(sizeof(GetActiveUniform) == 24, + "size of GetActiveUniform should be 24"); +static_assert(offsetof(GetActiveUniform, header) == 0, + "offset of GetActiveUniform header should be 0"); +static_assert(offsetof(GetActiveUniform, program) == 4, + "offset of GetActiveUniform program should be 4"); +static_assert(offsetof(GetActiveUniform, index) == 8, + "offset of GetActiveUniform index should be 8"); +static_assert(offsetof(GetActiveUniform, name_bucket_id) == 12, + "offset of GetActiveUniform name_bucket_id should be 12"); +static_assert(offsetof(GetActiveUniform, result_shm_id) == 16, + "offset of GetActiveUniform result_shm_id should be 16"); +static_assert(offsetof(GetActiveUniform, result_shm_offset) == 20, + "offset of GetActiveUniform result_shm_offset should be 20"); +static_assert(offsetof(GetActiveUniform::Result, success) == 0, + "offset of GetActiveUniform Result success should be " + "0"); +static_assert(offsetof(GetActiveUniform::Result, size) == 4, + "offset of GetActiveUniform Result size should be " + "4"); +static_assert(offsetof(GetActiveUniform::Result, type) == 8, + "offset of GetActiveUniform Result type should be " + "8"); + +struct GetActiveUniformBlockiv { + typedef GetActiveUniformBlockiv ValueType; + static const CommandId kCmdId = kGetActiveUniformBlockiv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLint> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + GLuint _index, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + SetHeader(); + program = _program; + index = _index; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + GLuint _index, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_program, _index, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t index; + uint32_t pname; + uint32_t params_shm_id; + uint32_t params_shm_offset; +}; + +static_assert(sizeof(GetActiveUniformBlockiv) == 24, + "size of GetActiveUniformBlockiv should be 24"); +static_assert(offsetof(GetActiveUniformBlockiv, header) == 0, + "offset of GetActiveUniformBlockiv header should be 0"); +static_assert(offsetof(GetActiveUniformBlockiv, program) == 4, + "offset of GetActiveUniformBlockiv program should be 4"); +static_assert(offsetof(GetActiveUniformBlockiv, index) == 8, + "offset of GetActiveUniformBlockiv index should be 8"); +static_assert(offsetof(GetActiveUniformBlockiv, pname) == 12, + "offset of GetActiveUniformBlockiv pname should be 12"); +static_assert(offsetof(GetActiveUniformBlockiv, params_shm_id) == 16, + "offset of GetActiveUniformBlockiv params_shm_id should be 16"); +static_assert( + offsetof(GetActiveUniformBlockiv, params_shm_offset) == 20, + "offset of GetActiveUniformBlockiv params_shm_offset should be 20"); + +struct GetActiveUniformBlockName { + typedef GetActiveUniformBlockName ValueType; + static const CommandId kCmdId = kGetActiveUniformBlockName; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef int32_t Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + GLuint _index, + uint32_t _name_bucket_id, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + SetHeader(); + program = _program; + index = _index; + name_bucket_id = _name_bucket_id; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + GLuint _index, + uint32_t _name_bucket_id, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_program, _index, _name_bucket_id, + _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t index; + uint32_t name_bucket_id; + uint32_t result_shm_id; + uint32_t result_shm_offset; +}; + +static_assert(sizeof(GetActiveUniformBlockName) == 24, + "size of GetActiveUniformBlockName should be 24"); +static_assert(offsetof(GetActiveUniformBlockName, header) == 0, + "offset of GetActiveUniformBlockName header should be 0"); +static_assert(offsetof(GetActiveUniformBlockName, program) == 4, + "offset of GetActiveUniformBlockName program should be 4"); +static_assert(offsetof(GetActiveUniformBlockName, index) == 8, + "offset of GetActiveUniformBlockName index should be 8"); +static_assert( + offsetof(GetActiveUniformBlockName, name_bucket_id) == 12, + "offset of GetActiveUniformBlockName name_bucket_id should be 12"); +static_assert(offsetof(GetActiveUniformBlockName, result_shm_id) == 16, + "offset of GetActiveUniformBlockName result_shm_id should be 16"); +static_assert( + offsetof(GetActiveUniformBlockName, result_shm_offset) == 20, + "offset of GetActiveUniformBlockName result_shm_offset should be 20"); + +struct GetActiveUniformsiv { + typedef GetActiveUniformsiv ValueType; + static const CommandId kCmdId = kGetActiveUniformsiv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLint> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + uint32_t _indices_bucket_id, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + SetHeader(); + program = _program; + indices_bucket_id = _indices_bucket_id; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + uint32_t _indices_bucket_id, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_program, _indices_bucket_id, _pname, + _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t indices_bucket_id; + uint32_t pname; + uint32_t params_shm_id; + uint32_t params_shm_offset; +}; + +static_assert(sizeof(GetActiveUniformsiv) == 24, + "size of GetActiveUniformsiv should be 24"); +static_assert(offsetof(GetActiveUniformsiv, header) == 0, + "offset of GetActiveUniformsiv header should be 0"); +static_assert(offsetof(GetActiveUniformsiv, program) == 4, + "offset of GetActiveUniformsiv program should be 4"); +static_assert(offsetof(GetActiveUniformsiv, indices_bucket_id) == 8, + "offset of GetActiveUniformsiv indices_bucket_id should be 8"); +static_assert(offsetof(GetActiveUniformsiv, pname) == 12, + "offset of GetActiveUniformsiv pname should be 12"); +static_assert(offsetof(GetActiveUniformsiv, params_shm_id) == 16, + "offset of GetActiveUniformsiv params_shm_id should be 16"); +static_assert(offsetof(GetActiveUniformsiv, params_shm_offset) == 20, + "offset of GetActiveUniformsiv params_shm_offset should be 20"); struct GetAttachedShaders { typedef GetAttachedShaders ValueType; @@ -2564,18 +4020,18 @@ struct GetAttachedShaders { uint32_t result_size; }; -COMPILE_ASSERT(sizeof(GetAttachedShaders) == 20, - Sizeof_GetAttachedShaders_is_not_20); -COMPILE_ASSERT(offsetof(GetAttachedShaders, header) == 0, - OffsetOf_GetAttachedShaders_header_not_0); -COMPILE_ASSERT(offsetof(GetAttachedShaders, program) == 4, - OffsetOf_GetAttachedShaders_program_not_4); -COMPILE_ASSERT(offsetof(GetAttachedShaders, result_shm_id) == 8, - OffsetOf_GetAttachedShaders_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(GetAttachedShaders, result_shm_offset) == 12, - OffsetOf_GetAttachedShaders_result_shm_offset_not_12); -COMPILE_ASSERT(offsetof(GetAttachedShaders, result_size) == 16, - OffsetOf_GetAttachedShaders_result_size_not_16); +static_assert(sizeof(GetAttachedShaders) == 20, + "size of GetAttachedShaders should be 20"); +static_assert(offsetof(GetAttachedShaders, header) == 0, + "offset of GetAttachedShaders header should be 0"); +static_assert(offsetof(GetAttachedShaders, program) == 4, + "offset of GetAttachedShaders program should be 4"); +static_assert(offsetof(GetAttachedShaders, result_shm_id) == 8, + "offset of GetAttachedShaders result_shm_id should be 8"); +static_assert(offsetof(GetAttachedShaders, result_shm_offset) == 12, + "offset of GetAttachedShaders result_shm_offset should be 12"); +static_assert(offsetof(GetAttachedShaders, result_size) == 16, + "offset of GetAttachedShaders result_size should be 16"); struct GetAttribLocation { typedef GetAttribLocation ValueType; @@ -2619,18 +4075,18 @@ struct GetAttribLocation { uint32_t location_shm_offset; }; -COMPILE_ASSERT(sizeof(GetAttribLocation) == 20, - Sizeof_GetAttribLocation_is_not_20); -COMPILE_ASSERT(offsetof(GetAttribLocation, header) == 0, - OffsetOf_GetAttribLocation_header_not_0); -COMPILE_ASSERT(offsetof(GetAttribLocation, program) == 4, - OffsetOf_GetAttribLocation_program_not_4); -COMPILE_ASSERT(offsetof(GetAttribLocation, name_bucket_id) == 8, - OffsetOf_GetAttribLocation_name_bucket_id_not_8); -COMPILE_ASSERT(offsetof(GetAttribLocation, location_shm_id) == 12, - OffsetOf_GetAttribLocation_location_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetAttribLocation, location_shm_offset) == 16, - OffsetOf_GetAttribLocation_location_shm_offset_not_16); +static_assert(sizeof(GetAttribLocation) == 20, + "size of GetAttribLocation should be 20"); +static_assert(offsetof(GetAttribLocation, header) == 0, + "offset of GetAttribLocation header should be 0"); +static_assert(offsetof(GetAttribLocation, program) == 4, + "offset of GetAttribLocation program should be 4"); +static_assert(offsetof(GetAttribLocation, name_bucket_id) == 8, + "offset of GetAttribLocation name_bucket_id should be 8"); +static_assert(offsetof(GetAttribLocation, location_shm_id) == 12, + "offset of GetAttribLocation location_shm_id should be 12"); +static_assert(offsetof(GetAttribLocation, location_shm_offset) == 16, + "offset of GetAttribLocation location_shm_offset should be 16"); struct GetBooleanv { typedef GetBooleanv ValueType; @@ -2670,15 +4126,15 @@ struct GetBooleanv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetBooleanv) == 16, Sizeof_GetBooleanv_is_not_16); -COMPILE_ASSERT(offsetof(GetBooleanv, header) == 0, - OffsetOf_GetBooleanv_header_not_0); -COMPILE_ASSERT(offsetof(GetBooleanv, pname) == 4, - OffsetOf_GetBooleanv_pname_not_4); -COMPILE_ASSERT(offsetof(GetBooleanv, params_shm_id) == 8, - OffsetOf_GetBooleanv_params_shm_id_not_8); -COMPILE_ASSERT(offsetof(GetBooleanv, params_shm_offset) == 12, - OffsetOf_GetBooleanv_params_shm_offset_not_12); +static_assert(sizeof(GetBooleanv) == 16, "size of GetBooleanv should be 16"); +static_assert(offsetof(GetBooleanv, header) == 0, + "offset of GetBooleanv header should be 0"); +static_assert(offsetof(GetBooleanv, pname) == 4, + "offset of GetBooleanv pname should be 4"); +static_assert(offsetof(GetBooleanv, params_shm_id) == 8, + "offset of GetBooleanv params_shm_id should be 8"); +static_assert(offsetof(GetBooleanv, params_shm_offset) == 12, + "offset of GetBooleanv params_shm_offset should be 12"); struct GetBufferParameteriv { typedef GetBufferParameteriv ValueType; @@ -2722,18 +4178,18 @@ struct GetBufferParameteriv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetBufferParameteriv) == 20, - Sizeof_GetBufferParameteriv_is_not_20); -COMPILE_ASSERT(offsetof(GetBufferParameteriv, header) == 0, - OffsetOf_GetBufferParameteriv_header_not_0); -COMPILE_ASSERT(offsetof(GetBufferParameteriv, target) == 4, - OffsetOf_GetBufferParameteriv_target_not_4); -COMPILE_ASSERT(offsetof(GetBufferParameteriv, pname) == 8, - OffsetOf_GetBufferParameteriv_pname_not_8); -COMPILE_ASSERT(offsetof(GetBufferParameteriv, params_shm_id) == 12, - OffsetOf_GetBufferParameteriv_params_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetBufferParameteriv, params_shm_offset) == 16, - OffsetOf_GetBufferParameteriv_params_shm_offset_not_16); +static_assert(sizeof(GetBufferParameteriv) == 20, + "size of GetBufferParameteriv should be 20"); +static_assert(offsetof(GetBufferParameteriv, header) == 0, + "offset of GetBufferParameteriv header should be 0"); +static_assert(offsetof(GetBufferParameteriv, target) == 4, + "offset of GetBufferParameteriv target should be 4"); +static_assert(offsetof(GetBufferParameteriv, pname) == 8, + "offset of GetBufferParameteriv pname should be 8"); +static_assert(offsetof(GetBufferParameteriv, params_shm_id) == 12, + "offset of GetBufferParameteriv params_shm_id should be 12"); +static_assert(offsetof(GetBufferParameteriv, params_shm_offset) == 16, + "offset of GetBufferParameteriv params_shm_offset should be 16"); struct GetError { typedef GetError ValueType; @@ -2765,12 +4221,13 @@ struct GetError { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(GetError) == 12, Sizeof_GetError_is_not_12); -COMPILE_ASSERT(offsetof(GetError, header) == 0, OffsetOf_GetError_header_not_0); -COMPILE_ASSERT(offsetof(GetError, result_shm_id) == 4, - OffsetOf_GetError_result_shm_id_not_4); -COMPILE_ASSERT(offsetof(GetError, result_shm_offset) == 8, - OffsetOf_GetError_result_shm_offset_not_8); +static_assert(sizeof(GetError) == 12, "size of GetError should be 12"); +static_assert(offsetof(GetError, header) == 0, + "offset of GetError header should be 0"); +static_assert(offsetof(GetError, result_shm_id) == 4, + "offset of GetError result_shm_id should be 4"); +static_assert(offsetof(GetError, result_shm_offset) == 8, + "offset of GetError result_shm_offset should be 8"); struct GetFloatv { typedef GetFloatv ValueType; @@ -2810,14 +4267,70 @@ struct GetFloatv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetFloatv) == 16, Sizeof_GetFloatv_is_not_16); -COMPILE_ASSERT(offsetof(GetFloatv, header) == 0, - OffsetOf_GetFloatv_header_not_0); -COMPILE_ASSERT(offsetof(GetFloatv, pname) == 4, OffsetOf_GetFloatv_pname_not_4); -COMPILE_ASSERT(offsetof(GetFloatv, params_shm_id) == 8, - OffsetOf_GetFloatv_params_shm_id_not_8); -COMPILE_ASSERT(offsetof(GetFloatv, params_shm_offset) == 12, - OffsetOf_GetFloatv_params_shm_offset_not_12); +static_assert(sizeof(GetFloatv) == 16, "size of GetFloatv should be 16"); +static_assert(offsetof(GetFloatv, header) == 0, + "offset of GetFloatv header should be 0"); +static_assert(offsetof(GetFloatv, pname) == 4, + "offset of GetFloatv pname should be 4"); +static_assert(offsetof(GetFloatv, params_shm_id) == 8, + "offset of GetFloatv params_shm_id should be 8"); +static_assert(offsetof(GetFloatv, params_shm_offset) == 12, + "offset of GetFloatv params_shm_offset should be 12"); + +struct GetFragDataLocation { + typedef GetFragDataLocation ValueType; + static const CommandId kCmdId = kGetFragDataLocation; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef GLint Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + uint32_t _name_bucket_id, + uint32_t _location_shm_id, + uint32_t _location_shm_offset) { + SetHeader(); + program = _program; + name_bucket_id = _name_bucket_id; + location_shm_id = _location_shm_id; + location_shm_offset = _location_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + uint32_t _name_bucket_id, + uint32_t _location_shm_id, + uint32_t _location_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_program, _name_bucket_id, + _location_shm_id, _location_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t name_bucket_id; + uint32_t location_shm_id; + uint32_t location_shm_offset; +}; + +static_assert(sizeof(GetFragDataLocation) == 20, + "size of GetFragDataLocation should be 20"); +static_assert(offsetof(GetFragDataLocation, header) == 0, + "offset of GetFragDataLocation header should be 0"); +static_assert(offsetof(GetFragDataLocation, program) == 4, + "offset of GetFragDataLocation program should be 4"); +static_assert(offsetof(GetFragDataLocation, name_bucket_id) == 8, + "offset of GetFragDataLocation name_bucket_id should be 8"); +static_assert(offsetof(GetFragDataLocation, location_shm_id) == 12, + "offset of GetFragDataLocation location_shm_id should be 12"); +static_assert(offsetof(GetFragDataLocation, location_shm_offset) == 16, + "offset of GetFragDataLocation location_shm_offset should be 16"); struct GetFramebufferAttachmentParameteriv { typedef GetFramebufferAttachmentParameteriv ValueType; @@ -2865,22 +4378,186 @@ struct GetFramebufferAttachmentParameteriv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetFramebufferAttachmentParameteriv) == 24, - Sizeof_GetFramebufferAttachmentParameteriv_is_not_24); -COMPILE_ASSERT(offsetof(GetFramebufferAttachmentParameteriv, header) == 0, - OffsetOf_GetFramebufferAttachmentParameteriv_header_not_0); -COMPILE_ASSERT(offsetof(GetFramebufferAttachmentParameteriv, target) == 4, - OffsetOf_GetFramebufferAttachmentParameteriv_target_not_4); -COMPILE_ASSERT(offsetof(GetFramebufferAttachmentParameteriv, attachment) == 8, - OffsetOf_GetFramebufferAttachmentParameteriv_attachment_not_8); -COMPILE_ASSERT(offsetof(GetFramebufferAttachmentParameteriv, pname) == 12, - OffsetOf_GetFramebufferAttachmentParameteriv_pname_not_12); -COMPILE_ASSERT( +static_assert(sizeof(GetFramebufferAttachmentParameteriv) == 24, + "size of GetFramebufferAttachmentParameteriv should be 24"); +static_assert( + offsetof(GetFramebufferAttachmentParameteriv, header) == 0, + "offset of GetFramebufferAttachmentParameteriv header should be 0"); +static_assert( + offsetof(GetFramebufferAttachmentParameteriv, target) == 4, + "offset of GetFramebufferAttachmentParameteriv target should be 4"); +static_assert( + offsetof(GetFramebufferAttachmentParameteriv, attachment) == 8, + "offset of GetFramebufferAttachmentParameteriv attachment should be 8"); +static_assert( + offsetof(GetFramebufferAttachmentParameteriv, pname) == 12, + "offset of GetFramebufferAttachmentParameteriv pname should be 12"); +static_assert( offsetof(GetFramebufferAttachmentParameteriv, params_shm_id) == 16, - OffsetOf_GetFramebufferAttachmentParameteriv_params_shm_id_not_16); -COMPILE_ASSERT( - offsetof(GetFramebufferAttachmentParameteriv, params_shm_offset) == 20, - OffsetOf_GetFramebufferAttachmentParameteriv_params_shm_offset_not_20); + "offset of GetFramebufferAttachmentParameteriv params_shm_id should be 16"); +static_assert(offsetof(GetFramebufferAttachmentParameteriv, + params_shm_offset) == 20, + "offset of GetFramebufferAttachmentParameteriv params_shm_offset " + "should be 20"); + +struct GetInteger64v { + typedef GetInteger64v ValueType; + static const CommandId kCmdId = kGetInteger64v; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLint64> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + SetHeader(); + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set(void* cmd, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t pname; + uint32_t params_shm_id; + uint32_t params_shm_offset; +}; + +static_assert(sizeof(GetInteger64v) == 16, + "size of GetInteger64v should be 16"); +static_assert(offsetof(GetInteger64v, header) == 0, + "offset of GetInteger64v header should be 0"); +static_assert(offsetof(GetInteger64v, pname) == 4, + "offset of GetInteger64v pname should be 4"); +static_assert(offsetof(GetInteger64v, params_shm_id) == 8, + "offset of GetInteger64v params_shm_id should be 8"); +static_assert(offsetof(GetInteger64v, params_shm_offset) == 12, + "offset of GetInteger64v params_shm_offset should be 12"); + +struct GetIntegeri_v { + typedef GetIntegeri_v ValueType; + static const CommandId kCmdId = kGetIntegeri_v; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLint> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _pname, + GLuint _index, + uint32_t _data_shm_id, + uint32_t _data_shm_offset) { + SetHeader(); + pname = _pname; + index = _index; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + } + + void* Set(void* cmd, + GLenum _pname, + GLuint _index, + uint32_t _data_shm_id, + uint32_t _data_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_pname, _index, _data_shm_id, _data_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t pname; + uint32_t index; + uint32_t data_shm_id; + uint32_t data_shm_offset; +}; + +static_assert(sizeof(GetIntegeri_v) == 20, + "size of GetIntegeri_v should be 20"); +static_assert(offsetof(GetIntegeri_v, header) == 0, + "offset of GetIntegeri_v header should be 0"); +static_assert(offsetof(GetIntegeri_v, pname) == 4, + "offset of GetIntegeri_v pname should be 4"); +static_assert(offsetof(GetIntegeri_v, index) == 8, + "offset of GetIntegeri_v index should be 8"); +static_assert(offsetof(GetIntegeri_v, data_shm_id) == 12, + "offset of GetIntegeri_v data_shm_id should be 12"); +static_assert(offsetof(GetIntegeri_v, data_shm_offset) == 16, + "offset of GetIntegeri_v data_shm_offset should be 16"); + +struct GetInteger64i_v { + typedef GetInteger64i_v ValueType; + static const CommandId kCmdId = kGetInteger64i_v; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLint64> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _pname, + GLuint _index, + uint32_t _data_shm_id, + uint32_t _data_shm_offset) { + SetHeader(); + pname = _pname; + index = _index; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + } + + void* Set(void* cmd, + GLenum _pname, + GLuint _index, + uint32_t _data_shm_id, + uint32_t _data_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_pname, _index, _data_shm_id, _data_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t pname; + uint32_t index; + uint32_t data_shm_id; + uint32_t data_shm_offset; +}; + +static_assert(sizeof(GetInteger64i_v) == 20, + "size of GetInteger64i_v should be 20"); +static_assert(offsetof(GetInteger64i_v, header) == 0, + "offset of GetInteger64i_v header should be 0"); +static_assert(offsetof(GetInteger64i_v, pname) == 4, + "offset of GetInteger64i_v pname should be 4"); +static_assert(offsetof(GetInteger64i_v, index) == 8, + "offset of GetInteger64i_v index should be 8"); +static_assert(offsetof(GetInteger64i_v, data_shm_id) == 12, + "offset of GetInteger64i_v data_shm_id should be 12"); +static_assert(offsetof(GetInteger64i_v, data_shm_offset) == 16, + "offset of GetInteger64i_v data_shm_offset should be 16"); struct GetIntegerv { typedef GetIntegerv ValueType; @@ -2920,15 +4597,82 @@ struct GetIntegerv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetIntegerv) == 16, Sizeof_GetIntegerv_is_not_16); -COMPILE_ASSERT(offsetof(GetIntegerv, header) == 0, - OffsetOf_GetIntegerv_header_not_0); -COMPILE_ASSERT(offsetof(GetIntegerv, pname) == 4, - OffsetOf_GetIntegerv_pname_not_4); -COMPILE_ASSERT(offsetof(GetIntegerv, params_shm_id) == 8, - OffsetOf_GetIntegerv_params_shm_id_not_8); -COMPILE_ASSERT(offsetof(GetIntegerv, params_shm_offset) == 12, - OffsetOf_GetIntegerv_params_shm_offset_not_12); +static_assert(sizeof(GetIntegerv) == 16, "size of GetIntegerv should be 16"); +static_assert(offsetof(GetIntegerv, header) == 0, + "offset of GetIntegerv header should be 0"); +static_assert(offsetof(GetIntegerv, pname) == 4, + "offset of GetIntegerv pname should be 4"); +static_assert(offsetof(GetIntegerv, params_shm_id) == 8, + "offset of GetIntegerv params_shm_id should be 8"); +static_assert(offsetof(GetIntegerv, params_shm_offset) == 12, + "offset of GetIntegerv params_shm_offset should be 12"); + +struct GetInternalformativ { + typedef GetInternalformativ ValueType; + static const CommandId kCmdId = kGetInternalformativ; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLint> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLenum _format, + GLenum _pname, + GLsizei _bufSize, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + SetHeader(); + target = _target; + format = _format; + pname = _pname; + bufSize = _bufSize; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set(void* cmd, + GLenum _target, + GLenum _format, + GLenum _pname, + GLsizei _bufSize, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_target, _format, _pname, _bufSize, + _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + uint32_t format; + uint32_t pname; + int32_t bufSize; + uint32_t params_shm_id; + uint32_t params_shm_offset; +}; + +static_assert(sizeof(GetInternalformativ) == 28, + "size of GetInternalformativ should be 28"); +static_assert(offsetof(GetInternalformativ, header) == 0, + "offset of GetInternalformativ header should be 0"); +static_assert(offsetof(GetInternalformativ, target) == 4, + "offset of GetInternalformativ target should be 4"); +static_assert(offsetof(GetInternalformativ, format) == 8, + "offset of GetInternalformativ format should be 8"); +static_assert(offsetof(GetInternalformativ, pname) == 12, + "offset of GetInternalformativ pname should be 12"); +static_assert(offsetof(GetInternalformativ, bufSize) == 16, + "offset of GetInternalformativ bufSize should be 16"); +static_assert(offsetof(GetInternalformativ, params_shm_id) == 20, + "offset of GetInternalformativ params_shm_id should be 20"); +static_assert(offsetof(GetInternalformativ, params_shm_offset) == 24, + "offset of GetInternalformativ params_shm_offset should be 24"); struct GetProgramiv { typedef GetProgramiv ValueType; @@ -2972,17 +4716,17 @@ struct GetProgramiv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetProgramiv) == 20, Sizeof_GetProgramiv_is_not_20); -COMPILE_ASSERT(offsetof(GetProgramiv, header) == 0, - OffsetOf_GetProgramiv_header_not_0); -COMPILE_ASSERT(offsetof(GetProgramiv, program) == 4, - OffsetOf_GetProgramiv_program_not_4); -COMPILE_ASSERT(offsetof(GetProgramiv, pname) == 8, - OffsetOf_GetProgramiv_pname_not_8); -COMPILE_ASSERT(offsetof(GetProgramiv, params_shm_id) == 12, - OffsetOf_GetProgramiv_params_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetProgramiv, params_shm_offset) == 16, - OffsetOf_GetProgramiv_params_shm_offset_not_16); +static_assert(sizeof(GetProgramiv) == 20, "size of GetProgramiv should be 20"); +static_assert(offsetof(GetProgramiv, header) == 0, + "offset of GetProgramiv header should be 0"); +static_assert(offsetof(GetProgramiv, program) == 4, + "offset of GetProgramiv program should be 4"); +static_assert(offsetof(GetProgramiv, pname) == 8, + "offset of GetProgramiv pname should be 8"); +static_assert(offsetof(GetProgramiv, params_shm_id) == 12, + "offset of GetProgramiv params_shm_id should be 12"); +static_assert(offsetof(GetProgramiv, params_shm_offset) == 16, + "offset of GetProgramiv params_shm_offset should be 16"); struct GetProgramInfoLog { typedef GetProgramInfoLog ValueType; @@ -3012,14 +4756,14 @@ struct GetProgramInfoLog { uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(GetProgramInfoLog) == 12, - Sizeof_GetProgramInfoLog_is_not_12); -COMPILE_ASSERT(offsetof(GetProgramInfoLog, header) == 0, - OffsetOf_GetProgramInfoLog_header_not_0); -COMPILE_ASSERT(offsetof(GetProgramInfoLog, program) == 4, - OffsetOf_GetProgramInfoLog_program_not_4); -COMPILE_ASSERT(offsetof(GetProgramInfoLog, bucket_id) == 8, - OffsetOf_GetProgramInfoLog_bucket_id_not_8); +static_assert(sizeof(GetProgramInfoLog) == 12, + "size of GetProgramInfoLog should be 12"); +static_assert(offsetof(GetProgramInfoLog, header) == 0, + "offset of GetProgramInfoLog header should be 0"); +static_assert(offsetof(GetProgramInfoLog, program) == 4, + "offset of GetProgramInfoLog program should be 4"); +static_assert(offsetof(GetProgramInfoLog, bucket_id) == 8, + "offset of GetProgramInfoLog bucket_id should be 8"); struct GetRenderbufferParameteriv { typedef GetRenderbufferParameteriv ValueType; @@ -3063,18 +4807,130 @@ struct GetRenderbufferParameteriv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetRenderbufferParameteriv) == 20, - Sizeof_GetRenderbufferParameteriv_is_not_20); -COMPILE_ASSERT(offsetof(GetRenderbufferParameteriv, header) == 0, - OffsetOf_GetRenderbufferParameteriv_header_not_0); -COMPILE_ASSERT(offsetof(GetRenderbufferParameteriv, target) == 4, - OffsetOf_GetRenderbufferParameteriv_target_not_4); -COMPILE_ASSERT(offsetof(GetRenderbufferParameteriv, pname) == 8, - OffsetOf_GetRenderbufferParameteriv_pname_not_8); -COMPILE_ASSERT(offsetof(GetRenderbufferParameteriv, params_shm_id) == 12, - OffsetOf_GetRenderbufferParameteriv_params_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetRenderbufferParameteriv, params_shm_offset) == 16, - OffsetOf_GetRenderbufferParameteriv_params_shm_offset_not_16); +static_assert(sizeof(GetRenderbufferParameteriv) == 20, + "size of GetRenderbufferParameteriv should be 20"); +static_assert(offsetof(GetRenderbufferParameteriv, header) == 0, + "offset of GetRenderbufferParameteriv header should be 0"); +static_assert(offsetof(GetRenderbufferParameteriv, target) == 4, + "offset of GetRenderbufferParameteriv target should be 4"); +static_assert(offsetof(GetRenderbufferParameteriv, pname) == 8, + "offset of GetRenderbufferParameteriv pname should be 8"); +static_assert( + offsetof(GetRenderbufferParameteriv, params_shm_id) == 12, + "offset of GetRenderbufferParameteriv params_shm_id should be 12"); +static_assert( + offsetof(GetRenderbufferParameteriv, params_shm_offset) == 16, + "offset of GetRenderbufferParameteriv params_shm_offset should be 16"); + +struct GetSamplerParameterfv { + typedef GetSamplerParameterfv ValueType; + static const CommandId kCmdId = kGetSamplerParameterfv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLfloat> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _sampler, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + SetHeader(); + sampler = _sampler; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set(void* cmd, + GLuint _sampler, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_sampler, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t sampler; + uint32_t pname; + uint32_t params_shm_id; + uint32_t params_shm_offset; +}; + +static_assert(sizeof(GetSamplerParameterfv) == 20, + "size of GetSamplerParameterfv should be 20"); +static_assert(offsetof(GetSamplerParameterfv, header) == 0, + "offset of GetSamplerParameterfv header should be 0"); +static_assert(offsetof(GetSamplerParameterfv, sampler) == 4, + "offset of GetSamplerParameterfv sampler should be 4"); +static_assert(offsetof(GetSamplerParameterfv, pname) == 8, + "offset of GetSamplerParameterfv pname should be 8"); +static_assert(offsetof(GetSamplerParameterfv, params_shm_id) == 12, + "offset of GetSamplerParameterfv params_shm_id should be 12"); +static_assert(offsetof(GetSamplerParameterfv, params_shm_offset) == 16, + "offset of GetSamplerParameterfv params_shm_offset should be 16"); + +struct GetSamplerParameteriv { + typedef GetSamplerParameteriv ValueType; + static const CommandId kCmdId = kGetSamplerParameteriv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLint> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _sampler, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + SetHeader(); + sampler = _sampler; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set(void* cmd, + GLuint _sampler, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_sampler, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t sampler; + uint32_t pname; + uint32_t params_shm_id; + uint32_t params_shm_offset; +}; + +static_assert(sizeof(GetSamplerParameteriv) == 20, + "size of GetSamplerParameteriv should be 20"); +static_assert(offsetof(GetSamplerParameteriv, header) == 0, + "offset of GetSamplerParameteriv header should be 0"); +static_assert(offsetof(GetSamplerParameteriv, sampler) == 4, + "offset of GetSamplerParameteriv sampler should be 4"); +static_assert(offsetof(GetSamplerParameteriv, pname) == 8, + "offset of GetSamplerParameteriv pname should be 8"); +static_assert(offsetof(GetSamplerParameteriv, params_shm_id) == 12, + "offset of GetSamplerParameteriv params_shm_id should be 12"); +static_assert(offsetof(GetSamplerParameteriv, params_shm_offset) == 16, + "offset of GetSamplerParameteriv params_shm_offset should be 16"); struct GetShaderiv { typedef GetShaderiv ValueType; @@ -3118,17 +4974,17 @@ struct GetShaderiv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetShaderiv) == 20, Sizeof_GetShaderiv_is_not_20); -COMPILE_ASSERT(offsetof(GetShaderiv, header) == 0, - OffsetOf_GetShaderiv_header_not_0); -COMPILE_ASSERT(offsetof(GetShaderiv, shader) == 4, - OffsetOf_GetShaderiv_shader_not_4); -COMPILE_ASSERT(offsetof(GetShaderiv, pname) == 8, - OffsetOf_GetShaderiv_pname_not_8); -COMPILE_ASSERT(offsetof(GetShaderiv, params_shm_id) == 12, - OffsetOf_GetShaderiv_params_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetShaderiv, params_shm_offset) == 16, - OffsetOf_GetShaderiv_params_shm_offset_not_16); +static_assert(sizeof(GetShaderiv) == 20, "size of GetShaderiv should be 20"); +static_assert(offsetof(GetShaderiv, header) == 0, + "offset of GetShaderiv header should be 0"); +static_assert(offsetof(GetShaderiv, shader) == 4, + "offset of GetShaderiv shader should be 4"); +static_assert(offsetof(GetShaderiv, pname) == 8, + "offset of GetShaderiv pname should be 8"); +static_assert(offsetof(GetShaderiv, params_shm_id) == 12, + "offset of GetShaderiv params_shm_id should be 12"); +static_assert(offsetof(GetShaderiv, params_shm_offset) == 16, + "offset of GetShaderiv params_shm_offset should be 16"); struct GetShaderInfoLog { typedef GetShaderInfoLog ValueType; @@ -3158,14 +5014,14 @@ struct GetShaderInfoLog { uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(GetShaderInfoLog) == 12, - Sizeof_GetShaderInfoLog_is_not_12); -COMPILE_ASSERT(offsetof(GetShaderInfoLog, header) == 0, - OffsetOf_GetShaderInfoLog_header_not_0); -COMPILE_ASSERT(offsetof(GetShaderInfoLog, shader) == 4, - OffsetOf_GetShaderInfoLog_shader_not_4); -COMPILE_ASSERT(offsetof(GetShaderInfoLog, bucket_id) == 8, - OffsetOf_GetShaderInfoLog_bucket_id_not_8); +static_assert(sizeof(GetShaderInfoLog) == 12, + "size of GetShaderInfoLog should be 12"); +static_assert(offsetof(GetShaderInfoLog, header) == 0, + "offset of GetShaderInfoLog header should be 0"); +static_assert(offsetof(GetShaderInfoLog, shader) == 4, + "offset of GetShaderInfoLog shader should be 4"); +static_assert(offsetof(GetShaderInfoLog, bucket_id) == 8, + "offset of GetShaderInfoLog bucket_id should be 8"); struct GetShaderPrecisionFormat { typedef GetShaderPrecisionFormat ValueType; @@ -3214,26 +5070,31 @@ struct GetShaderPrecisionFormat { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(GetShaderPrecisionFormat) == 20, - Sizeof_GetShaderPrecisionFormat_is_not_20); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, header) == 0, - OffsetOf_GetShaderPrecisionFormat_header_not_0); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, shadertype) == 4, - OffsetOf_GetShaderPrecisionFormat_shadertype_not_4); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, precisiontype) == 8, - OffsetOf_GetShaderPrecisionFormat_precisiontype_not_8); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, result_shm_id) == 12, - OffsetOf_GetShaderPrecisionFormat_result_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, result_shm_offset) == 16, - OffsetOf_GetShaderPrecisionFormat_result_shm_offset_not_16); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat::Result, success) == 0, - OffsetOf_GetShaderPrecisionFormat_Result_success_not_0); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat::Result, min_range) == 4, - OffsetOf_GetShaderPrecisionFormat_Result_min_range_not_4); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat::Result, max_range) == 8, - OffsetOf_GetShaderPrecisionFormat_Result_max_range_not_8); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat::Result, precision) == 12, - OffsetOf_GetShaderPrecisionFormat_Result_precision_not_12); +static_assert(sizeof(GetShaderPrecisionFormat) == 20, + "size of GetShaderPrecisionFormat should be 20"); +static_assert(offsetof(GetShaderPrecisionFormat, header) == 0, + "offset of GetShaderPrecisionFormat header should be 0"); +static_assert(offsetof(GetShaderPrecisionFormat, shadertype) == 4, + "offset of GetShaderPrecisionFormat shadertype should be 4"); +static_assert(offsetof(GetShaderPrecisionFormat, precisiontype) == 8, + "offset of GetShaderPrecisionFormat precisiontype should be 8"); +static_assert(offsetof(GetShaderPrecisionFormat, result_shm_id) == 12, + "offset of GetShaderPrecisionFormat result_shm_id should be 12"); +static_assert( + offsetof(GetShaderPrecisionFormat, result_shm_offset) == 16, + "offset of GetShaderPrecisionFormat result_shm_offset should be 16"); +static_assert(offsetof(GetShaderPrecisionFormat::Result, success) == 0, + "offset of GetShaderPrecisionFormat Result success should be " + "0"); +static_assert(offsetof(GetShaderPrecisionFormat::Result, min_range) == 4, + "offset of GetShaderPrecisionFormat Result min_range should be " + "4"); +static_assert(offsetof(GetShaderPrecisionFormat::Result, max_range) == 8, + "offset of GetShaderPrecisionFormat Result max_range should be " + "8"); +static_assert(offsetof(GetShaderPrecisionFormat::Result, precision) == 12, + "offset of GetShaderPrecisionFormat Result precision should be " + "12"); struct GetShaderSource { typedef GetShaderSource ValueType; @@ -3263,13 +5124,14 @@ struct GetShaderSource { uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(GetShaderSource) == 12, Sizeof_GetShaderSource_is_not_12); -COMPILE_ASSERT(offsetof(GetShaderSource, header) == 0, - OffsetOf_GetShaderSource_header_not_0); -COMPILE_ASSERT(offsetof(GetShaderSource, shader) == 4, - OffsetOf_GetShaderSource_shader_not_4); -COMPILE_ASSERT(offsetof(GetShaderSource, bucket_id) == 8, - OffsetOf_GetShaderSource_bucket_id_not_8); +static_assert(sizeof(GetShaderSource) == 12, + "size of GetShaderSource should be 12"); +static_assert(offsetof(GetShaderSource, header) == 0, + "offset of GetShaderSource header should be 0"); +static_assert(offsetof(GetShaderSource, shader) == 4, + "offset of GetShaderSource shader should be 4"); +static_assert(offsetof(GetShaderSource, bucket_id) == 8, + "offset of GetShaderSource bucket_id should be 8"); struct GetString { typedef GetString ValueType; @@ -3299,12 +5161,67 @@ struct GetString { uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(GetString) == 12, Sizeof_GetString_is_not_12); -COMPILE_ASSERT(offsetof(GetString, header) == 0, - OffsetOf_GetString_header_not_0); -COMPILE_ASSERT(offsetof(GetString, name) == 4, OffsetOf_GetString_name_not_4); -COMPILE_ASSERT(offsetof(GetString, bucket_id) == 8, - OffsetOf_GetString_bucket_id_not_8); +static_assert(sizeof(GetString) == 12, "size of GetString should be 12"); +static_assert(offsetof(GetString, header) == 0, + "offset of GetString header should be 0"); +static_assert(offsetof(GetString, name) == 4, + "offset of GetString name should be 4"); +static_assert(offsetof(GetString, bucket_id) == 8, + "offset of GetString bucket_id should be 8"); + +struct GetSynciv { + typedef GetSynciv ValueType; + static const CommandId kCmdId = kGetSynciv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLint> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _sync, + GLenum _pname, + uint32_t _values_shm_id, + uint32_t _values_shm_offset) { + SetHeader(); + sync = _sync; + pname = _pname; + values_shm_id = _values_shm_id; + values_shm_offset = _values_shm_offset; + } + + void* Set(void* cmd, + GLuint _sync, + GLenum _pname, + uint32_t _values_shm_id, + uint32_t _values_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_sync, _pname, _values_shm_id, _values_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t sync; + uint32_t pname; + uint32_t values_shm_id; + uint32_t values_shm_offset; +}; + +static_assert(sizeof(GetSynciv) == 20, "size of GetSynciv should be 20"); +static_assert(offsetof(GetSynciv, header) == 0, + "offset of GetSynciv header should be 0"); +static_assert(offsetof(GetSynciv, sync) == 4, + "offset of GetSynciv sync should be 4"); +static_assert(offsetof(GetSynciv, pname) == 8, + "offset of GetSynciv pname should be 8"); +static_assert(offsetof(GetSynciv, values_shm_id) == 12, + "offset of GetSynciv values_shm_id should be 12"); +static_assert(offsetof(GetSynciv, values_shm_offset) == 16, + "offset of GetSynciv values_shm_offset should be 16"); struct GetTexParameterfv { typedef GetTexParameterfv ValueType; @@ -3348,18 +5265,18 @@ struct GetTexParameterfv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetTexParameterfv) == 20, - Sizeof_GetTexParameterfv_is_not_20); -COMPILE_ASSERT(offsetof(GetTexParameterfv, header) == 0, - OffsetOf_GetTexParameterfv_header_not_0); -COMPILE_ASSERT(offsetof(GetTexParameterfv, target) == 4, - OffsetOf_GetTexParameterfv_target_not_4); -COMPILE_ASSERT(offsetof(GetTexParameterfv, pname) == 8, - OffsetOf_GetTexParameterfv_pname_not_8); -COMPILE_ASSERT(offsetof(GetTexParameterfv, params_shm_id) == 12, - OffsetOf_GetTexParameterfv_params_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetTexParameterfv, params_shm_offset) == 16, - OffsetOf_GetTexParameterfv_params_shm_offset_not_16); +static_assert(sizeof(GetTexParameterfv) == 20, + "size of GetTexParameterfv should be 20"); +static_assert(offsetof(GetTexParameterfv, header) == 0, + "offset of GetTexParameterfv header should be 0"); +static_assert(offsetof(GetTexParameterfv, target) == 4, + "offset of GetTexParameterfv target should be 4"); +static_assert(offsetof(GetTexParameterfv, pname) == 8, + "offset of GetTexParameterfv pname should be 8"); +static_assert(offsetof(GetTexParameterfv, params_shm_id) == 12, + "offset of GetTexParameterfv params_shm_id should be 12"); +static_assert(offsetof(GetTexParameterfv, params_shm_offset) == 16, + "offset of GetTexParameterfv params_shm_offset should be 16"); struct GetTexParameteriv { typedef GetTexParameteriv ValueType; @@ -3403,18 +5320,150 @@ struct GetTexParameteriv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetTexParameteriv) == 20, - Sizeof_GetTexParameteriv_is_not_20); -COMPILE_ASSERT(offsetof(GetTexParameteriv, header) == 0, - OffsetOf_GetTexParameteriv_header_not_0); -COMPILE_ASSERT(offsetof(GetTexParameteriv, target) == 4, - OffsetOf_GetTexParameteriv_target_not_4); -COMPILE_ASSERT(offsetof(GetTexParameteriv, pname) == 8, - OffsetOf_GetTexParameteriv_pname_not_8); -COMPILE_ASSERT(offsetof(GetTexParameteriv, params_shm_id) == 12, - OffsetOf_GetTexParameteriv_params_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetTexParameteriv, params_shm_offset) == 16, - OffsetOf_GetTexParameteriv_params_shm_offset_not_16); +static_assert(sizeof(GetTexParameteriv) == 20, + "size of GetTexParameteriv should be 20"); +static_assert(offsetof(GetTexParameteriv, header) == 0, + "offset of GetTexParameteriv header should be 0"); +static_assert(offsetof(GetTexParameteriv, target) == 4, + "offset of GetTexParameteriv target should be 4"); +static_assert(offsetof(GetTexParameteriv, pname) == 8, + "offset of GetTexParameteriv pname should be 8"); +static_assert(offsetof(GetTexParameteriv, params_shm_id) == 12, + "offset of GetTexParameteriv params_shm_id should be 12"); +static_assert(offsetof(GetTexParameteriv, params_shm_offset) == 16, + "offset of GetTexParameteriv params_shm_offset should be 16"); + +struct GetTransformFeedbackVarying { + typedef GetTransformFeedbackVarying ValueType; + static const CommandId kCmdId = kGetTransformFeedbackVarying; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + struct Result { + int32_t success; + int32_t size; + uint32_t type; + }; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + GLuint _index, + uint32_t _name_bucket_id, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + SetHeader(); + program = _program; + index = _index; + name_bucket_id = _name_bucket_id; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + GLuint _index, + uint32_t _name_bucket_id, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_program, _index, _name_bucket_id, + _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t index; + uint32_t name_bucket_id; + uint32_t result_shm_id; + uint32_t result_shm_offset; +}; + +static_assert(sizeof(GetTransformFeedbackVarying) == 24, + "size of GetTransformFeedbackVarying should be 24"); +static_assert(offsetof(GetTransformFeedbackVarying, header) == 0, + "offset of GetTransformFeedbackVarying header should be 0"); +static_assert(offsetof(GetTransformFeedbackVarying, program) == 4, + "offset of GetTransformFeedbackVarying program should be 4"); +static_assert(offsetof(GetTransformFeedbackVarying, index) == 8, + "offset of GetTransformFeedbackVarying index should be 8"); +static_assert( + offsetof(GetTransformFeedbackVarying, name_bucket_id) == 12, + "offset of GetTransformFeedbackVarying name_bucket_id should be 12"); +static_assert( + offsetof(GetTransformFeedbackVarying, result_shm_id) == 16, + "offset of GetTransformFeedbackVarying result_shm_id should be 16"); +static_assert( + offsetof(GetTransformFeedbackVarying, result_shm_offset) == 20, + "offset of GetTransformFeedbackVarying result_shm_offset should be 20"); +static_assert(offsetof(GetTransformFeedbackVarying::Result, success) == 0, + "offset of GetTransformFeedbackVarying Result success should be " + "0"); +static_assert(offsetof(GetTransformFeedbackVarying::Result, size) == 4, + "offset of GetTransformFeedbackVarying Result size should be " + "4"); +static_assert(offsetof(GetTransformFeedbackVarying::Result, type) == 8, + "offset of GetTransformFeedbackVarying Result type should be " + "8"); + +struct GetUniformBlockIndex { + typedef GetUniformBlockIndex ValueType; + static const CommandId kCmdId = kGetUniformBlockIndex; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef GLuint Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + uint32_t _name_bucket_id, + uint32_t _index_shm_id, + uint32_t _index_shm_offset) { + SetHeader(); + program = _program; + name_bucket_id = _name_bucket_id; + index_shm_id = _index_shm_id; + index_shm_offset = _index_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + uint32_t _name_bucket_id, + uint32_t _index_shm_id, + uint32_t _index_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_program, _name_bucket_id, _index_shm_id, _index_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t name_bucket_id; + uint32_t index_shm_id; + uint32_t index_shm_offset; +}; + +static_assert(sizeof(GetUniformBlockIndex) == 20, + "size of GetUniformBlockIndex should be 20"); +static_assert(offsetof(GetUniformBlockIndex, header) == 0, + "offset of GetUniformBlockIndex header should be 0"); +static_assert(offsetof(GetUniformBlockIndex, program) == 4, + "offset of GetUniformBlockIndex program should be 4"); +static_assert(offsetof(GetUniformBlockIndex, name_bucket_id) == 8, + "offset of GetUniformBlockIndex name_bucket_id should be 8"); +static_assert(offsetof(GetUniformBlockIndex, index_shm_id) == 12, + "offset of GetUniformBlockIndex index_shm_id should be 12"); +static_assert(offsetof(GetUniformBlockIndex, index_shm_offset) == 16, + "offset of GetUniformBlockIndex index_shm_offset should be 16"); struct GetUniformfv { typedef GetUniformfv ValueType; @@ -3458,17 +5507,17 @@ struct GetUniformfv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetUniformfv) == 20, Sizeof_GetUniformfv_is_not_20); -COMPILE_ASSERT(offsetof(GetUniformfv, header) == 0, - OffsetOf_GetUniformfv_header_not_0); -COMPILE_ASSERT(offsetof(GetUniformfv, program) == 4, - OffsetOf_GetUniformfv_program_not_4); -COMPILE_ASSERT(offsetof(GetUniformfv, location) == 8, - OffsetOf_GetUniformfv_location_not_8); -COMPILE_ASSERT(offsetof(GetUniformfv, params_shm_id) == 12, - OffsetOf_GetUniformfv_params_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetUniformfv, params_shm_offset) == 16, - OffsetOf_GetUniformfv_params_shm_offset_not_16); +static_assert(sizeof(GetUniformfv) == 20, "size of GetUniformfv should be 20"); +static_assert(offsetof(GetUniformfv, header) == 0, + "offset of GetUniformfv header should be 0"); +static_assert(offsetof(GetUniformfv, program) == 4, + "offset of GetUniformfv program should be 4"); +static_assert(offsetof(GetUniformfv, location) == 8, + "offset of GetUniformfv location should be 8"); +static_assert(offsetof(GetUniformfv, params_shm_id) == 12, + "offset of GetUniformfv params_shm_id should be 12"); +static_assert(offsetof(GetUniformfv, params_shm_offset) == 16, + "offset of GetUniformfv params_shm_offset should be 16"); struct GetUniformiv { typedef GetUniformiv ValueType; @@ -3512,17 +5561,127 @@ struct GetUniformiv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetUniformiv) == 20, Sizeof_GetUniformiv_is_not_20); -COMPILE_ASSERT(offsetof(GetUniformiv, header) == 0, - OffsetOf_GetUniformiv_header_not_0); -COMPILE_ASSERT(offsetof(GetUniformiv, program) == 4, - OffsetOf_GetUniformiv_program_not_4); -COMPILE_ASSERT(offsetof(GetUniformiv, location) == 8, - OffsetOf_GetUniformiv_location_not_8); -COMPILE_ASSERT(offsetof(GetUniformiv, params_shm_id) == 12, - OffsetOf_GetUniformiv_params_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetUniformiv, params_shm_offset) == 16, - OffsetOf_GetUniformiv_params_shm_offset_not_16); +static_assert(sizeof(GetUniformiv) == 20, "size of GetUniformiv should be 20"); +static_assert(offsetof(GetUniformiv, header) == 0, + "offset of GetUniformiv header should be 0"); +static_assert(offsetof(GetUniformiv, program) == 4, + "offset of GetUniformiv program should be 4"); +static_assert(offsetof(GetUniformiv, location) == 8, + "offset of GetUniformiv location should be 8"); +static_assert(offsetof(GetUniformiv, params_shm_id) == 12, + "offset of GetUniformiv params_shm_id should be 12"); +static_assert(offsetof(GetUniformiv, params_shm_offset) == 16, + "offset of GetUniformiv params_shm_offset should be 16"); + +struct GetUniformuiv { + typedef GetUniformuiv ValueType; + static const CommandId kCmdId = kGetUniformuiv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLuint> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + GLint _location, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + SetHeader(); + program = _program; + location = _location; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + GLint _location, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_program, _location, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + int32_t location; + uint32_t params_shm_id; + uint32_t params_shm_offset; +}; + +static_assert(sizeof(GetUniformuiv) == 20, + "size of GetUniformuiv should be 20"); +static_assert(offsetof(GetUniformuiv, header) == 0, + "offset of GetUniformuiv header should be 0"); +static_assert(offsetof(GetUniformuiv, program) == 4, + "offset of GetUniformuiv program should be 4"); +static_assert(offsetof(GetUniformuiv, location) == 8, + "offset of GetUniformuiv location should be 8"); +static_assert(offsetof(GetUniformuiv, params_shm_id) == 12, + "offset of GetUniformuiv params_shm_id should be 12"); +static_assert(offsetof(GetUniformuiv, params_shm_offset) == 16, + "offset of GetUniformuiv params_shm_offset should be 16"); + +struct GetUniformIndices { + typedef GetUniformIndices ValueType; + static const CommandId kCmdId = kGetUniformIndices; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLuint> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + uint32_t _names_bucket_id, + uint32_t _indices_shm_id, + uint32_t _indices_shm_offset) { + SetHeader(); + program = _program; + names_bucket_id = _names_bucket_id; + indices_shm_id = _indices_shm_id; + indices_shm_offset = _indices_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + uint32_t _names_bucket_id, + uint32_t _indices_shm_id, + uint32_t _indices_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_program, _names_bucket_id, + _indices_shm_id, _indices_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t names_bucket_id; + uint32_t indices_shm_id; + uint32_t indices_shm_offset; +}; + +static_assert(sizeof(GetUniformIndices) == 20, + "size of GetUniformIndices should be 20"); +static_assert(offsetof(GetUniformIndices, header) == 0, + "offset of GetUniformIndices header should be 0"); +static_assert(offsetof(GetUniformIndices, program) == 4, + "offset of GetUniformIndices program should be 4"); +static_assert(offsetof(GetUniformIndices, names_bucket_id) == 8, + "offset of GetUniformIndices names_bucket_id should be 8"); +static_assert(offsetof(GetUniformIndices, indices_shm_id) == 12, + "offset of GetUniformIndices indices_shm_id should be 12"); +static_assert(offsetof(GetUniformIndices, indices_shm_offset) == 16, + "offset of GetUniformIndices indices_shm_offset should be 16"); struct GetUniformLocation { typedef GetUniformLocation ValueType; @@ -3566,18 +5725,18 @@ struct GetUniformLocation { uint32_t location_shm_offset; }; -COMPILE_ASSERT(sizeof(GetUniformLocation) == 20, - Sizeof_GetUniformLocation_is_not_20); -COMPILE_ASSERT(offsetof(GetUniformLocation, header) == 0, - OffsetOf_GetUniformLocation_header_not_0); -COMPILE_ASSERT(offsetof(GetUniformLocation, program) == 4, - OffsetOf_GetUniformLocation_program_not_4); -COMPILE_ASSERT(offsetof(GetUniformLocation, name_bucket_id) == 8, - OffsetOf_GetUniformLocation_name_bucket_id_not_8); -COMPILE_ASSERT(offsetof(GetUniformLocation, location_shm_id) == 12, - OffsetOf_GetUniformLocation_location_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetUniformLocation, location_shm_offset) == 16, - OffsetOf_GetUniformLocation_location_shm_offset_not_16); +static_assert(sizeof(GetUniformLocation) == 20, + "size of GetUniformLocation should be 20"); +static_assert(offsetof(GetUniformLocation, header) == 0, + "offset of GetUniformLocation header should be 0"); +static_assert(offsetof(GetUniformLocation, program) == 4, + "offset of GetUniformLocation program should be 4"); +static_assert(offsetof(GetUniformLocation, name_bucket_id) == 8, + "offset of GetUniformLocation name_bucket_id should be 8"); +static_assert(offsetof(GetUniformLocation, location_shm_id) == 12, + "offset of GetUniformLocation location_shm_id should be 12"); +static_assert(offsetof(GetUniformLocation, location_shm_offset) == 16, + "offset of GetUniformLocation location_shm_offset should be 16"); struct GetVertexAttribfv { typedef GetVertexAttribfv ValueType; @@ -3621,18 +5780,18 @@ struct GetVertexAttribfv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetVertexAttribfv) == 20, - Sizeof_GetVertexAttribfv_is_not_20); -COMPILE_ASSERT(offsetof(GetVertexAttribfv, header) == 0, - OffsetOf_GetVertexAttribfv_header_not_0); -COMPILE_ASSERT(offsetof(GetVertexAttribfv, index) == 4, - OffsetOf_GetVertexAttribfv_index_not_4); -COMPILE_ASSERT(offsetof(GetVertexAttribfv, pname) == 8, - OffsetOf_GetVertexAttribfv_pname_not_8); -COMPILE_ASSERT(offsetof(GetVertexAttribfv, params_shm_id) == 12, - OffsetOf_GetVertexAttribfv_params_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetVertexAttribfv, params_shm_offset) == 16, - OffsetOf_GetVertexAttribfv_params_shm_offset_not_16); +static_assert(sizeof(GetVertexAttribfv) == 20, + "size of GetVertexAttribfv should be 20"); +static_assert(offsetof(GetVertexAttribfv, header) == 0, + "offset of GetVertexAttribfv header should be 0"); +static_assert(offsetof(GetVertexAttribfv, index) == 4, + "offset of GetVertexAttribfv index should be 4"); +static_assert(offsetof(GetVertexAttribfv, pname) == 8, + "offset of GetVertexAttribfv pname should be 8"); +static_assert(offsetof(GetVertexAttribfv, params_shm_id) == 12, + "offset of GetVertexAttribfv params_shm_id should be 12"); +static_assert(offsetof(GetVertexAttribfv, params_shm_offset) == 16, + "offset of GetVertexAttribfv params_shm_offset should be 16"); struct GetVertexAttribiv { typedef GetVertexAttribiv ValueType; @@ -3676,18 +5835,128 @@ struct GetVertexAttribiv { uint32_t params_shm_offset; }; -COMPILE_ASSERT(sizeof(GetVertexAttribiv) == 20, - Sizeof_GetVertexAttribiv_is_not_20); -COMPILE_ASSERT(offsetof(GetVertexAttribiv, header) == 0, - OffsetOf_GetVertexAttribiv_header_not_0); -COMPILE_ASSERT(offsetof(GetVertexAttribiv, index) == 4, - OffsetOf_GetVertexAttribiv_index_not_4); -COMPILE_ASSERT(offsetof(GetVertexAttribiv, pname) == 8, - OffsetOf_GetVertexAttribiv_pname_not_8); -COMPILE_ASSERT(offsetof(GetVertexAttribiv, params_shm_id) == 12, - OffsetOf_GetVertexAttribiv_params_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetVertexAttribiv, params_shm_offset) == 16, - OffsetOf_GetVertexAttribiv_params_shm_offset_not_16); +static_assert(sizeof(GetVertexAttribiv) == 20, + "size of GetVertexAttribiv should be 20"); +static_assert(offsetof(GetVertexAttribiv, header) == 0, + "offset of GetVertexAttribiv header should be 0"); +static_assert(offsetof(GetVertexAttribiv, index) == 4, + "offset of GetVertexAttribiv index should be 4"); +static_assert(offsetof(GetVertexAttribiv, pname) == 8, + "offset of GetVertexAttribiv pname should be 8"); +static_assert(offsetof(GetVertexAttribiv, params_shm_id) == 12, + "offset of GetVertexAttribiv params_shm_id should be 12"); +static_assert(offsetof(GetVertexAttribiv, params_shm_offset) == 16, + "offset of GetVertexAttribiv params_shm_offset should be 16"); + +struct GetVertexAttribIiv { + typedef GetVertexAttribIiv ValueType; + static const CommandId kCmdId = kGetVertexAttribIiv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLint> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _index, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + SetHeader(); + index = _index; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set(void* cmd, + GLuint _index, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_index, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t index; + uint32_t pname; + uint32_t params_shm_id; + uint32_t params_shm_offset; +}; + +static_assert(sizeof(GetVertexAttribIiv) == 20, + "size of GetVertexAttribIiv should be 20"); +static_assert(offsetof(GetVertexAttribIiv, header) == 0, + "offset of GetVertexAttribIiv header should be 0"); +static_assert(offsetof(GetVertexAttribIiv, index) == 4, + "offset of GetVertexAttribIiv index should be 4"); +static_assert(offsetof(GetVertexAttribIiv, pname) == 8, + "offset of GetVertexAttribIiv pname should be 8"); +static_assert(offsetof(GetVertexAttribIiv, params_shm_id) == 12, + "offset of GetVertexAttribIiv params_shm_id should be 12"); +static_assert(offsetof(GetVertexAttribIiv, params_shm_offset) == 16, + "offset of GetVertexAttribIiv params_shm_offset should be 16"); + +struct GetVertexAttribIuiv { + typedef GetVertexAttribIuiv ValueType; + static const CommandId kCmdId = kGetVertexAttribIuiv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef SizedResult<GLuint> Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _index, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + SetHeader(); + index = _index; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set(void* cmd, + GLuint _index, + GLenum _pname, + uint32_t _params_shm_id, + uint32_t _params_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_index, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t index; + uint32_t pname; + uint32_t params_shm_id; + uint32_t params_shm_offset; +}; + +static_assert(sizeof(GetVertexAttribIuiv) == 20, + "size of GetVertexAttribIuiv should be 20"); +static_assert(offsetof(GetVertexAttribIuiv, header) == 0, + "offset of GetVertexAttribIuiv header should be 0"); +static_assert(offsetof(GetVertexAttribIuiv, index) == 4, + "offset of GetVertexAttribIuiv index should be 4"); +static_assert(offsetof(GetVertexAttribIuiv, pname) == 8, + "offset of GetVertexAttribIuiv pname should be 8"); +static_assert(offsetof(GetVertexAttribIuiv, params_shm_id) == 12, + "offset of GetVertexAttribIuiv params_shm_id should be 12"); +static_assert(offsetof(GetVertexAttribIuiv, params_shm_offset) == 16, + "offset of GetVertexAttribIuiv params_shm_offset should be 16"); struct GetVertexAttribPointerv { typedef GetVertexAttribPointerv ValueType; @@ -3731,18 +6000,19 @@ struct GetVertexAttribPointerv { uint32_t pointer_shm_offset; }; -COMPILE_ASSERT(sizeof(GetVertexAttribPointerv) == 20, - Sizeof_GetVertexAttribPointerv_is_not_20); -COMPILE_ASSERT(offsetof(GetVertexAttribPointerv, header) == 0, - OffsetOf_GetVertexAttribPointerv_header_not_0); -COMPILE_ASSERT(offsetof(GetVertexAttribPointerv, index) == 4, - OffsetOf_GetVertexAttribPointerv_index_not_4); -COMPILE_ASSERT(offsetof(GetVertexAttribPointerv, pname) == 8, - OffsetOf_GetVertexAttribPointerv_pname_not_8); -COMPILE_ASSERT(offsetof(GetVertexAttribPointerv, pointer_shm_id) == 12, - OffsetOf_GetVertexAttribPointerv_pointer_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetVertexAttribPointerv, pointer_shm_offset) == 16, - OffsetOf_GetVertexAttribPointerv_pointer_shm_offset_not_16); +static_assert(sizeof(GetVertexAttribPointerv) == 20, + "size of GetVertexAttribPointerv should be 20"); +static_assert(offsetof(GetVertexAttribPointerv, header) == 0, + "offset of GetVertexAttribPointerv header should be 0"); +static_assert(offsetof(GetVertexAttribPointerv, index) == 4, + "offset of GetVertexAttribPointerv index should be 4"); +static_assert(offsetof(GetVertexAttribPointerv, pname) == 8, + "offset of GetVertexAttribPointerv pname should be 8"); +static_assert(offsetof(GetVertexAttribPointerv, pointer_shm_id) == 12, + "offset of GetVertexAttribPointerv pointer_shm_id should be 12"); +static_assert( + offsetof(GetVertexAttribPointerv, pointer_shm_offset) == 16, + "offset of GetVertexAttribPointerv pointer_shm_offset should be 16"); struct Hint { typedef Hint ValueType; @@ -3772,10 +6042,136 @@ struct Hint { uint32_t mode; }; -COMPILE_ASSERT(sizeof(Hint) == 12, Sizeof_Hint_is_not_12); -COMPILE_ASSERT(offsetof(Hint, header) == 0, OffsetOf_Hint_header_not_0); -COMPILE_ASSERT(offsetof(Hint, target) == 4, OffsetOf_Hint_target_not_4); -COMPILE_ASSERT(offsetof(Hint, mode) == 8, OffsetOf_Hint_mode_not_8); +static_assert(sizeof(Hint) == 12, "size of Hint should be 12"); +static_assert(offsetof(Hint, header) == 0, "offset of Hint header should be 0"); +static_assert(offsetof(Hint, target) == 4, "offset of Hint target should be 4"); +static_assert(offsetof(Hint, mode) == 8, "offset of Hint mode should be 8"); + +struct InvalidateFramebufferImmediate { + typedef InvalidateFramebufferImmediate ValueType; + static const CommandId kCmdId = kInvalidateFramebufferImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLenum) * 1 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLenum _target, GLsizei _count, const GLenum* _attachments) { + SetHeader(_count); + target = _target; + count = _count; + memcpy(ImmediateDataAddress(this), _attachments, ComputeDataSize(_count)); + } + + void* Set(void* cmd, + GLenum _target, + GLsizei _count, + const GLenum* _attachments) { + static_cast<ValueType*>(cmd)->Init(_target, _count, _attachments); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t count; +}; + +static_assert(sizeof(InvalidateFramebufferImmediate) == 12, + "size of InvalidateFramebufferImmediate should be 12"); +static_assert(offsetof(InvalidateFramebufferImmediate, header) == 0, + "offset of InvalidateFramebufferImmediate header should be 0"); +static_assert(offsetof(InvalidateFramebufferImmediate, target) == 4, + "offset of InvalidateFramebufferImmediate target should be 4"); +static_assert(offsetof(InvalidateFramebufferImmediate, count) == 8, + "offset of InvalidateFramebufferImmediate count should be 8"); + +struct InvalidateSubFramebufferImmediate { + typedef InvalidateSubFramebufferImmediate ValueType; + static const CommandId kCmdId = kInvalidateSubFramebufferImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLenum) * 1 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLenum _target, + GLsizei _count, + const GLenum* _attachments, + GLint _x, + GLint _y, + GLsizei _width, + GLsizei _height) { + SetHeader(_count); + target = _target; + count = _count; + x = _x; + y = _y; + width = _width; + height = _height; + memcpy(ImmediateDataAddress(this), _attachments, ComputeDataSize(_count)); + } + + void* Set(void* cmd, + GLenum _target, + GLsizei _count, + const GLenum* _attachments, + GLint _x, + GLint _y, + GLsizei _width, + GLsizei _height) { + static_cast<ValueType*>(cmd) + ->Init(_target, _count, _attachments, _x, _y, _width, _height); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t count; + int32_t x; + int32_t y; + int32_t width; + int32_t height; +}; + +static_assert(sizeof(InvalidateSubFramebufferImmediate) == 28, + "size of InvalidateSubFramebufferImmediate should be 28"); +static_assert(offsetof(InvalidateSubFramebufferImmediate, header) == 0, + "offset of InvalidateSubFramebufferImmediate header should be 0"); +static_assert(offsetof(InvalidateSubFramebufferImmediate, target) == 4, + "offset of InvalidateSubFramebufferImmediate target should be 4"); +static_assert(offsetof(InvalidateSubFramebufferImmediate, count) == 8, + "offset of InvalidateSubFramebufferImmediate count should be 8"); +static_assert(offsetof(InvalidateSubFramebufferImmediate, x) == 12, + "offset of InvalidateSubFramebufferImmediate x should be 12"); +static_assert(offsetof(InvalidateSubFramebufferImmediate, y) == 16, + "offset of InvalidateSubFramebufferImmediate y should be 16"); +static_assert(offsetof(InvalidateSubFramebufferImmediate, width) == 20, + "offset of InvalidateSubFramebufferImmediate width should be 20"); +static_assert( + offsetof(InvalidateSubFramebufferImmediate, height) == 24, + "offset of InvalidateSubFramebufferImmediate height should be 24"); struct IsBuffer { typedef IsBuffer ValueType; @@ -3815,13 +6211,15 @@ struct IsBuffer { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(IsBuffer) == 16, Sizeof_IsBuffer_is_not_16); -COMPILE_ASSERT(offsetof(IsBuffer, header) == 0, OffsetOf_IsBuffer_header_not_0); -COMPILE_ASSERT(offsetof(IsBuffer, buffer) == 4, OffsetOf_IsBuffer_buffer_not_4); -COMPILE_ASSERT(offsetof(IsBuffer, result_shm_id) == 8, - OffsetOf_IsBuffer_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(IsBuffer, result_shm_offset) == 12, - OffsetOf_IsBuffer_result_shm_offset_not_12); +static_assert(sizeof(IsBuffer) == 16, "size of IsBuffer should be 16"); +static_assert(offsetof(IsBuffer, header) == 0, + "offset of IsBuffer header should be 0"); +static_assert(offsetof(IsBuffer, buffer) == 4, + "offset of IsBuffer buffer should be 4"); +static_assert(offsetof(IsBuffer, result_shm_id) == 8, + "offset of IsBuffer result_shm_id should be 8"); +static_assert(offsetof(IsBuffer, result_shm_offset) == 12, + "offset of IsBuffer result_shm_offset should be 12"); struct IsEnabled { typedef IsEnabled ValueType; @@ -3859,14 +6257,15 @@ struct IsEnabled { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(IsEnabled) == 16, Sizeof_IsEnabled_is_not_16); -COMPILE_ASSERT(offsetof(IsEnabled, header) == 0, - OffsetOf_IsEnabled_header_not_0); -COMPILE_ASSERT(offsetof(IsEnabled, cap) == 4, OffsetOf_IsEnabled_cap_not_4); -COMPILE_ASSERT(offsetof(IsEnabled, result_shm_id) == 8, - OffsetOf_IsEnabled_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(IsEnabled, result_shm_offset) == 12, - OffsetOf_IsEnabled_result_shm_offset_not_12); +static_assert(sizeof(IsEnabled) == 16, "size of IsEnabled should be 16"); +static_assert(offsetof(IsEnabled, header) == 0, + "offset of IsEnabled header should be 0"); +static_assert(offsetof(IsEnabled, cap) == 4, + "offset of IsEnabled cap should be 4"); +static_assert(offsetof(IsEnabled, result_shm_id) == 8, + "offset of IsEnabled result_shm_id should be 8"); +static_assert(offsetof(IsEnabled, result_shm_offset) == 12, + "offset of IsEnabled result_shm_offset should be 12"); struct IsFramebuffer { typedef IsFramebuffer ValueType; @@ -3906,15 +6305,16 @@ struct IsFramebuffer { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(IsFramebuffer) == 16, Sizeof_IsFramebuffer_is_not_16); -COMPILE_ASSERT(offsetof(IsFramebuffer, header) == 0, - OffsetOf_IsFramebuffer_header_not_0); -COMPILE_ASSERT(offsetof(IsFramebuffer, framebuffer) == 4, - OffsetOf_IsFramebuffer_framebuffer_not_4); -COMPILE_ASSERT(offsetof(IsFramebuffer, result_shm_id) == 8, - OffsetOf_IsFramebuffer_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(IsFramebuffer, result_shm_offset) == 12, - OffsetOf_IsFramebuffer_result_shm_offset_not_12); +static_assert(sizeof(IsFramebuffer) == 16, + "size of IsFramebuffer should be 16"); +static_assert(offsetof(IsFramebuffer, header) == 0, + "offset of IsFramebuffer header should be 0"); +static_assert(offsetof(IsFramebuffer, framebuffer) == 4, + "offset of IsFramebuffer framebuffer should be 4"); +static_assert(offsetof(IsFramebuffer, result_shm_id) == 8, + "offset of IsFramebuffer result_shm_id should be 8"); +static_assert(offsetof(IsFramebuffer, result_shm_offset) == 12, + "offset of IsFramebuffer result_shm_offset should be 12"); struct IsProgram { typedef IsProgram ValueType; @@ -3954,15 +6354,15 @@ struct IsProgram { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(IsProgram) == 16, Sizeof_IsProgram_is_not_16); -COMPILE_ASSERT(offsetof(IsProgram, header) == 0, - OffsetOf_IsProgram_header_not_0); -COMPILE_ASSERT(offsetof(IsProgram, program) == 4, - OffsetOf_IsProgram_program_not_4); -COMPILE_ASSERT(offsetof(IsProgram, result_shm_id) == 8, - OffsetOf_IsProgram_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(IsProgram, result_shm_offset) == 12, - OffsetOf_IsProgram_result_shm_offset_not_12); +static_assert(sizeof(IsProgram) == 16, "size of IsProgram should be 16"); +static_assert(offsetof(IsProgram, header) == 0, + "offset of IsProgram header should be 0"); +static_assert(offsetof(IsProgram, program) == 4, + "offset of IsProgram program should be 4"); +static_assert(offsetof(IsProgram, result_shm_id) == 8, + "offset of IsProgram result_shm_id should be 8"); +static_assert(offsetof(IsProgram, result_shm_offset) == 12, + "offset of IsProgram result_shm_offset should be 12"); struct IsRenderbuffer { typedef IsRenderbuffer ValueType; @@ -4002,15 +6402,64 @@ struct IsRenderbuffer { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(IsRenderbuffer) == 16, Sizeof_IsRenderbuffer_is_not_16); -COMPILE_ASSERT(offsetof(IsRenderbuffer, header) == 0, - OffsetOf_IsRenderbuffer_header_not_0); -COMPILE_ASSERT(offsetof(IsRenderbuffer, renderbuffer) == 4, - OffsetOf_IsRenderbuffer_renderbuffer_not_4); -COMPILE_ASSERT(offsetof(IsRenderbuffer, result_shm_id) == 8, - OffsetOf_IsRenderbuffer_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(IsRenderbuffer, result_shm_offset) == 12, - OffsetOf_IsRenderbuffer_result_shm_offset_not_12); +static_assert(sizeof(IsRenderbuffer) == 16, + "size of IsRenderbuffer should be 16"); +static_assert(offsetof(IsRenderbuffer, header) == 0, + "offset of IsRenderbuffer header should be 0"); +static_assert(offsetof(IsRenderbuffer, renderbuffer) == 4, + "offset of IsRenderbuffer renderbuffer should be 4"); +static_assert(offsetof(IsRenderbuffer, result_shm_id) == 8, + "offset of IsRenderbuffer result_shm_id should be 8"); +static_assert(offsetof(IsRenderbuffer, result_shm_offset) == 12, + "offset of IsRenderbuffer result_shm_offset should be 12"); + +struct IsSampler { + typedef IsSampler ValueType; + static const CommandId kCmdId = kIsSampler; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef uint32_t Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _sampler, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + SetHeader(); + sampler = _sampler; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set(void* cmd, + GLuint _sampler, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_sampler, _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t sampler; + uint32_t result_shm_id; + uint32_t result_shm_offset; +}; + +static_assert(sizeof(IsSampler) == 16, "size of IsSampler should be 16"); +static_assert(offsetof(IsSampler, header) == 0, + "offset of IsSampler header should be 0"); +static_assert(offsetof(IsSampler, sampler) == 4, + "offset of IsSampler sampler should be 4"); +static_assert(offsetof(IsSampler, result_shm_id) == 8, + "offset of IsSampler result_shm_id should be 8"); +static_assert(offsetof(IsSampler, result_shm_offset) == 12, + "offset of IsSampler result_shm_offset should be 12"); struct IsShader { typedef IsShader ValueType; @@ -4050,13 +6499,62 @@ struct IsShader { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(IsShader) == 16, Sizeof_IsShader_is_not_16); -COMPILE_ASSERT(offsetof(IsShader, header) == 0, OffsetOf_IsShader_header_not_0); -COMPILE_ASSERT(offsetof(IsShader, shader) == 4, OffsetOf_IsShader_shader_not_4); -COMPILE_ASSERT(offsetof(IsShader, result_shm_id) == 8, - OffsetOf_IsShader_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(IsShader, result_shm_offset) == 12, - OffsetOf_IsShader_result_shm_offset_not_12); +static_assert(sizeof(IsShader) == 16, "size of IsShader should be 16"); +static_assert(offsetof(IsShader, header) == 0, + "offset of IsShader header should be 0"); +static_assert(offsetof(IsShader, shader) == 4, + "offset of IsShader shader should be 4"); +static_assert(offsetof(IsShader, result_shm_id) == 8, + "offset of IsShader result_shm_id should be 8"); +static_assert(offsetof(IsShader, result_shm_offset) == 12, + "offset of IsShader result_shm_offset should be 12"); + +struct IsSync { + typedef IsSync ValueType; + static const CommandId kCmdId = kIsSync; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef uint32_t Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _sync, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + SetHeader(); + sync = _sync; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set(void* cmd, + GLuint _sync, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_sync, _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t sync; + uint32_t result_shm_id; + uint32_t result_shm_offset; +}; + +static_assert(sizeof(IsSync) == 16, "size of IsSync should be 16"); +static_assert(offsetof(IsSync, header) == 0, + "offset of IsSync header should be 0"); +static_assert(offsetof(IsSync, sync) == 4, "offset of IsSync sync should be 4"); +static_assert(offsetof(IsSync, result_shm_id) == 8, + "offset of IsSync result_shm_id should be 8"); +static_assert(offsetof(IsSync, result_shm_offset) == 12, + "offset of IsSync result_shm_offset should be 12"); struct IsTexture { typedef IsTexture ValueType; @@ -4096,15 +6594,64 @@ struct IsTexture { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(IsTexture) == 16, Sizeof_IsTexture_is_not_16); -COMPILE_ASSERT(offsetof(IsTexture, header) == 0, - OffsetOf_IsTexture_header_not_0); -COMPILE_ASSERT(offsetof(IsTexture, texture) == 4, - OffsetOf_IsTexture_texture_not_4); -COMPILE_ASSERT(offsetof(IsTexture, result_shm_id) == 8, - OffsetOf_IsTexture_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(IsTexture, result_shm_offset) == 12, - OffsetOf_IsTexture_result_shm_offset_not_12); +static_assert(sizeof(IsTexture) == 16, "size of IsTexture should be 16"); +static_assert(offsetof(IsTexture, header) == 0, + "offset of IsTexture header should be 0"); +static_assert(offsetof(IsTexture, texture) == 4, + "offset of IsTexture texture should be 4"); +static_assert(offsetof(IsTexture, result_shm_id) == 8, + "offset of IsTexture result_shm_id should be 8"); +static_assert(offsetof(IsTexture, result_shm_offset) == 12, + "offset of IsTexture result_shm_offset should be 12"); + +struct IsTransformFeedback { + typedef IsTransformFeedback ValueType; + static const CommandId kCmdId = kIsTransformFeedback; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef uint32_t Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _transformfeedback, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + SetHeader(); + transformfeedback = _transformfeedback; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set(void* cmd, + GLuint _transformfeedback, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_transformfeedback, _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t transformfeedback; + uint32_t result_shm_id; + uint32_t result_shm_offset; +}; + +static_assert(sizeof(IsTransformFeedback) == 16, + "size of IsTransformFeedback should be 16"); +static_assert(offsetof(IsTransformFeedback, header) == 0, + "offset of IsTransformFeedback header should be 0"); +static_assert(offsetof(IsTransformFeedback, transformfeedback) == 4, + "offset of IsTransformFeedback transformfeedback should be 4"); +static_assert(offsetof(IsTransformFeedback, result_shm_id) == 8, + "offset of IsTransformFeedback result_shm_id should be 8"); +static_assert(offsetof(IsTransformFeedback, result_shm_offset) == 12, + "offset of IsTransformFeedback result_shm_offset should be 12"); struct LineWidth { typedef LineWidth ValueType; @@ -4132,10 +6679,11 @@ struct LineWidth { float width; }; -COMPILE_ASSERT(sizeof(LineWidth) == 8, Sizeof_LineWidth_is_not_8); -COMPILE_ASSERT(offsetof(LineWidth, header) == 0, - OffsetOf_LineWidth_header_not_0); -COMPILE_ASSERT(offsetof(LineWidth, width) == 4, OffsetOf_LineWidth_width_not_4); +static_assert(sizeof(LineWidth) == 8, "size of LineWidth should be 8"); +static_assert(offsetof(LineWidth, header) == 0, + "offset of LineWidth header should be 0"); +static_assert(offsetof(LineWidth, width) == 4, + "offset of LineWidth width should be 4"); struct LinkProgram { typedef LinkProgram ValueType; @@ -4163,11 +6711,38 @@ struct LinkProgram { uint32_t program; }; -COMPILE_ASSERT(sizeof(LinkProgram) == 8, Sizeof_LinkProgram_is_not_8); -COMPILE_ASSERT(offsetof(LinkProgram, header) == 0, - OffsetOf_LinkProgram_header_not_0); -COMPILE_ASSERT(offsetof(LinkProgram, program) == 4, - OffsetOf_LinkProgram_program_not_4); +static_assert(sizeof(LinkProgram) == 8, "size of LinkProgram should be 8"); +static_assert(offsetof(LinkProgram, header) == 0, + "offset of LinkProgram header should be 0"); +static_assert(offsetof(LinkProgram, program) == 4, + "offset of LinkProgram program should be 4"); + +struct PauseTransformFeedback { + typedef PauseTransformFeedback ValueType; + static const CommandId kCmdId = kPauseTransformFeedback; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init() { SetHeader(); } + + void* Set(void* cmd) { + static_cast<ValueType*>(cmd)->Init(); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; +}; + +static_assert(sizeof(PauseTransformFeedback) == 4, + "size of PauseTransformFeedback should be 4"); +static_assert(offsetof(PauseTransformFeedback, header) == 0, + "offset of PauseTransformFeedback header should be 0"); struct PixelStorei { typedef PixelStorei ValueType; @@ -4197,13 +6772,13 @@ struct PixelStorei { int32_t param; }; -COMPILE_ASSERT(sizeof(PixelStorei) == 12, Sizeof_PixelStorei_is_not_12); -COMPILE_ASSERT(offsetof(PixelStorei, header) == 0, - OffsetOf_PixelStorei_header_not_0); -COMPILE_ASSERT(offsetof(PixelStorei, pname) == 4, - OffsetOf_PixelStorei_pname_not_4); -COMPILE_ASSERT(offsetof(PixelStorei, param) == 8, - OffsetOf_PixelStorei_param_not_8); +static_assert(sizeof(PixelStorei) == 12, "size of PixelStorei should be 12"); +static_assert(offsetof(PixelStorei, header) == 0, + "offset of PixelStorei header should be 0"); +static_assert(offsetof(PixelStorei, pname) == 4, + "offset of PixelStorei pname should be 4"); +static_assert(offsetof(PixelStorei, param) == 8, + "offset of PixelStorei param should be 8"); struct PolygonOffset { typedef PolygonOffset ValueType; @@ -4233,13 +6808,46 @@ struct PolygonOffset { float units; }; -COMPILE_ASSERT(sizeof(PolygonOffset) == 12, Sizeof_PolygonOffset_is_not_12); -COMPILE_ASSERT(offsetof(PolygonOffset, header) == 0, - OffsetOf_PolygonOffset_header_not_0); -COMPILE_ASSERT(offsetof(PolygonOffset, factor) == 4, - OffsetOf_PolygonOffset_factor_not_4); -COMPILE_ASSERT(offsetof(PolygonOffset, units) == 8, - OffsetOf_PolygonOffset_units_not_8); +static_assert(sizeof(PolygonOffset) == 12, + "size of PolygonOffset should be 12"); +static_assert(offsetof(PolygonOffset, header) == 0, + "offset of PolygonOffset header should be 0"); +static_assert(offsetof(PolygonOffset, factor) == 4, + "offset of PolygonOffset factor should be 4"); +static_assert(offsetof(PolygonOffset, units) == 8, + "offset of PolygonOffset units should be 8"); + +struct ReadBuffer { + typedef ReadBuffer ValueType; + static const CommandId kCmdId = kReadBuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _src) { + SetHeader(); + src = _src; + } + + void* Set(void* cmd, GLenum _src) { + static_cast<ValueType*>(cmd)->Init(_src); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t src; +}; + +static_assert(sizeof(ReadBuffer) == 8, "size of ReadBuffer should be 8"); +static_assert(offsetof(ReadBuffer, header) == 0, + "offset of ReadBuffer header should be 0"); +static_assert(offsetof(ReadBuffer, src) == 4, + "offset of ReadBuffer src should be 4"); // ReadPixels has the result separated from the pixel buffer so that // it is easier to specify the result going to some specific place @@ -4315,29 +6923,31 @@ struct ReadPixels { uint32_t async; }; -COMPILE_ASSERT(sizeof(ReadPixels) == 48, Sizeof_ReadPixels_is_not_48); -COMPILE_ASSERT(offsetof(ReadPixels, header) == 0, - OffsetOf_ReadPixels_header_not_0); -COMPILE_ASSERT(offsetof(ReadPixels, x) == 4, OffsetOf_ReadPixels_x_not_4); -COMPILE_ASSERT(offsetof(ReadPixels, y) == 8, OffsetOf_ReadPixels_y_not_8); -COMPILE_ASSERT(offsetof(ReadPixels, width) == 12, - OffsetOf_ReadPixels_width_not_12); -COMPILE_ASSERT(offsetof(ReadPixels, height) == 16, - OffsetOf_ReadPixels_height_not_16); -COMPILE_ASSERT(offsetof(ReadPixels, format) == 20, - OffsetOf_ReadPixels_format_not_20); -COMPILE_ASSERT(offsetof(ReadPixels, type) == 24, - OffsetOf_ReadPixels_type_not_24); -COMPILE_ASSERT(offsetof(ReadPixels, pixels_shm_id) == 28, - OffsetOf_ReadPixels_pixels_shm_id_not_28); -COMPILE_ASSERT(offsetof(ReadPixels, pixels_shm_offset) == 32, - OffsetOf_ReadPixels_pixels_shm_offset_not_32); -COMPILE_ASSERT(offsetof(ReadPixels, result_shm_id) == 36, - OffsetOf_ReadPixels_result_shm_id_not_36); -COMPILE_ASSERT(offsetof(ReadPixels, result_shm_offset) == 40, - OffsetOf_ReadPixels_result_shm_offset_not_40); -COMPILE_ASSERT(offsetof(ReadPixels, async) == 44, - OffsetOf_ReadPixels_async_not_44); +static_assert(sizeof(ReadPixels) == 48, "size of ReadPixels should be 48"); +static_assert(offsetof(ReadPixels, header) == 0, + "offset of ReadPixels header should be 0"); +static_assert(offsetof(ReadPixels, x) == 4, + "offset of ReadPixels x should be 4"); +static_assert(offsetof(ReadPixels, y) == 8, + "offset of ReadPixels y should be 8"); +static_assert(offsetof(ReadPixels, width) == 12, + "offset of ReadPixels width should be 12"); +static_assert(offsetof(ReadPixels, height) == 16, + "offset of ReadPixels height should be 16"); +static_assert(offsetof(ReadPixels, format) == 20, + "offset of ReadPixels format should be 20"); +static_assert(offsetof(ReadPixels, type) == 24, + "offset of ReadPixels type should be 24"); +static_assert(offsetof(ReadPixels, pixels_shm_id) == 28, + "offset of ReadPixels pixels_shm_id should be 28"); +static_assert(offsetof(ReadPixels, pixels_shm_offset) == 32, + "offset of ReadPixels pixels_shm_offset should be 32"); +static_assert(offsetof(ReadPixels, result_shm_id) == 36, + "offset of ReadPixels result_shm_id should be 36"); +static_assert(offsetof(ReadPixels, result_shm_offset) == 40, + "offset of ReadPixels result_shm_offset should be 40"); +static_assert(offsetof(ReadPixels, async) == 44, + "offset of ReadPixels async should be 44"); struct ReleaseShaderCompiler { typedef ReleaseShaderCompiler ValueType; @@ -4361,10 +6971,10 @@ struct ReleaseShaderCompiler { gpu::CommandHeader header; }; -COMPILE_ASSERT(sizeof(ReleaseShaderCompiler) == 4, - Sizeof_ReleaseShaderCompiler_is_not_4); -COMPILE_ASSERT(offsetof(ReleaseShaderCompiler, header) == 0, - OffsetOf_ReleaseShaderCompiler_header_not_0); +static_assert(sizeof(ReleaseShaderCompiler) == 4, + "size of ReleaseShaderCompiler should be 4"); +static_assert(offsetof(ReleaseShaderCompiler, header) == 0, + "offset of ReleaseShaderCompiler header should be 0"); struct RenderbufferStorage { typedef RenderbufferStorage ValueType; @@ -4406,18 +7016,45 @@ struct RenderbufferStorage { int32_t height; }; -COMPILE_ASSERT(sizeof(RenderbufferStorage) == 20, - Sizeof_RenderbufferStorage_is_not_20); -COMPILE_ASSERT(offsetof(RenderbufferStorage, header) == 0, - OffsetOf_RenderbufferStorage_header_not_0); -COMPILE_ASSERT(offsetof(RenderbufferStorage, target) == 4, - OffsetOf_RenderbufferStorage_target_not_4); -COMPILE_ASSERT(offsetof(RenderbufferStorage, internalformat) == 8, - OffsetOf_RenderbufferStorage_internalformat_not_8); -COMPILE_ASSERT(offsetof(RenderbufferStorage, width) == 12, - OffsetOf_RenderbufferStorage_width_not_12); -COMPILE_ASSERT(offsetof(RenderbufferStorage, height) == 16, - OffsetOf_RenderbufferStorage_height_not_16); +static_assert(sizeof(RenderbufferStorage) == 20, + "size of RenderbufferStorage should be 20"); +static_assert(offsetof(RenderbufferStorage, header) == 0, + "offset of RenderbufferStorage header should be 0"); +static_assert(offsetof(RenderbufferStorage, target) == 4, + "offset of RenderbufferStorage target should be 4"); +static_assert(offsetof(RenderbufferStorage, internalformat) == 8, + "offset of RenderbufferStorage internalformat should be 8"); +static_assert(offsetof(RenderbufferStorage, width) == 12, + "offset of RenderbufferStorage width should be 12"); +static_assert(offsetof(RenderbufferStorage, height) == 16, + "offset of RenderbufferStorage height should be 16"); + +struct ResumeTransformFeedback { + typedef ResumeTransformFeedback ValueType; + static const CommandId kCmdId = kResumeTransformFeedback; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init() { SetHeader(); } + + void* Set(void* cmd) { + static_cast<ValueType*>(cmd)->Init(); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; +}; + +static_assert(sizeof(ResumeTransformFeedback) == 4, + "size of ResumeTransformFeedback should be 4"); +static_assert(offsetof(ResumeTransformFeedback, header) == 0, + "offset of ResumeTransformFeedback header should be 0"); struct SampleCoverage { typedef SampleCoverage ValueType; @@ -4447,13 +7084,182 @@ struct SampleCoverage { uint32_t invert; }; -COMPILE_ASSERT(sizeof(SampleCoverage) == 12, Sizeof_SampleCoverage_is_not_12); -COMPILE_ASSERT(offsetof(SampleCoverage, header) == 0, - OffsetOf_SampleCoverage_header_not_0); -COMPILE_ASSERT(offsetof(SampleCoverage, value) == 4, - OffsetOf_SampleCoverage_value_not_4); -COMPILE_ASSERT(offsetof(SampleCoverage, invert) == 8, - OffsetOf_SampleCoverage_invert_not_8); +static_assert(sizeof(SampleCoverage) == 12, + "size of SampleCoverage should be 12"); +static_assert(offsetof(SampleCoverage, header) == 0, + "offset of SampleCoverage header should be 0"); +static_assert(offsetof(SampleCoverage, value) == 4, + "offset of SampleCoverage value should be 4"); +static_assert(offsetof(SampleCoverage, invert) == 8, + "offset of SampleCoverage invert should be 8"); + +struct SamplerParameterf { + typedef SamplerParameterf ValueType; + static const CommandId kCmdId = kSamplerParameterf; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _sampler, GLenum _pname, GLfloat _param) { + SetHeader(); + sampler = _sampler; + pname = _pname; + param = _param; + } + + void* Set(void* cmd, GLuint _sampler, GLenum _pname, GLfloat _param) { + static_cast<ValueType*>(cmd)->Init(_sampler, _pname, _param); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t sampler; + uint32_t pname; + float param; +}; + +static_assert(sizeof(SamplerParameterf) == 16, + "size of SamplerParameterf should be 16"); +static_assert(offsetof(SamplerParameterf, header) == 0, + "offset of SamplerParameterf header should be 0"); +static_assert(offsetof(SamplerParameterf, sampler) == 4, + "offset of SamplerParameterf sampler should be 4"); +static_assert(offsetof(SamplerParameterf, pname) == 8, + "offset of SamplerParameterf pname should be 8"); +static_assert(offsetof(SamplerParameterf, param) == 12, + "offset of SamplerParameterf param should be 12"); + +struct SamplerParameterfvImmediate { + typedef SamplerParameterfvImmediate ValueType; + static const CommandId kCmdId = kSamplerParameterfvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize() { + return static_cast<uint32_t>(sizeof(GLfloat) * 1); + } + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); + } + + void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } + + void Init(GLuint _sampler, GLenum _pname, const GLfloat* _params) { + SetHeader(); + sampler = _sampler; + pname = _pname; + memcpy(ImmediateDataAddress(this), _params, ComputeDataSize()); + } + + void* Set(void* cmd, GLuint _sampler, GLenum _pname, const GLfloat* _params) { + static_cast<ValueType*>(cmd)->Init(_sampler, _pname, _params); + const uint32_t size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + uint32_t sampler; + uint32_t pname; +}; + +static_assert(sizeof(SamplerParameterfvImmediate) == 12, + "size of SamplerParameterfvImmediate should be 12"); +static_assert(offsetof(SamplerParameterfvImmediate, header) == 0, + "offset of SamplerParameterfvImmediate header should be 0"); +static_assert(offsetof(SamplerParameterfvImmediate, sampler) == 4, + "offset of SamplerParameterfvImmediate sampler should be 4"); +static_assert(offsetof(SamplerParameterfvImmediate, pname) == 8, + "offset of SamplerParameterfvImmediate pname should be 8"); + +struct SamplerParameteri { + typedef SamplerParameteri ValueType; + static const CommandId kCmdId = kSamplerParameteri; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _sampler, GLenum _pname, GLint _param) { + SetHeader(); + sampler = _sampler; + pname = _pname; + param = _param; + } + + void* Set(void* cmd, GLuint _sampler, GLenum _pname, GLint _param) { + static_cast<ValueType*>(cmd)->Init(_sampler, _pname, _param); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t sampler; + uint32_t pname; + int32_t param; +}; + +static_assert(sizeof(SamplerParameteri) == 16, + "size of SamplerParameteri should be 16"); +static_assert(offsetof(SamplerParameteri, header) == 0, + "offset of SamplerParameteri header should be 0"); +static_assert(offsetof(SamplerParameteri, sampler) == 4, + "offset of SamplerParameteri sampler should be 4"); +static_assert(offsetof(SamplerParameteri, pname) == 8, + "offset of SamplerParameteri pname should be 8"); +static_assert(offsetof(SamplerParameteri, param) == 12, + "offset of SamplerParameteri param should be 12"); + +struct SamplerParameterivImmediate { + typedef SamplerParameterivImmediate ValueType; + static const CommandId kCmdId = kSamplerParameterivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize() { + return static_cast<uint32_t>(sizeof(GLint) * 1); + } + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); + } + + void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } + + void Init(GLuint _sampler, GLenum _pname, const GLint* _params) { + SetHeader(); + sampler = _sampler; + pname = _pname; + memcpy(ImmediateDataAddress(this), _params, ComputeDataSize()); + } + + void* Set(void* cmd, GLuint _sampler, GLenum _pname, const GLint* _params) { + static_cast<ValueType*>(cmd)->Init(_sampler, _pname, _params); + const uint32_t size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + uint32_t sampler; + uint32_t pname; +}; + +static_assert(sizeof(SamplerParameterivImmediate) == 12, + "size of SamplerParameterivImmediate should be 12"); +static_assert(offsetof(SamplerParameterivImmediate, header) == 0, + "offset of SamplerParameterivImmediate header should be 0"); +static_assert(offsetof(SamplerParameterivImmediate, sampler) == 4, + "offset of SamplerParameterivImmediate sampler should be 4"); +static_assert(offsetof(SamplerParameterivImmediate, pname) == 8, + "offset of SamplerParameterivImmediate pname should be 8"); struct Scissor { typedef Scissor ValueType; @@ -4487,12 +7293,15 @@ struct Scissor { int32_t height; }; -COMPILE_ASSERT(sizeof(Scissor) == 20, Sizeof_Scissor_is_not_20); -COMPILE_ASSERT(offsetof(Scissor, header) == 0, OffsetOf_Scissor_header_not_0); -COMPILE_ASSERT(offsetof(Scissor, x) == 4, OffsetOf_Scissor_x_not_4); -COMPILE_ASSERT(offsetof(Scissor, y) == 8, OffsetOf_Scissor_y_not_8); -COMPILE_ASSERT(offsetof(Scissor, width) == 12, OffsetOf_Scissor_width_not_12); -COMPILE_ASSERT(offsetof(Scissor, height) == 16, OffsetOf_Scissor_height_not_16); +static_assert(sizeof(Scissor) == 20, "size of Scissor should be 20"); +static_assert(offsetof(Scissor, header) == 0, + "offset of Scissor header should be 0"); +static_assert(offsetof(Scissor, x) == 4, "offset of Scissor x should be 4"); +static_assert(offsetof(Scissor, y) == 8, "offset of Scissor y should be 8"); +static_assert(offsetof(Scissor, width) == 12, + "offset of Scissor width should be 12"); +static_assert(offsetof(Scissor, height) == 16, + "offset of Scissor height should be 16"); struct ShaderBinary { typedef ShaderBinary ValueType; @@ -4547,22 +7356,23 @@ struct ShaderBinary { int32_t length; }; -COMPILE_ASSERT(sizeof(ShaderBinary) == 32, Sizeof_ShaderBinary_is_not_32); -COMPILE_ASSERT(offsetof(ShaderBinary, header) == 0, - OffsetOf_ShaderBinary_header_not_0); -COMPILE_ASSERT(offsetof(ShaderBinary, n) == 4, OffsetOf_ShaderBinary_n_not_4); -COMPILE_ASSERT(offsetof(ShaderBinary, shaders_shm_id) == 8, - OffsetOf_ShaderBinary_shaders_shm_id_not_8); -COMPILE_ASSERT(offsetof(ShaderBinary, shaders_shm_offset) == 12, - OffsetOf_ShaderBinary_shaders_shm_offset_not_12); -COMPILE_ASSERT(offsetof(ShaderBinary, binaryformat) == 16, - OffsetOf_ShaderBinary_binaryformat_not_16); -COMPILE_ASSERT(offsetof(ShaderBinary, binary_shm_id) == 20, - OffsetOf_ShaderBinary_binary_shm_id_not_20); -COMPILE_ASSERT(offsetof(ShaderBinary, binary_shm_offset) == 24, - OffsetOf_ShaderBinary_binary_shm_offset_not_24); -COMPILE_ASSERT(offsetof(ShaderBinary, length) == 28, - OffsetOf_ShaderBinary_length_not_28); +static_assert(sizeof(ShaderBinary) == 32, "size of ShaderBinary should be 32"); +static_assert(offsetof(ShaderBinary, header) == 0, + "offset of ShaderBinary header should be 0"); +static_assert(offsetof(ShaderBinary, n) == 4, + "offset of ShaderBinary n should be 4"); +static_assert(offsetof(ShaderBinary, shaders_shm_id) == 8, + "offset of ShaderBinary shaders_shm_id should be 8"); +static_assert(offsetof(ShaderBinary, shaders_shm_offset) == 12, + "offset of ShaderBinary shaders_shm_offset should be 12"); +static_assert(offsetof(ShaderBinary, binaryformat) == 16, + "offset of ShaderBinary binaryformat should be 16"); +static_assert(offsetof(ShaderBinary, binary_shm_id) == 20, + "offset of ShaderBinary binary_shm_id should be 20"); +static_assert(offsetof(ShaderBinary, binary_shm_offset) == 24, + "offset of ShaderBinary binary_shm_offset should be 24"); +static_assert(offsetof(ShaderBinary, length) == 28, + "offset of ShaderBinary length should be 28"); struct ShaderSourceBucket { typedef ShaderSourceBucket ValueType; @@ -4576,30 +7386,30 @@ struct ShaderSourceBucket { void SetHeader() { header.SetCmd<ValueType>(); } - void Init(GLuint _shader, uint32_t _data_bucket_id) { + void Init(GLuint _shader, uint32_t _str_bucket_id) { SetHeader(); shader = _shader; - data_bucket_id = _data_bucket_id; + str_bucket_id = _str_bucket_id; } - void* Set(void* cmd, GLuint _shader, uint32_t _data_bucket_id) { - static_cast<ValueType*>(cmd)->Init(_shader, _data_bucket_id); + void* Set(void* cmd, GLuint _shader, uint32_t _str_bucket_id) { + static_cast<ValueType*>(cmd)->Init(_shader, _str_bucket_id); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; uint32_t shader; - uint32_t data_bucket_id; + uint32_t str_bucket_id; }; -COMPILE_ASSERT(sizeof(ShaderSourceBucket) == 12, - Sizeof_ShaderSourceBucket_is_not_12); -COMPILE_ASSERT(offsetof(ShaderSourceBucket, header) == 0, - OffsetOf_ShaderSourceBucket_header_not_0); -COMPILE_ASSERT(offsetof(ShaderSourceBucket, shader) == 4, - OffsetOf_ShaderSourceBucket_shader_not_4); -COMPILE_ASSERT(offsetof(ShaderSourceBucket, data_bucket_id) == 8, - OffsetOf_ShaderSourceBucket_data_bucket_id_not_8); +static_assert(sizeof(ShaderSourceBucket) == 12, + "size of ShaderSourceBucket should be 12"); +static_assert(offsetof(ShaderSourceBucket, header) == 0, + "offset of ShaderSourceBucket header should be 0"); +static_assert(offsetof(ShaderSourceBucket, shader) == 4, + "offset of ShaderSourceBucket shader should be 4"); +static_assert(offsetof(ShaderSourceBucket, str_bucket_id) == 8, + "offset of ShaderSourceBucket str_bucket_id should be 8"); struct StencilFunc { typedef StencilFunc ValueType; @@ -4631,14 +7441,15 @@ struct StencilFunc { uint32_t mask; }; -COMPILE_ASSERT(sizeof(StencilFunc) == 16, Sizeof_StencilFunc_is_not_16); -COMPILE_ASSERT(offsetof(StencilFunc, header) == 0, - OffsetOf_StencilFunc_header_not_0); -COMPILE_ASSERT(offsetof(StencilFunc, func) == 4, - OffsetOf_StencilFunc_func_not_4); -COMPILE_ASSERT(offsetof(StencilFunc, ref) == 8, OffsetOf_StencilFunc_ref_not_8); -COMPILE_ASSERT(offsetof(StencilFunc, mask) == 12, - OffsetOf_StencilFunc_mask_not_12); +static_assert(sizeof(StencilFunc) == 16, "size of StencilFunc should be 16"); +static_assert(offsetof(StencilFunc, header) == 0, + "offset of StencilFunc header should be 0"); +static_assert(offsetof(StencilFunc, func) == 4, + "offset of StencilFunc func should be 4"); +static_assert(offsetof(StencilFunc, ref) == 8, + "offset of StencilFunc ref should be 8"); +static_assert(offsetof(StencilFunc, mask) == 12, + "offset of StencilFunc mask should be 12"); struct StencilFuncSeparate { typedef StencilFuncSeparate ValueType; @@ -4672,18 +7483,18 @@ struct StencilFuncSeparate { uint32_t mask; }; -COMPILE_ASSERT(sizeof(StencilFuncSeparate) == 20, - Sizeof_StencilFuncSeparate_is_not_20); -COMPILE_ASSERT(offsetof(StencilFuncSeparate, header) == 0, - OffsetOf_StencilFuncSeparate_header_not_0); -COMPILE_ASSERT(offsetof(StencilFuncSeparate, face) == 4, - OffsetOf_StencilFuncSeparate_face_not_4); -COMPILE_ASSERT(offsetof(StencilFuncSeparate, func) == 8, - OffsetOf_StencilFuncSeparate_func_not_8); -COMPILE_ASSERT(offsetof(StencilFuncSeparate, ref) == 12, - OffsetOf_StencilFuncSeparate_ref_not_12); -COMPILE_ASSERT(offsetof(StencilFuncSeparate, mask) == 16, - OffsetOf_StencilFuncSeparate_mask_not_16); +static_assert(sizeof(StencilFuncSeparate) == 20, + "size of StencilFuncSeparate should be 20"); +static_assert(offsetof(StencilFuncSeparate, header) == 0, + "offset of StencilFuncSeparate header should be 0"); +static_assert(offsetof(StencilFuncSeparate, face) == 4, + "offset of StencilFuncSeparate face should be 4"); +static_assert(offsetof(StencilFuncSeparate, func) == 8, + "offset of StencilFuncSeparate func should be 8"); +static_assert(offsetof(StencilFuncSeparate, ref) == 12, + "offset of StencilFuncSeparate ref should be 12"); +static_assert(offsetof(StencilFuncSeparate, mask) == 16, + "offset of StencilFuncSeparate mask should be 16"); struct StencilMask { typedef StencilMask ValueType; @@ -4711,11 +7522,11 @@ struct StencilMask { uint32_t mask; }; -COMPILE_ASSERT(sizeof(StencilMask) == 8, Sizeof_StencilMask_is_not_8); -COMPILE_ASSERT(offsetof(StencilMask, header) == 0, - OffsetOf_StencilMask_header_not_0); -COMPILE_ASSERT(offsetof(StencilMask, mask) == 4, - OffsetOf_StencilMask_mask_not_4); +static_assert(sizeof(StencilMask) == 8, "size of StencilMask should be 8"); +static_assert(offsetof(StencilMask, header) == 0, + "offset of StencilMask header should be 0"); +static_assert(offsetof(StencilMask, mask) == 4, + "offset of StencilMask mask should be 4"); struct StencilMaskSeparate { typedef StencilMaskSeparate ValueType; @@ -4745,14 +7556,14 @@ struct StencilMaskSeparate { uint32_t mask; }; -COMPILE_ASSERT(sizeof(StencilMaskSeparate) == 12, - Sizeof_StencilMaskSeparate_is_not_12); -COMPILE_ASSERT(offsetof(StencilMaskSeparate, header) == 0, - OffsetOf_StencilMaskSeparate_header_not_0); -COMPILE_ASSERT(offsetof(StencilMaskSeparate, face) == 4, - OffsetOf_StencilMaskSeparate_face_not_4); -COMPILE_ASSERT(offsetof(StencilMaskSeparate, mask) == 8, - OffsetOf_StencilMaskSeparate_mask_not_8); +static_assert(sizeof(StencilMaskSeparate) == 12, + "size of StencilMaskSeparate should be 12"); +static_assert(offsetof(StencilMaskSeparate, header) == 0, + "offset of StencilMaskSeparate header should be 0"); +static_assert(offsetof(StencilMaskSeparate, face) == 4, + "offset of StencilMaskSeparate face should be 4"); +static_assert(offsetof(StencilMaskSeparate, mask) == 8, + "offset of StencilMaskSeparate mask should be 8"); struct StencilOp { typedef StencilOp ValueType; @@ -4784,13 +7595,15 @@ struct StencilOp { uint32_t zpass; }; -COMPILE_ASSERT(sizeof(StencilOp) == 16, Sizeof_StencilOp_is_not_16); -COMPILE_ASSERT(offsetof(StencilOp, header) == 0, - OffsetOf_StencilOp_header_not_0); -COMPILE_ASSERT(offsetof(StencilOp, fail) == 4, OffsetOf_StencilOp_fail_not_4); -COMPILE_ASSERT(offsetof(StencilOp, zfail) == 8, OffsetOf_StencilOp_zfail_not_8); -COMPILE_ASSERT(offsetof(StencilOp, zpass) == 12, - OffsetOf_StencilOp_zpass_not_12); +static_assert(sizeof(StencilOp) == 16, "size of StencilOp should be 16"); +static_assert(offsetof(StencilOp, header) == 0, + "offset of StencilOp header should be 0"); +static_assert(offsetof(StencilOp, fail) == 4, + "offset of StencilOp fail should be 4"); +static_assert(offsetof(StencilOp, zfail) == 8, + "offset of StencilOp zfail should be 8"); +static_assert(offsetof(StencilOp, zpass) == 12, + "offset of StencilOp zpass should be 12"); struct StencilOpSeparate { typedef StencilOpSeparate ValueType; @@ -4828,18 +7641,18 @@ struct StencilOpSeparate { uint32_t zpass; }; -COMPILE_ASSERT(sizeof(StencilOpSeparate) == 20, - Sizeof_StencilOpSeparate_is_not_20); -COMPILE_ASSERT(offsetof(StencilOpSeparate, header) == 0, - OffsetOf_StencilOpSeparate_header_not_0); -COMPILE_ASSERT(offsetof(StencilOpSeparate, face) == 4, - OffsetOf_StencilOpSeparate_face_not_4); -COMPILE_ASSERT(offsetof(StencilOpSeparate, fail) == 8, - OffsetOf_StencilOpSeparate_fail_not_8); -COMPILE_ASSERT(offsetof(StencilOpSeparate, zfail) == 12, - OffsetOf_StencilOpSeparate_zfail_not_12); -COMPILE_ASSERT(offsetof(StencilOpSeparate, zpass) == 16, - OffsetOf_StencilOpSeparate_zpass_not_16); +static_assert(sizeof(StencilOpSeparate) == 20, + "size of StencilOpSeparate should be 20"); +static_assert(offsetof(StencilOpSeparate, header) == 0, + "offset of StencilOpSeparate header should be 0"); +static_assert(offsetof(StencilOpSeparate, face) == 4, + "offset of StencilOpSeparate face should be 4"); +static_assert(offsetof(StencilOpSeparate, fail) == 8, + "offset of StencilOpSeparate fail should be 8"); +static_assert(offsetof(StencilOpSeparate, zfail) == 12, + "offset of StencilOpSeparate zfail should be 12"); +static_assert(offsetof(StencilOpSeparate, zpass) == 16, + "offset of StencilOpSeparate zpass should be 16"); struct TexImage2D { typedef TexImage2D ValueType; @@ -4903,27 +7716,117 @@ struct TexImage2D { static const int32_t border = 0; }; -COMPILE_ASSERT(sizeof(TexImage2D) == 40, Sizeof_TexImage2D_is_not_40); -COMPILE_ASSERT(offsetof(TexImage2D, header) == 0, - OffsetOf_TexImage2D_header_not_0); -COMPILE_ASSERT(offsetof(TexImage2D, target) == 4, - OffsetOf_TexImage2D_target_not_4); -COMPILE_ASSERT(offsetof(TexImage2D, level) == 8, - OffsetOf_TexImage2D_level_not_8); -COMPILE_ASSERT(offsetof(TexImage2D, internalformat) == 12, - OffsetOf_TexImage2D_internalformat_not_12); -COMPILE_ASSERT(offsetof(TexImage2D, width) == 16, - OffsetOf_TexImage2D_width_not_16); -COMPILE_ASSERT(offsetof(TexImage2D, height) == 20, - OffsetOf_TexImage2D_height_not_20); -COMPILE_ASSERT(offsetof(TexImage2D, format) == 24, - OffsetOf_TexImage2D_format_not_24); -COMPILE_ASSERT(offsetof(TexImage2D, type) == 28, - OffsetOf_TexImage2D_type_not_28); -COMPILE_ASSERT(offsetof(TexImage2D, pixels_shm_id) == 32, - OffsetOf_TexImage2D_pixels_shm_id_not_32); -COMPILE_ASSERT(offsetof(TexImage2D, pixels_shm_offset) == 36, - OffsetOf_TexImage2D_pixels_shm_offset_not_36); +static_assert(sizeof(TexImage2D) == 40, "size of TexImage2D should be 40"); +static_assert(offsetof(TexImage2D, header) == 0, + "offset of TexImage2D header should be 0"); +static_assert(offsetof(TexImage2D, target) == 4, + "offset of TexImage2D target should be 4"); +static_assert(offsetof(TexImage2D, level) == 8, + "offset of TexImage2D level should be 8"); +static_assert(offsetof(TexImage2D, internalformat) == 12, + "offset of TexImage2D internalformat should be 12"); +static_assert(offsetof(TexImage2D, width) == 16, + "offset of TexImage2D width should be 16"); +static_assert(offsetof(TexImage2D, height) == 20, + "offset of TexImage2D height should be 20"); +static_assert(offsetof(TexImage2D, format) == 24, + "offset of TexImage2D format should be 24"); +static_assert(offsetof(TexImage2D, type) == 28, + "offset of TexImage2D type should be 28"); +static_assert(offsetof(TexImage2D, pixels_shm_id) == 32, + "offset of TexImage2D pixels_shm_id should be 32"); +static_assert(offsetof(TexImage2D, pixels_shm_offset) == 36, + "offset of TexImage2D pixels_shm_offset should be 36"); + +struct TexImage3D { + typedef TexImage3D ValueType; + static const CommandId kCmdId = kTexImage3D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLint _level, + GLint _internalformat, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLenum _format, + GLenum _type, + uint32_t _pixels_shm_id, + uint32_t _pixels_shm_offset) { + SetHeader(); + target = _target; + level = _level; + internalformat = _internalformat; + width = _width; + height = _height; + depth = _depth; + format = _format; + type = _type; + pixels_shm_id = _pixels_shm_id; + pixels_shm_offset = _pixels_shm_offset; + } + + void* Set(void* cmd, + GLenum _target, + GLint _level, + GLint _internalformat, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLenum _format, + GLenum _type, + uint32_t _pixels_shm_id, + uint32_t _pixels_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_target, _level, _internalformat, _width, + _height, _depth, _format, _type, + _pixels_shm_id, _pixels_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t level; + int32_t internalformat; + int32_t width; + int32_t height; + int32_t depth; + uint32_t format; + uint32_t type; + uint32_t pixels_shm_id; + uint32_t pixels_shm_offset; + static const int32_t border = 0; +}; + +static_assert(sizeof(TexImage3D) == 44, "size of TexImage3D should be 44"); +static_assert(offsetof(TexImage3D, header) == 0, + "offset of TexImage3D header should be 0"); +static_assert(offsetof(TexImage3D, target) == 4, + "offset of TexImage3D target should be 4"); +static_assert(offsetof(TexImage3D, level) == 8, + "offset of TexImage3D level should be 8"); +static_assert(offsetof(TexImage3D, internalformat) == 12, + "offset of TexImage3D internalformat should be 12"); +static_assert(offsetof(TexImage3D, width) == 16, + "offset of TexImage3D width should be 16"); +static_assert(offsetof(TexImage3D, height) == 20, + "offset of TexImage3D height should be 20"); +static_assert(offsetof(TexImage3D, depth) == 24, + "offset of TexImage3D depth should be 24"); +static_assert(offsetof(TexImage3D, format) == 28, + "offset of TexImage3D format should be 28"); +static_assert(offsetof(TexImage3D, type) == 32, + "offset of TexImage3D type should be 32"); +static_assert(offsetof(TexImage3D, pixels_shm_id) == 36, + "offset of TexImage3D pixels_shm_id should be 36"); +static_assert(offsetof(TexImage3D, pixels_shm_offset) == 40, + "offset of TexImage3D pixels_shm_offset should be 40"); struct TexParameterf { typedef TexParameterf ValueType; @@ -4955,15 +7858,16 @@ struct TexParameterf { float param; }; -COMPILE_ASSERT(sizeof(TexParameterf) == 16, Sizeof_TexParameterf_is_not_16); -COMPILE_ASSERT(offsetof(TexParameterf, header) == 0, - OffsetOf_TexParameterf_header_not_0); -COMPILE_ASSERT(offsetof(TexParameterf, target) == 4, - OffsetOf_TexParameterf_target_not_4); -COMPILE_ASSERT(offsetof(TexParameterf, pname) == 8, - OffsetOf_TexParameterf_pname_not_8); -COMPILE_ASSERT(offsetof(TexParameterf, param) == 12, - OffsetOf_TexParameterf_param_not_12); +static_assert(sizeof(TexParameterf) == 16, + "size of TexParameterf should be 16"); +static_assert(offsetof(TexParameterf, header) == 0, + "offset of TexParameterf header should be 0"); +static_assert(offsetof(TexParameterf, target) == 4, + "offset of TexParameterf target should be 4"); +static_assert(offsetof(TexParameterf, pname) == 8, + "offset of TexParameterf pname should be 8"); +static_assert(offsetof(TexParameterf, param) == 12, + "offset of TexParameterf param should be 12"); struct TexParameterfvImmediate { typedef TexParameterfvImmediate ValueType; @@ -4972,12 +7876,11 @@ struct TexParameterfvImmediate { static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); static uint32_t ComputeDataSize() { - return static_cast<uint32_t>(sizeof(GLfloat) * 1); // NOLINT + return static_cast<uint32_t>(sizeof(GLfloat) * 1); } static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType) + - ComputeDataSize()); // NOLINT + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); } void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } @@ -5000,14 +7903,14 @@ struct TexParameterfvImmediate { uint32_t pname; }; -COMPILE_ASSERT(sizeof(TexParameterfvImmediate) == 12, - Sizeof_TexParameterfvImmediate_is_not_12); -COMPILE_ASSERT(offsetof(TexParameterfvImmediate, header) == 0, - OffsetOf_TexParameterfvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(TexParameterfvImmediate, target) == 4, - OffsetOf_TexParameterfvImmediate_target_not_4); -COMPILE_ASSERT(offsetof(TexParameterfvImmediate, pname) == 8, - OffsetOf_TexParameterfvImmediate_pname_not_8); +static_assert(sizeof(TexParameterfvImmediate) == 12, + "size of TexParameterfvImmediate should be 12"); +static_assert(offsetof(TexParameterfvImmediate, header) == 0, + "offset of TexParameterfvImmediate header should be 0"); +static_assert(offsetof(TexParameterfvImmediate, target) == 4, + "offset of TexParameterfvImmediate target should be 4"); +static_assert(offsetof(TexParameterfvImmediate, pname) == 8, + "offset of TexParameterfvImmediate pname should be 8"); struct TexParameteri { typedef TexParameteri ValueType; @@ -5039,15 +7942,16 @@ struct TexParameteri { int32_t param; }; -COMPILE_ASSERT(sizeof(TexParameteri) == 16, Sizeof_TexParameteri_is_not_16); -COMPILE_ASSERT(offsetof(TexParameteri, header) == 0, - OffsetOf_TexParameteri_header_not_0); -COMPILE_ASSERT(offsetof(TexParameteri, target) == 4, - OffsetOf_TexParameteri_target_not_4); -COMPILE_ASSERT(offsetof(TexParameteri, pname) == 8, - OffsetOf_TexParameteri_pname_not_8); -COMPILE_ASSERT(offsetof(TexParameteri, param) == 12, - OffsetOf_TexParameteri_param_not_12); +static_assert(sizeof(TexParameteri) == 16, + "size of TexParameteri should be 16"); +static_assert(offsetof(TexParameteri, header) == 0, + "offset of TexParameteri header should be 0"); +static_assert(offsetof(TexParameteri, target) == 4, + "offset of TexParameteri target should be 4"); +static_assert(offsetof(TexParameteri, pname) == 8, + "offset of TexParameteri pname should be 8"); +static_assert(offsetof(TexParameteri, param) == 12, + "offset of TexParameteri param should be 12"); struct TexParameterivImmediate { typedef TexParameterivImmediate ValueType; @@ -5056,12 +7960,11 @@ struct TexParameterivImmediate { static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); static uint32_t ComputeDataSize() { - return static_cast<uint32_t>(sizeof(GLint) * 1); // NOLINT + return static_cast<uint32_t>(sizeof(GLint) * 1); } static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType) + - ComputeDataSize()); // NOLINT + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); } void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } @@ -5084,14 +7987,78 @@ struct TexParameterivImmediate { uint32_t pname; }; -COMPILE_ASSERT(sizeof(TexParameterivImmediate) == 12, - Sizeof_TexParameterivImmediate_is_not_12); -COMPILE_ASSERT(offsetof(TexParameterivImmediate, header) == 0, - OffsetOf_TexParameterivImmediate_header_not_0); -COMPILE_ASSERT(offsetof(TexParameterivImmediate, target) == 4, - OffsetOf_TexParameterivImmediate_target_not_4); -COMPILE_ASSERT(offsetof(TexParameterivImmediate, pname) == 8, - OffsetOf_TexParameterivImmediate_pname_not_8); +static_assert(sizeof(TexParameterivImmediate) == 12, + "size of TexParameterivImmediate should be 12"); +static_assert(offsetof(TexParameterivImmediate, header) == 0, + "offset of TexParameterivImmediate header should be 0"); +static_assert(offsetof(TexParameterivImmediate, target) == 4, + "offset of TexParameterivImmediate target should be 4"); +static_assert(offsetof(TexParameterivImmediate, pname) == 8, + "offset of TexParameterivImmediate pname should be 8"); + +struct TexStorage3D { + typedef TexStorage3D ValueType; + static const CommandId kCmdId = kTexStorage3D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLsizei _levels, + GLenum _internalFormat, + GLsizei _width, + GLsizei _height, + GLsizei _depth) { + SetHeader(); + target = _target; + levels = _levels; + internalFormat = _internalFormat; + width = _width; + height = _height; + depth = _depth; + } + + void* Set(void* cmd, + GLenum _target, + GLsizei _levels, + GLenum _internalFormat, + GLsizei _width, + GLsizei _height, + GLsizei _depth) { + static_cast<ValueType*>(cmd) + ->Init(_target, _levels, _internalFormat, _width, _height, _depth); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t levels; + uint32_t internalFormat; + int32_t width; + int32_t height; + int32_t depth; +}; + +static_assert(sizeof(TexStorage3D) == 28, "size of TexStorage3D should be 28"); +static_assert(offsetof(TexStorage3D, header) == 0, + "offset of TexStorage3D header should be 0"); +static_assert(offsetof(TexStorage3D, target) == 4, + "offset of TexStorage3D target should be 4"); +static_assert(offsetof(TexStorage3D, levels) == 8, + "offset of TexStorage3D levels should be 8"); +static_assert(offsetof(TexStorage3D, internalFormat) == 12, + "offset of TexStorage3D internalFormat should be 12"); +static_assert(offsetof(TexStorage3D, width) == 16, + "offset of TexStorage3D width should be 16"); +static_assert(offsetof(TexStorage3D, height) == 20, + "offset of TexStorage3D height should be 20"); +static_assert(offsetof(TexStorage3D, depth) == 24, + "offset of TexStorage3D depth should be 24"); struct TexSubImage2D { typedef TexSubImage2D ValueType; @@ -5162,31 +8129,187 @@ struct TexSubImage2D { uint32_t internal; }; -COMPILE_ASSERT(sizeof(TexSubImage2D) == 48, Sizeof_TexSubImage2D_is_not_48); -COMPILE_ASSERT(offsetof(TexSubImage2D, header) == 0, - OffsetOf_TexSubImage2D_header_not_0); -COMPILE_ASSERT(offsetof(TexSubImage2D, target) == 4, - OffsetOf_TexSubImage2D_target_not_4); -COMPILE_ASSERT(offsetof(TexSubImage2D, level) == 8, - OffsetOf_TexSubImage2D_level_not_8); -COMPILE_ASSERT(offsetof(TexSubImage2D, xoffset) == 12, - OffsetOf_TexSubImage2D_xoffset_not_12); -COMPILE_ASSERT(offsetof(TexSubImage2D, yoffset) == 16, - OffsetOf_TexSubImage2D_yoffset_not_16); -COMPILE_ASSERT(offsetof(TexSubImage2D, width) == 20, - OffsetOf_TexSubImage2D_width_not_20); -COMPILE_ASSERT(offsetof(TexSubImage2D, height) == 24, - OffsetOf_TexSubImage2D_height_not_24); -COMPILE_ASSERT(offsetof(TexSubImage2D, format) == 28, - OffsetOf_TexSubImage2D_format_not_28); -COMPILE_ASSERT(offsetof(TexSubImage2D, type) == 32, - OffsetOf_TexSubImage2D_type_not_32); -COMPILE_ASSERT(offsetof(TexSubImage2D, pixels_shm_id) == 36, - OffsetOf_TexSubImage2D_pixels_shm_id_not_36); -COMPILE_ASSERT(offsetof(TexSubImage2D, pixels_shm_offset) == 40, - OffsetOf_TexSubImage2D_pixels_shm_offset_not_40); -COMPILE_ASSERT(offsetof(TexSubImage2D, internal) == 44, - OffsetOf_TexSubImage2D_internal_not_44); +static_assert(sizeof(TexSubImage2D) == 48, + "size of TexSubImage2D should be 48"); +static_assert(offsetof(TexSubImage2D, header) == 0, + "offset of TexSubImage2D header should be 0"); +static_assert(offsetof(TexSubImage2D, target) == 4, + "offset of TexSubImage2D target should be 4"); +static_assert(offsetof(TexSubImage2D, level) == 8, + "offset of TexSubImage2D level should be 8"); +static_assert(offsetof(TexSubImage2D, xoffset) == 12, + "offset of TexSubImage2D xoffset should be 12"); +static_assert(offsetof(TexSubImage2D, yoffset) == 16, + "offset of TexSubImage2D yoffset should be 16"); +static_assert(offsetof(TexSubImage2D, width) == 20, + "offset of TexSubImage2D width should be 20"); +static_assert(offsetof(TexSubImage2D, height) == 24, + "offset of TexSubImage2D height should be 24"); +static_assert(offsetof(TexSubImage2D, format) == 28, + "offset of TexSubImage2D format should be 28"); +static_assert(offsetof(TexSubImage2D, type) == 32, + "offset of TexSubImage2D type should be 32"); +static_assert(offsetof(TexSubImage2D, pixels_shm_id) == 36, + "offset of TexSubImage2D pixels_shm_id should be 36"); +static_assert(offsetof(TexSubImage2D, pixels_shm_offset) == 40, + "offset of TexSubImage2D pixels_shm_offset should be 40"); +static_assert(offsetof(TexSubImage2D, internal) == 44, + "offset of TexSubImage2D internal should be 44"); + +struct TexSubImage3D { + typedef TexSubImage3D ValueType; + static const CommandId kCmdId = kTexSubImage3D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLint _level, + GLint _xoffset, + GLint _yoffset, + GLint _zoffset, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLenum _format, + GLenum _type, + uint32_t _pixels_shm_id, + uint32_t _pixels_shm_offset, + GLboolean _internal) { + SetHeader(); + target = _target; + level = _level; + xoffset = _xoffset; + yoffset = _yoffset; + zoffset = _zoffset; + width = _width; + height = _height; + depth = _depth; + format = _format; + type = _type; + pixels_shm_id = _pixels_shm_id; + pixels_shm_offset = _pixels_shm_offset; + internal = _internal; + } + + void* Set(void* cmd, + GLenum _target, + GLint _level, + GLint _xoffset, + GLint _yoffset, + GLint _zoffset, + GLsizei _width, + GLsizei _height, + GLsizei _depth, + GLenum _format, + GLenum _type, + uint32_t _pixels_shm_id, + uint32_t _pixels_shm_offset, + GLboolean _internal) { + static_cast<ValueType*>(cmd)->Init( + _target, _level, _xoffset, _yoffset, _zoffset, _width, _height, _depth, + _format, _type, _pixels_shm_id, _pixels_shm_offset, _internal); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t level; + int32_t xoffset; + int32_t yoffset; + int32_t zoffset; + int32_t width; + int32_t height; + int32_t depth; + uint32_t format; + uint32_t type; + uint32_t pixels_shm_id; + uint32_t pixels_shm_offset; + uint32_t internal; +}; + +static_assert(sizeof(TexSubImage3D) == 56, + "size of TexSubImage3D should be 56"); +static_assert(offsetof(TexSubImage3D, header) == 0, + "offset of TexSubImage3D header should be 0"); +static_assert(offsetof(TexSubImage3D, target) == 4, + "offset of TexSubImage3D target should be 4"); +static_assert(offsetof(TexSubImage3D, level) == 8, + "offset of TexSubImage3D level should be 8"); +static_assert(offsetof(TexSubImage3D, xoffset) == 12, + "offset of TexSubImage3D xoffset should be 12"); +static_assert(offsetof(TexSubImage3D, yoffset) == 16, + "offset of TexSubImage3D yoffset should be 16"); +static_assert(offsetof(TexSubImage3D, zoffset) == 20, + "offset of TexSubImage3D zoffset should be 20"); +static_assert(offsetof(TexSubImage3D, width) == 24, + "offset of TexSubImage3D width should be 24"); +static_assert(offsetof(TexSubImage3D, height) == 28, + "offset of TexSubImage3D height should be 28"); +static_assert(offsetof(TexSubImage3D, depth) == 32, + "offset of TexSubImage3D depth should be 32"); +static_assert(offsetof(TexSubImage3D, format) == 36, + "offset of TexSubImage3D format should be 36"); +static_assert(offsetof(TexSubImage3D, type) == 40, + "offset of TexSubImage3D type should be 40"); +static_assert(offsetof(TexSubImage3D, pixels_shm_id) == 44, + "offset of TexSubImage3D pixels_shm_id should be 44"); +static_assert(offsetof(TexSubImage3D, pixels_shm_offset) == 48, + "offset of TexSubImage3D pixels_shm_offset should be 48"); +static_assert(offsetof(TexSubImage3D, internal) == 52, + "offset of TexSubImage3D internal should be 52"); + +struct TransformFeedbackVaryingsBucket { + typedef TransformFeedbackVaryingsBucket ValueType; + static const CommandId kCmdId = kTransformFeedbackVaryingsBucket; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, uint32_t _varyings_bucket_id, GLenum _buffermode) { + SetHeader(); + program = _program; + varyings_bucket_id = _varyings_bucket_id; + buffermode = _buffermode; + } + + void* Set(void* cmd, + GLuint _program, + uint32_t _varyings_bucket_id, + GLenum _buffermode) { + static_cast<ValueType*>(cmd) + ->Init(_program, _varyings_bucket_id, _buffermode); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t varyings_bucket_id; + uint32_t buffermode; +}; + +static_assert(sizeof(TransformFeedbackVaryingsBucket) == 16, + "size of TransformFeedbackVaryingsBucket should be 16"); +static_assert(offsetof(TransformFeedbackVaryingsBucket, header) == 0, + "offset of TransformFeedbackVaryingsBucket header should be 0"); +static_assert(offsetof(TransformFeedbackVaryingsBucket, program) == 4, + "offset of TransformFeedbackVaryingsBucket program should be 4"); +static_assert( + offsetof(TransformFeedbackVaryingsBucket, varyings_bucket_id) == 8, + "offset of TransformFeedbackVaryingsBucket varyings_bucket_id should be 8"); +static_assert( + offsetof(TransformFeedbackVaryingsBucket, buffermode) == 12, + "offset of TransformFeedbackVaryingsBucket buffermode should be 12"); struct Uniform1f { typedef Uniform1f ValueType; @@ -5216,12 +8339,12 @@ struct Uniform1f { float x; }; -COMPILE_ASSERT(sizeof(Uniform1f) == 12, Sizeof_Uniform1f_is_not_12); -COMPILE_ASSERT(offsetof(Uniform1f, header) == 0, - OffsetOf_Uniform1f_header_not_0); -COMPILE_ASSERT(offsetof(Uniform1f, location) == 4, - OffsetOf_Uniform1f_location_not_4); -COMPILE_ASSERT(offsetof(Uniform1f, x) == 8, OffsetOf_Uniform1f_x_not_8); +static_assert(sizeof(Uniform1f) == 12, "size of Uniform1f should be 12"); +static_assert(offsetof(Uniform1f, header) == 0, + "offset of Uniform1f header should be 0"); +static_assert(offsetof(Uniform1f, location) == 4, + "offset of Uniform1f location should be 4"); +static_assert(offsetof(Uniform1f, x) == 8, "offset of Uniform1f x should be 8"); struct Uniform1fvImmediate { typedef Uniform1fvImmediate ValueType; @@ -5260,14 +8383,14 @@ struct Uniform1fvImmediate { int32_t count; }; -COMPILE_ASSERT(sizeof(Uniform1fvImmediate) == 12, - Sizeof_Uniform1fvImmediate_is_not_12); -COMPILE_ASSERT(offsetof(Uniform1fvImmediate, header) == 0, - OffsetOf_Uniform1fvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(Uniform1fvImmediate, location) == 4, - OffsetOf_Uniform1fvImmediate_location_not_4); -COMPILE_ASSERT(offsetof(Uniform1fvImmediate, count) == 8, - OffsetOf_Uniform1fvImmediate_count_not_8); +static_assert(sizeof(Uniform1fvImmediate) == 12, + "size of Uniform1fvImmediate should be 12"); +static_assert(offsetof(Uniform1fvImmediate, header) == 0, + "offset of Uniform1fvImmediate header should be 0"); +static_assert(offsetof(Uniform1fvImmediate, location) == 4, + "offset of Uniform1fvImmediate location should be 4"); +static_assert(offsetof(Uniform1fvImmediate, count) == 8, + "offset of Uniform1fvImmediate count should be 8"); struct Uniform1i { typedef Uniform1i ValueType; @@ -5297,12 +8420,12 @@ struct Uniform1i { int32_t x; }; -COMPILE_ASSERT(sizeof(Uniform1i) == 12, Sizeof_Uniform1i_is_not_12); -COMPILE_ASSERT(offsetof(Uniform1i, header) == 0, - OffsetOf_Uniform1i_header_not_0); -COMPILE_ASSERT(offsetof(Uniform1i, location) == 4, - OffsetOf_Uniform1i_location_not_4); -COMPILE_ASSERT(offsetof(Uniform1i, x) == 8, OffsetOf_Uniform1i_x_not_8); +static_assert(sizeof(Uniform1i) == 12, "size of Uniform1i should be 12"); +static_assert(offsetof(Uniform1i, header) == 0, + "offset of Uniform1i header should be 0"); +static_assert(offsetof(Uniform1i, location) == 4, + "offset of Uniform1i location should be 4"); +static_assert(offsetof(Uniform1i, x) == 8, "offset of Uniform1i x should be 8"); struct Uniform1ivImmediate { typedef Uniform1ivImmediate ValueType; @@ -5341,14 +8464,96 @@ struct Uniform1ivImmediate { int32_t count; }; -COMPILE_ASSERT(sizeof(Uniform1ivImmediate) == 12, - Sizeof_Uniform1ivImmediate_is_not_12); -COMPILE_ASSERT(offsetof(Uniform1ivImmediate, header) == 0, - OffsetOf_Uniform1ivImmediate_header_not_0); -COMPILE_ASSERT(offsetof(Uniform1ivImmediate, location) == 4, - OffsetOf_Uniform1ivImmediate_location_not_4); -COMPILE_ASSERT(offsetof(Uniform1ivImmediate, count) == 8, - OffsetOf_Uniform1ivImmediate_count_not_8); +static_assert(sizeof(Uniform1ivImmediate) == 12, + "size of Uniform1ivImmediate should be 12"); +static_assert(offsetof(Uniform1ivImmediate, header) == 0, + "offset of Uniform1ivImmediate header should be 0"); +static_assert(offsetof(Uniform1ivImmediate, location) == 4, + "offset of Uniform1ivImmediate location should be 4"); +static_assert(offsetof(Uniform1ivImmediate, count) == 8, + "offset of Uniform1ivImmediate count should be 8"); + +struct Uniform1ui { + typedef Uniform1ui ValueType; + static const CommandId kCmdId = kUniform1ui; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLint _location, GLuint _x) { + SetHeader(); + location = _location; + x = _x; + } + + void* Set(void* cmd, GLint _location, GLuint _x) { + static_cast<ValueType*>(cmd)->Init(_location, _x); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + int32_t location; + uint32_t x; +}; + +static_assert(sizeof(Uniform1ui) == 12, "size of Uniform1ui should be 12"); +static_assert(offsetof(Uniform1ui, header) == 0, + "offset of Uniform1ui header should be 0"); +static_assert(offsetof(Uniform1ui, location) == 4, + "offset of Uniform1ui location should be 4"); +static_assert(offsetof(Uniform1ui, x) == 8, + "offset of Uniform1ui x should be 8"); + +struct Uniform1uivImmediate { + typedef Uniform1uivImmediate ValueType; + static const CommandId kCmdId = kUniform1uivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLuint) * 1 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLuint* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLuint* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t location; + int32_t count; +}; + +static_assert(sizeof(Uniform1uivImmediate) == 12, + "size of Uniform1uivImmediate should be 12"); +static_assert(offsetof(Uniform1uivImmediate, header) == 0, + "offset of Uniform1uivImmediate header should be 0"); +static_assert(offsetof(Uniform1uivImmediate, location) == 4, + "offset of Uniform1uivImmediate location should be 4"); +static_assert(offsetof(Uniform1uivImmediate, count) == 8, + "offset of Uniform1uivImmediate count should be 8"); struct Uniform2f { typedef Uniform2f ValueType; @@ -5380,13 +8585,14 @@ struct Uniform2f { float y; }; -COMPILE_ASSERT(sizeof(Uniform2f) == 16, Sizeof_Uniform2f_is_not_16); -COMPILE_ASSERT(offsetof(Uniform2f, header) == 0, - OffsetOf_Uniform2f_header_not_0); -COMPILE_ASSERT(offsetof(Uniform2f, location) == 4, - OffsetOf_Uniform2f_location_not_4); -COMPILE_ASSERT(offsetof(Uniform2f, x) == 8, OffsetOf_Uniform2f_x_not_8); -COMPILE_ASSERT(offsetof(Uniform2f, y) == 12, OffsetOf_Uniform2f_y_not_12); +static_assert(sizeof(Uniform2f) == 16, "size of Uniform2f should be 16"); +static_assert(offsetof(Uniform2f, header) == 0, + "offset of Uniform2f header should be 0"); +static_assert(offsetof(Uniform2f, location) == 4, + "offset of Uniform2f location should be 4"); +static_assert(offsetof(Uniform2f, x) == 8, "offset of Uniform2f x should be 8"); +static_assert(offsetof(Uniform2f, y) == 12, + "offset of Uniform2f y should be 12"); struct Uniform2fvImmediate { typedef Uniform2fvImmediate ValueType; @@ -5425,14 +8631,14 @@ struct Uniform2fvImmediate { int32_t count; }; -COMPILE_ASSERT(sizeof(Uniform2fvImmediate) == 12, - Sizeof_Uniform2fvImmediate_is_not_12); -COMPILE_ASSERT(offsetof(Uniform2fvImmediate, header) == 0, - OffsetOf_Uniform2fvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(Uniform2fvImmediate, location) == 4, - OffsetOf_Uniform2fvImmediate_location_not_4); -COMPILE_ASSERT(offsetof(Uniform2fvImmediate, count) == 8, - OffsetOf_Uniform2fvImmediate_count_not_8); +static_assert(sizeof(Uniform2fvImmediate) == 12, + "size of Uniform2fvImmediate should be 12"); +static_assert(offsetof(Uniform2fvImmediate, header) == 0, + "offset of Uniform2fvImmediate header should be 0"); +static_assert(offsetof(Uniform2fvImmediate, location) == 4, + "offset of Uniform2fvImmediate location should be 4"); +static_assert(offsetof(Uniform2fvImmediate, count) == 8, + "offset of Uniform2fvImmediate count should be 8"); struct Uniform2i { typedef Uniform2i ValueType; @@ -5464,13 +8670,14 @@ struct Uniform2i { int32_t y; }; -COMPILE_ASSERT(sizeof(Uniform2i) == 16, Sizeof_Uniform2i_is_not_16); -COMPILE_ASSERT(offsetof(Uniform2i, header) == 0, - OffsetOf_Uniform2i_header_not_0); -COMPILE_ASSERT(offsetof(Uniform2i, location) == 4, - OffsetOf_Uniform2i_location_not_4); -COMPILE_ASSERT(offsetof(Uniform2i, x) == 8, OffsetOf_Uniform2i_x_not_8); -COMPILE_ASSERT(offsetof(Uniform2i, y) == 12, OffsetOf_Uniform2i_y_not_12); +static_assert(sizeof(Uniform2i) == 16, "size of Uniform2i should be 16"); +static_assert(offsetof(Uniform2i, header) == 0, + "offset of Uniform2i header should be 0"); +static_assert(offsetof(Uniform2i, location) == 4, + "offset of Uniform2i location should be 4"); +static_assert(offsetof(Uniform2i, x) == 8, "offset of Uniform2i x should be 8"); +static_assert(offsetof(Uniform2i, y) == 12, + "offset of Uniform2i y should be 12"); struct Uniform2ivImmediate { typedef Uniform2ivImmediate ValueType; @@ -5509,14 +8716,100 @@ struct Uniform2ivImmediate { int32_t count; }; -COMPILE_ASSERT(sizeof(Uniform2ivImmediate) == 12, - Sizeof_Uniform2ivImmediate_is_not_12); -COMPILE_ASSERT(offsetof(Uniform2ivImmediate, header) == 0, - OffsetOf_Uniform2ivImmediate_header_not_0); -COMPILE_ASSERT(offsetof(Uniform2ivImmediate, location) == 4, - OffsetOf_Uniform2ivImmediate_location_not_4); -COMPILE_ASSERT(offsetof(Uniform2ivImmediate, count) == 8, - OffsetOf_Uniform2ivImmediate_count_not_8); +static_assert(sizeof(Uniform2ivImmediate) == 12, + "size of Uniform2ivImmediate should be 12"); +static_assert(offsetof(Uniform2ivImmediate, header) == 0, + "offset of Uniform2ivImmediate header should be 0"); +static_assert(offsetof(Uniform2ivImmediate, location) == 4, + "offset of Uniform2ivImmediate location should be 4"); +static_assert(offsetof(Uniform2ivImmediate, count) == 8, + "offset of Uniform2ivImmediate count should be 8"); + +struct Uniform2ui { + typedef Uniform2ui ValueType; + static const CommandId kCmdId = kUniform2ui; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLint _location, GLuint _x, GLuint _y) { + SetHeader(); + location = _location; + x = _x; + y = _y; + } + + void* Set(void* cmd, GLint _location, GLuint _x, GLuint _y) { + static_cast<ValueType*>(cmd)->Init(_location, _x, _y); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + int32_t location; + uint32_t x; + uint32_t y; +}; + +static_assert(sizeof(Uniform2ui) == 16, "size of Uniform2ui should be 16"); +static_assert(offsetof(Uniform2ui, header) == 0, + "offset of Uniform2ui header should be 0"); +static_assert(offsetof(Uniform2ui, location) == 4, + "offset of Uniform2ui location should be 4"); +static_assert(offsetof(Uniform2ui, x) == 8, + "offset of Uniform2ui x should be 8"); +static_assert(offsetof(Uniform2ui, y) == 12, + "offset of Uniform2ui y should be 12"); + +struct Uniform2uivImmediate { + typedef Uniform2uivImmediate ValueType; + static const CommandId kCmdId = kUniform2uivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLuint) * 2 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLuint* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLuint* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t location; + int32_t count; +}; + +static_assert(sizeof(Uniform2uivImmediate) == 12, + "size of Uniform2uivImmediate should be 12"); +static_assert(offsetof(Uniform2uivImmediate, header) == 0, + "offset of Uniform2uivImmediate header should be 0"); +static_assert(offsetof(Uniform2uivImmediate, location) == 4, + "offset of Uniform2uivImmediate location should be 4"); +static_assert(offsetof(Uniform2uivImmediate, count) == 8, + "offset of Uniform2uivImmediate count should be 8"); struct Uniform3f { typedef Uniform3f ValueType; @@ -5550,14 +8843,16 @@ struct Uniform3f { float z; }; -COMPILE_ASSERT(sizeof(Uniform3f) == 20, Sizeof_Uniform3f_is_not_20); -COMPILE_ASSERT(offsetof(Uniform3f, header) == 0, - OffsetOf_Uniform3f_header_not_0); -COMPILE_ASSERT(offsetof(Uniform3f, location) == 4, - OffsetOf_Uniform3f_location_not_4); -COMPILE_ASSERT(offsetof(Uniform3f, x) == 8, OffsetOf_Uniform3f_x_not_8); -COMPILE_ASSERT(offsetof(Uniform3f, y) == 12, OffsetOf_Uniform3f_y_not_12); -COMPILE_ASSERT(offsetof(Uniform3f, z) == 16, OffsetOf_Uniform3f_z_not_16); +static_assert(sizeof(Uniform3f) == 20, "size of Uniform3f should be 20"); +static_assert(offsetof(Uniform3f, header) == 0, + "offset of Uniform3f header should be 0"); +static_assert(offsetof(Uniform3f, location) == 4, + "offset of Uniform3f location should be 4"); +static_assert(offsetof(Uniform3f, x) == 8, "offset of Uniform3f x should be 8"); +static_assert(offsetof(Uniform3f, y) == 12, + "offset of Uniform3f y should be 12"); +static_assert(offsetof(Uniform3f, z) == 16, + "offset of Uniform3f z should be 16"); struct Uniform3fvImmediate { typedef Uniform3fvImmediate ValueType; @@ -5596,14 +8891,14 @@ struct Uniform3fvImmediate { int32_t count; }; -COMPILE_ASSERT(sizeof(Uniform3fvImmediate) == 12, - Sizeof_Uniform3fvImmediate_is_not_12); -COMPILE_ASSERT(offsetof(Uniform3fvImmediate, header) == 0, - OffsetOf_Uniform3fvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(Uniform3fvImmediate, location) == 4, - OffsetOf_Uniform3fvImmediate_location_not_4); -COMPILE_ASSERT(offsetof(Uniform3fvImmediate, count) == 8, - OffsetOf_Uniform3fvImmediate_count_not_8); +static_assert(sizeof(Uniform3fvImmediate) == 12, + "size of Uniform3fvImmediate should be 12"); +static_assert(offsetof(Uniform3fvImmediate, header) == 0, + "offset of Uniform3fvImmediate header should be 0"); +static_assert(offsetof(Uniform3fvImmediate, location) == 4, + "offset of Uniform3fvImmediate location should be 4"); +static_assert(offsetof(Uniform3fvImmediate, count) == 8, + "offset of Uniform3fvImmediate count should be 8"); struct Uniform3i { typedef Uniform3i ValueType; @@ -5637,14 +8932,16 @@ struct Uniform3i { int32_t z; }; -COMPILE_ASSERT(sizeof(Uniform3i) == 20, Sizeof_Uniform3i_is_not_20); -COMPILE_ASSERT(offsetof(Uniform3i, header) == 0, - OffsetOf_Uniform3i_header_not_0); -COMPILE_ASSERT(offsetof(Uniform3i, location) == 4, - OffsetOf_Uniform3i_location_not_4); -COMPILE_ASSERT(offsetof(Uniform3i, x) == 8, OffsetOf_Uniform3i_x_not_8); -COMPILE_ASSERT(offsetof(Uniform3i, y) == 12, OffsetOf_Uniform3i_y_not_12); -COMPILE_ASSERT(offsetof(Uniform3i, z) == 16, OffsetOf_Uniform3i_z_not_16); +static_assert(sizeof(Uniform3i) == 20, "size of Uniform3i should be 20"); +static_assert(offsetof(Uniform3i, header) == 0, + "offset of Uniform3i header should be 0"); +static_assert(offsetof(Uniform3i, location) == 4, + "offset of Uniform3i location should be 4"); +static_assert(offsetof(Uniform3i, x) == 8, "offset of Uniform3i x should be 8"); +static_assert(offsetof(Uniform3i, y) == 12, + "offset of Uniform3i y should be 12"); +static_assert(offsetof(Uniform3i, z) == 16, + "offset of Uniform3i z should be 16"); struct Uniform3ivImmediate { typedef Uniform3ivImmediate ValueType; @@ -5683,14 +8980,104 @@ struct Uniform3ivImmediate { int32_t count; }; -COMPILE_ASSERT(sizeof(Uniform3ivImmediate) == 12, - Sizeof_Uniform3ivImmediate_is_not_12); -COMPILE_ASSERT(offsetof(Uniform3ivImmediate, header) == 0, - OffsetOf_Uniform3ivImmediate_header_not_0); -COMPILE_ASSERT(offsetof(Uniform3ivImmediate, location) == 4, - OffsetOf_Uniform3ivImmediate_location_not_4); -COMPILE_ASSERT(offsetof(Uniform3ivImmediate, count) == 8, - OffsetOf_Uniform3ivImmediate_count_not_8); +static_assert(sizeof(Uniform3ivImmediate) == 12, + "size of Uniform3ivImmediate should be 12"); +static_assert(offsetof(Uniform3ivImmediate, header) == 0, + "offset of Uniform3ivImmediate header should be 0"); +static_assert(offsetof(Uniform3ivImmediate, location) == 4, + "offset of Uniform3ivImmediate location should be 4"); +static_assert(offsetof(Uniform3ivImmediate, count) == 8, + "offset of Uniform3ivImmediate count should be 8"); + +struct Uniform3ui { + typedef Uniform3ui ValueType; + static const CommandId kCmdId = kUniform3ui; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLint _location, GLuint _x, GLuint _y, GLuint _z) { + SetHeader(); + location = _location; + x = _x; + y = _y; + z = _z; + } + + void* Set(void* cmd, GLint _location, GLuint _x, GLuint _y, GLuint _z) { + static_cast<ValueType*>(cmd)->Init(_location, _x, _y, _z); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + int32_t location; + uint32_t x; + uint32_t y; + uint32_t z; +}; + +static_assert(sizeof(Uniform3ui) == 20, "size of Uniform3ui should be 20"); +static_assert(offsetof(Uniform3ui, header) == 0, + "offset of Uniform3ui header should be 0"); +static_assert(offsetof(Uniform3ui, location) == 4, + "offset of Uniform3ui location should be 4"); +static_assert(offsetof(Uniform3ui, x) == 8, + "offset of Uniform3ui x should be 8"); +static_assert(offsetof(Uniform3ui, y) == 12, + "offset of Uniform3ui y should be 12"); +static_assert(offsetof(Uniform3ui, z) == 16, + "offset of Uniform3ui z should be 16"); + +struct Uniform3uivImmediate { + typedef Uniform3uivImmediate ValueType; + static const CommandId kCmdId = kUniform3uivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLuint) * 3 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLuint* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLuint* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t location; + int32_t count; +}; + +static_assert(sizeof(Uniform3uivImmediate) == 12, + "size of Uniform3uivImmediate should be 12"); +static_assert(offsetof(Uniform3uivImmediate, header) == 0, + "offset of Uniform3uivImmediate header should be 0"); +static_assert(offsetof(Uniform3uivImmediate, location) == 4, + "offset of Uniform3uivImmediate location should be 4"); +static_assert(offsetof(Uniform3uivImmediate, count) == 8, + "offset of Uniform3uivImmediate count should be 8"); struct Uniform4f { typedef Uniform4f ValueType; @@ -5731,15 +9118,18 @@ struct Uniform4f { float w; }; -COMPILE_ASSERT(sizeof(Uniform4f) == 24, Sizeof_Uniform4f_is_not_24); -COMPILE_ASSERT(offsetof(Uniform4f, header) == 0, - OffsetOf_Uniform4f_header_not_0); -COMPILE_ASSERT(offsetof(Uniform4f, location) == 4, - OffsetOf_Uniform4f_location_not_4); -COMPILE_ASSERT(offsetof(Uniform4f, x) == 8, OffsetOf_Uniform4f_x_not_8); -COMPILE_ASSERT(offsetof(Uniform4f, y) == 12, OffsetOf_Uniform4f_y_not_12); -COMPILE_ASSERT(offsetof(Uniform4f, z) == 16, OffsetOf_Uniform4f_z_not_16); -COMPILE_ASSERT(offsetof(Uniform4f, w) == 20, OffsetOf_Uniform4f_w_not_20); +static_assert(sizeof(Uniform4f) == 24, "size of Uniform4f should be 24"); +static_assert(offsetof(Uniform4f, header) == 0, + "offset of Uniform4f header should be 0"); +static_assert(offsetof(Uniform4f, location) == 4, + "offset of Uniform4f location should be 4"); +static_assert(offsetof(Uniform4f, x) == 8, "offset of Uniform4f x should be 8"); +static_assert(offsetof(Uniform4f, y) == 12, + "offset of Uniform4f y should be 12"); +static_assert(offsetof(Uniform4f, z) == 16, + "offset of Uniform4f z should be 16"); +static_assert(offsetof(Uniform4f, w) == 20, + "offset of Uniform4f w should be 20"); struct Uniform4fvImmediate { typedef Uniform4fvImmediate ValueType; @@ -5778,14 +9168,14 @@ struct Uniform4fvImmediate { int32_t count; }; -COMPILE_ASSERT(sizeof(Uniform4fvImmediate) == 12, - Sizeof_Uniform4fvImmediate_is_not_12); -COMPILE_ASSERT(offsetof(Uniform4fvImmediate, header) == 0, - OffsetOf_Uniform4fvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(Uniform4fvImmediate, location) == 4, - OffsetOf_Uniform4fvImmediate_location_not_4); -COMPILE_ASSERT(offsetof(Uniform4fvImmediate, count) == 8, - OffsetOf_Uniform4fvImmediate_count_not_8); +static_assert(sizeof(Uniform4fvImmediate) == 12, + "size of Uniform4fvImmediate should be 12"); +static_assert(offsetof(Uniform4fvImmediate, header) == 0, + "offset of Uniform4fvImmediate header should be 0"); +static_assert(offsetof(Uniform4fvImmediate, location) == 4, + "offset of Uniform4fvImmediate location should be 4"); +static_assert(offsetof(Uniform4fvImmediate, count) == 8, + "offset of Uniform4fvImmediate count should be 8"); struct Uniform4i { typedef Uniform4i ValueType; @@ -5826,15 +9216,18 @@ struct Uniform4i { int32_t w; }; -COMPILE_ASSERT(sizeof(Uniform4i) == 24, Sizeof_Uniform4i_is_not_24); -COMPILE_ASSERT(offsetof(Uniform4i, header) == 0, - OffsetOf_Uniform4i_header_not_0); -COMPILE_ASSERT(offsetof(Uniform4i, location) == 4, - OffsetOf_Uniform4i_location_not_4); -COMPILE_ASSERT(offsetof(Uniform4i, x) == 8, OffsetOf_Uniform4i_x_not_8); -COMPILE_ASSERT(offsetof(Uniform4i, y) == 12, OffsetOf_Uniform4i_y_not_12); -COMPILE_ASSERT(offsetof(Uniform4i, z) == 16, OffsetOf_Uniform4i_z_not_16); -COMPILE_ASSERT(offsetof(Uniform4i, w) == 20, OffsetOf_Uniform4i_w_not_20); +static_assert(sizeof(Uniform4i) == 24, "size of Uniform4i should be 24"); +static_assert(offsetof(Uniform4i, header) == 0, + "offset of Uniform4i header should be 0"); +static_assert(offsetof(Uniform4i, location) == 4, + "offset of Uniform4i location should be 4"); +static_assert(offsetof(Uniform4i, x) == 8, "offset of Uniform4i x should be 8"); +static_assert(offsetof(Uniform4i, y) == 12, + "offset of Uniform4i y should be 12"); +static_assert(offsetof(Uniform4i, z) == 16, + "offset of Uniform4i z should be 16"); +static_assert(offsetof(Uniform4i, w) == 20, + "offset of Uniform4i w should be 20"); struct Uniform4ivImmediate { typedef Uniform4ivImmediate ValueType; @@ -5873,14 +9266,154 @@ struct Uniform4ivImmediate { int32_t count; }; -COMPILE_ASSERT(sizeof(Uniform4ivImmediate) == 12, - Sizeof_Uniform4ivImmediate_is_not_12); -COMPILE_ASSERT(offsetof(Uniform4ivImmediate, header) == 0, - OffsetOf_Uniform4ivImmediate_header_not_0); -COMPILE_ASSERT(offsetof(Uniform4ivImmediate, location) == 4, - OffsetOf_Uniform4ivImmediate_location_not_4); -COMPILE_ASSERT(offsetof(Uniform4ivImmediate, count) == 8, - OffsetOf_Uniform4ivImmediate_count_not_8); +static_assert(sizeof(Uniform4ivImmediate) == 12, + "size of Uniform4ivImmediate should be 12"); +static_assert(offsetof(Uniform4ivImmediate, header) == 0, + "offset of Uniform4ivImmediate header should be 0"); +static_assert(offsetof(Uniform4ivImmediate, location) == 4, + "offset of Uniform4ivImmediate location should be 4"); +static_assert(offsetof(Uniform4ivImmediate, count) == 8, + "offset of Uniform4ivImmediate count should be 8"); + +struct Uniform4ui { + typedef Uniform4ui ValueType; + static const CommandId kCmdId = kUniform4ui; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLint _location, GLuint _x, GLuint _y, GLuint _z, GLuint _w) { + SetHeader(); + location = _location; + x = _x; + y = _y; + z = _z; + w = _w; + } + + void* Set(void* cmd, + GLint _location, + GLuint _x, + GLuint _y, + GLuint _z, + GLuint _w) { + static_cast<ValueType*>(cmd)->Init(_location, _x, _y, _z, _w); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + int32_t location; + uint32_t x; + uint32_t y; + uint32_t z; + uint32_t w; +}; + +static_assert(sizeof(Uniform4ui) == 24, "size of Uniform4ui should be 24"); +static_assert(offsetof(Uniform4ui, header) == 0, + "offset of Uniform4ui header should be 0"); +static_assert(offsetof(Uniform4ui, location) == 4, + "offset of Uniform4ui location should be 4"); +static_assert(offsetof(Uniform4ui, x) == 8, + "offset of Uniform4ui x should be 8"); +static_assert(offsetof(Uniform4ui, y) == 12, + "offset of Uniform4ui y should be 12"); +static_assert(offsetof(Uniform4ui, z) == 16, + "offset of Uniform4ui z should be 16"); +static_assert(offsetof(Uniform4ui, w) == 20, + "offset of Uniform4ui w should be 20"); + +struct Uniform4uivImmediate { + typedef Uniform4uivImmediate ValueType; + static const CommandId kCmdId = kUniform4uivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLuint) * 4 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLuint* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLuint* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t location; + int32_t count; +}; + +static_assert(sizeof(Uniform4uivImmediate) == 12, + "size of Uniform4uivImmediate should be 12"); +static_assert(offsetof(Uniform4uivImmediate, header) == 0, + "offset of Uniform4uivImmediate header should be 0"); +static_assert(offsetof(Uniform4uivImmediate, location) == 4, + "offset of Uniform4uivImmediate location should be 4"); +static_assert(offsetof(Uniform4uivImmediate, count) == 8, + "offset of Uniform4uivImmediate count should be 8"); + +struct UniformBlockBinding { + typedef UniformBlockBinding ValueType; + static const CommandId kCmdId = kUniformBlockBinding; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, GLuint _index, GLuint _binding) { + SetHeader(); + program = _program; + index = _index; + binding = _binding; + } + + void* Set(void* cmd, GLuint _program, GLuint _index, GLuint _binding) { + static_cast<ValueType*>(cmd)->Init(_program, _index, _binding); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t index; + uint32_t binding; +}; + +static_assert(sizeof(UniformBlockBinding) == 16, + "size of UniformBlockBinding should be 16"); +static_assert(offsetof(UniformBlockBinding, header) == 0, + "offset of UniformBlockBinding header should be 0"); +static_assert(offsetof(UniformBlockBinding, program) == 4, + "offset of UniformBlockBinding program should be 4"); +static_assert(offsetof(UniformBlockBinding, index) == 8, + "offset of UniformBlockBinding index should be 8"); +static_assert(offsetof(UniformBlockBinding, binding) == 12, + "offset of UniformBlockBinding binding should be 12"); struct UniformMatrix2fvImmediate { typedef UniformMatrix2fvImmediate ValueType; @@ -5920,14 +9453,108 @@ struct UniformMatrix2fvImmediate { static const uint32_t transpose = false; }; -COMPILE_ASSERT(sizeof(UniformMatrix2fvImmediate) == 12, - Sizeof_UniformMatrix2fvImmediate_is_not_12); -COMPILE_ASSERT(offsetof(UniformMatrix2fvImmediate, header) == 0, - OffsetOf_UniformMatrix2fvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(UniformMatrix2fvImmediate, location) == 4, - OffsetOf_UniformMatrix2fvImmediate_location_not_4); -COMPILE_ASSERT(offsetof(UniformMatrix2fvImmediate, count) == 8, - OffsetOf_UniformMatrix2fvImmediate_count_not_8); +static_assert(sizeof(UniformMatrix2fvImmediate) == 12, + "size of UniformMatrix2fvImmediate should be 12"); +static_assert(offsetof(UniformMatrix2fvImmediate, header) == 0, + "offset of UniformMatrix2fvImmediate header should be 0"); +static_assert(offsetof(UniformMatrix2fvImmediate, location) == 4, + "offset of UniformMatrix2fvImmediate location should be 4"); +static_assert(offsetof(UniformMatrix2fvImmediate, count) == 8, + "offset of UniformMatrix2fvImmediate count should be 8"); + +struct UniformMatrix2x3fvImmediate { + typedef UniformMatrix2x3fvImmediate ValueType; + static const CommandId kCmdId = kUniformMatrix2x3fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLfloat) * 6 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLfloat* _value) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), _value, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _value) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _value); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t location; + int32_t count; + static const uint32_t transpose = false; +}; + +static_assert(sizeof(UniformMatrix2x3fvImmediate) == 12, + "size of UniformMatrix2x3fvImmediate should be 12"); +static_assert(offsetof(UniformMatrix2x3fvImmediate, header) == 0, + "offset of UniformMatrix2x3fvImmediate header should be 0"); +static_assert(offsetof(UniformMatrix2x3fvImmediate, location) == 4, + "offset of UniformMatrix2x3fvImmediate location should be 4"); +static_assert(offsetof(UniformMatrix2x3fvImmediate, count) == 8, + "offset of UniformMatrix2x3fvImmediate count should be 8"); + +struct UniformMatrix2x4fvImmediate { + typedef UniformMatrix2x4fvImmediate ValueType; + static const CommandId kCmdId = kUniformMatrix2x4fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLfloat) * 8 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLfloat* _value) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), _value, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _value) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _value); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t location; + int32_t count; + static const uint32_t transpose = false; +}; + +static_assert(sizeof(UniformMatrix2x4fvImmediate) == 12, + "size of UniformMatrix2x4fvImmediate should be 12"); +static_assert(offsetof(UniformMatrix2x4fvImmediate, header) == 0, + "offset of UniformMatrix2x4fvImmediate header should be 0"); +static_assert(offsetof(UniformMatrix2x4fvImmediate, location) == 4, + "offset of UniformMatrix2x4fvImmediate location should be 4"); +static_assert(offsetof(UniformMatrix2x4fvImmediate, count) == 8, + "offset of UniformMatrix2x4fvImmediate count should be 8"); struct UniformMatrix3fvImmediate { typedef UniformMatrix3fvImmediate ValueType; @@ -5967,14 +9594,108 @@ struct UniformMatrix3fvImmediate { static const uint32_t transpose = false; }; -COMPILE_ASSERT(sizeof(UniformMatrix3fvImmediate) == 12, - Sizeof_UniformMatrix3fvImmediate_is_not_12); -COMPILE_ASSERT(offsetof(UniformMatrix3fvImmediate, header) == 0, - OffsetOf_UniformMatrix3fvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(UniformMatrix3fvImmediate, location) == 4, - OffsetOf_UniformMatrix3fvImmediate_location_not_4); -COMPILE_ASSERT(offsetof(UniformMatrix3fvImmediate, count) == 8, - OffsetOf_UniformMatrix3fvImmediate_count_not_8); +static_assert(sizeof(UniformMatrix3fvImmediate) == 12, + "size of UniformMatrix3fvImmediate should be 12"); +static_assert(offsetof(UniformMatrix3fvImmediate, header) == 0, + "offset of UniformMatrix3fvImmediate header should be 0"); +static_assert(offsetof(UniformMatrix3fvImmediate, location) == 4, + "offset of UniformMatrix3fvImmediate location should be 4"); +static_assert(offsetof(UniformMatrix3fvImmediate, count) == 8, + "offset of UniformMatrix3fvImmediate count should be 8"); + +struct UniformMatrix3x2fvImmediate { + typedef UniformMatrix3x2fvImmediate ValueType; + static const CommandId kCmdId = kUniformMatrix3x2fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLfloat) * 6 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLfloat* _value) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), _value, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _value) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _value); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t location; + int32_t count; + static const uint32_t transpose = false; +}; + +static_assert(sizeof(UniformMatrix3x2fvImmediate) == 12, + "size of UniformMatrix3x2fvImmediate should be 12"); +static_assert(offsetof(UniformMatrix3x2fvImmediate, header) == 0, + "offset of UniformMatrix3x2fvImmediate header should be 0"); +static_assert(offsetof(UniformMatrix3x2fvImmediate, location) == 4, + "offset of UniformMatrix3x2fvImmediate location should be 4"); +static_assert(offsetof(UniformMatrix3x2fvImmediate, count) == 8, + "offset of UniformMatrix3x2fvImmediate count should be 8"); + +struct UniformMatrix3x4fvImmediate { + typedef UniformMatrix3x4fvImmediate ValueType; + static const CommandId kCmdId = kUniformMatrix3x4fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLfloat) * 12 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLfloat* _value) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), _value, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _value) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _value); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t location; + int32_t count; + static const uint32_t transpose = false; +}; + +static_assert(sizeof(UniformMatrix3x4fvImmediate) == 12, + "size of UniformMatrix3x4fvImmediate should be 12"); +static_assert(offsetof(UniformMatrix3x4fvImmediate, header) == 0, + "offset of UniformMatrix3x4fvImmediate header should be 0"); +static_assert(offsetof(UniformMatrix3x4fvImmediate, location) == 4, + "offset of UniformMatrix3x4fvImmediate location should be 4"); +static_assert(offsetof(UniformMatrix3x4fvImmediate, count) == 8, + "offset of UniformMatrix3x4fvImmediate count should be 8"); struct UniformMatrix4fvImmediate { typedef UniformMatrix4fvImmediate ValueType; @@ -6014,14 +9735,108 @@ struct UniformMatrix4fvImmediate { static const uint32_t transpose = false; }; -COMPILE_ASSERT(sizeof(UniformMatrix4fvImmediate) == 12, - Sizeof_UniformMatrix4fvImmediate_is_not_12); -COMPILE_ASSERT(offsetof(UniformMatrix4fvImmediate, header) == 0, - OffsetOf_UniformMatrix4fvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(UniformMatrix4fvImmediate, location) == 4, - OffsetOf_UniformMatrix4fvImmediate_location_not_4); -COMPILE_ASSERT(offsetof(UniformMatrix4fvImmediate, count) == 8, - OffsetOf_UniformMatrix4fvImmediate_count_not_8); +static_assert(sizeof(UniformMatrix4fvImmediate) == 12, + "size of UniformMatrix4fvImmediate should be 12"); +static_assert(offsetof(UniformMatrix4fvImmediate, header) == 0, + "offset of UniformMatrix4fvImmediate header should be 0"); +static_assert(offsetof(UniformMatrix4fvImmediate, location) == 4, + "offset of UniformMatrix4fvImmediate location should be 4"); +static_assert(offsetof(UniformMatrix4fvImmediate, count) == 8, + "offset of UniformMatrix4fvImmediate count should be 8"); + +struct UniformMatrix4x2fvImmediate { + typedef UniformMatrix4x2fvImmediate ValueType; + static const CommandId kCmdId = kUniformMatrix4x2fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLfloat) * 8 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLfloat* _value) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), _value, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _value) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _value); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t location; + int32_t count; + static const uint32_t transpose = false; +}; + +static_assert(sizeof(UniformMatrix4x2fvImmediate) == 12, + "size of UniformMatrix4x2fvImmediate should be 12"); +static_assert(offsetof(UniformMatrix4x2fvImmediate, header) == 0, + "offset of UniformMatrix4x2fvImmediate header should be 0"); +static_assert(offsetof(UniformMatrix4x2fvImmediate, location) == 4, + "offset of UniformMatrix4x2fvImmediate location should be 4"); +static_assert(offsetof(UniformMatrix4x2fvImmediate, count) == 8, + "offset of UniformMatrix4x2fvImmediate count should be 8"); + +struct UniformMatrix4x3fvImmediate { + typedef UniformMatrix4x3fvImmediate ValueType; + static const CommandId kCmdId = kUniformMatrix4x3fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(GLfloat) * 12 * count); // NOLINT + } + + static uint32_t ComputeSize(GLsizei count) { + return static_cast<uint32_t>(sizeof(ValueType) + + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLfloat* _value) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), _value, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _value) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _value); + const uint32_t size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + int32_t location; + int32_t count; + static const uint32_t transpose = false; +}; + +static_assert(sizeof(UniformMatrix4x3fvImmediate) == 12, + "size of UniformMatrix4x3fvImmediate should be 12"); +static_assert(offsetof(UniformMatrix4x3fvImmediate, header) == 0, + "offset of UniformMatrix4x3fvImmediate header should be 0"); +static_assert(offsetof(UniformMatrix4x3fvImmediate, location) == 4, + "offset of UniformMatrix4x3fvImmediate location should be 4"); +static_assert(offsetof(UniformMatrix4x3fvImmediate, count) == 8, + "offset of UniformMatrix4x3fvImmediate count should be 8"); struct UseProgram { typedef UseProgram ValueType; @@ -6049,11 +9864,11 @@ struct UseProgram { uint32_t program; }; -COMPILE_ASSERT(sizeof(UseProgram) == 8, Sizeof_UseProgram_is_not_8); -COMPILE_ASSERT(offsetof(UseProgram, header) == 0, - OffsetOf_UseProgram_header_not_0); -COMPILE_ASSERT(offsetof(UseProgram, program) == 4, - OffsetOf_UseProgram_program_not_4); +static_assert(sizeof(UseProgram) == 8, "size of UseProgram should be 8"); +static_assert(offsetof(UseProgram, header) == 0, + "offset of UseProgram header should be 0"); +static_assert(offsetof(UseProgram, program) == 4, + "offset of UseProgram program should be 4"); struct ValidateProgram { typedef ValidateProgram ValueType; @@ -6081,11 +9896,12 @@ struct ValidateProgram { uint32_t program; }; -COMPILE_ASSERT(sizeof(ValidateProgram) == 8, Sizeof_ValidateProgram_is_not_8); -COMPILE_ASSERT(offsetof(ValidateProgram, header) == 0, - OffsetOf_ValidateProgram_header_not_0); -COMPILE_ASSERT(offsetof(ValidateProgram, program) == 4, - OffsetOf_ValidateProgram_program_not_4); +static_assert(sizeof(ValidateProgram) == 8, + "size of ValidateProgram should be 8"); +static_assert(offsetof(ValidateProgram, header) == 0, + "offset of ValidateProgram header should be 0"); +static_assert(offsetof(ValidateProgram, program) == 4, + "offset of ValidateProgram program should be 4"); struct VertexAttrib1f { typedef VertexAttrib1f ValueType; @@ -6115,13 +9931,14 @@ struct VertexAttrib1f { float x; }; -COMPILE_ASSERT(sizeof(VertexAttrib1f) == 12, Sizeof_VertexAttrib1f_is_not_12); -COMPILE_ASSERT(offsetof(VertexAttrib1f, header) == 0, - OffsetOf_VertexAttrib1f_header_not_0); -COMPILE_ASSERT(offsetof(VertexAttrib1f, indx) == 4, - OffsetOf_VertexAttrib1f_indx_not_4); -COMPILE_ASSERT(offsetof(VertexAttrib1f, x) == 8, - OffsetOf_VertexAttrib1f_x_not_8); +static_assert(sizeof(VertexAttrib1f) == 12, + "size of VertexAttrib1f should be 12"); +static_assert(offsetof(VertexAttrib1f, header) == 0, + "offset of VertexAttrib1f header should be 0"); +static_assert(offsetof(VertexAttrib1f, indx) == 4, + "offset of VertexAttrib1f indx should be 4"); +static_assert(offsetof(VertexAttrib1f, x) == 8, + "offset of VertexAttrib1f x should be 8"); struct VertexAttrib1fvImmediate { typedef VertexAttrib1fvImmediate ValueType; @@ -6130,12 +9947,11 @@ struct VertexAttrib1fvImmediate { static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); static uint32_t ComputeDataSize() { - return static_cast<uint32_t>(sizeof(GLfloat) * 1); // NOLINT + return static_cast<uint32_t>(sizeof(GLfloat) * 1); } static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType) + - ComputeDataSize()); // NOLINT + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); } void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } @@ -6156,12 +9972,12 @@ struct VertexAttrib1fvImmediate { uint32_t indx; }; -COMPILE_ASSERT(sizeof(VertexAttrib1fvImmediate) == 8, - Sizeof_VertexAttrib1fvImmediate_is_not_8); -COMPILE_ASSERT(offsetof(VertexAttrib1fvImmediate, header) == 0, - OffsetOf_VertexAttrib1fvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(VertexAttrib1fvImmediate, indx) == 4, - OffsetOf_VertexAttrib1fvImmediate_indx_not_4); +static_assert(sizeof(VertexAttrib1fvImmediate) == 8, + "size of VertexAttrib1fvImmediate should be 8"); +static_assert(offsetof(VertexAttrib1fvImmediate, header) == 0, + "offset of VertexAttrib1fvImmediate header should be 0"); +static_assert(offsetof(VertexAttrib1fvImmediate, indx) == 4, + "offset of VertexAttrib1fvImmediate indx should be 4"); struct VertexAttrib2f { typedef VertexAttrib2f ValueType; @@ -6193,15 +10009,16 @@ struct VertexAttrib2f { float y; }; -COMPILE_ASSERT(sizeof(VertexAttrib2f) == 16, Sizeof_VertexAttrib2f_is_not_16); -COMPILE_ASSERT(offsetof(VertexAttrib2f, header) == 0, - OffsetOf_VertexAttrib2f_header_not_0); -COMPILE_ASSERT(offsetof(VertexAttrib2f, indx) == 4, - OffsetOf_VertexAttrib2f_indx_not_4); -COMPILE_ASSERT(offsetof(VertexAttrib2f, x) == 8, - OffsetOf_VertexAttrib2f_x_not_8); -COMPILE_ASSERT(offsetof(VertexAttrib2f, y) == 12, - OffsetOf_VertexAttrib2f_y_not_12); +static_assert(sizeof(VertexAttrib2f) == 16, + "size of VertexAttrib2f should be 16"); +static_assert(offsetof(VertexAttrib2f, header) == 0, + "offset of VertexAttrib2f header should be 0"); +static_assert(offsetof(VertexAttrib2f, indx) == 4, + "offset of VertexAttrib2f indx should be 4"); +static_assert(offsetof(VertexAttrib2f, x) == 8, + "offset of VertexAttrib2f x should be 8"); +static_assert(offsetof(VertexAttrib2f, y) == 12, + "offset of VertexAttrib2f y should be 12"); struct VertexAttrib2fvImmediate { typedef VertexAttrib2fvImmediate ValueType; @@ -6210,12 +10027,11 @@ struct VertexAttrib2fvImmediate { static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); static uint32_t ComputeDataSize() { - return static_cast<uint32_t>(sizeof(GLfloat) * 2); // NOLINT + return static_cast<uint32_t>(sizeof(GLfloat) * 2); } static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType) + - ComputeDataSize()); // NOLINT + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); } void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } @@ -6236,12 +10052,12 @@ struct VertexAttrib2fvImmediate { uint32_t indx; }; -COMPILE_ASSERT(sizeof(VertexAttrib2fvImmediate) == 8, - Sizeof_VertexAttrib2fvImmediate_is_not_8); -COMPILE_ASSERT(offsetof(VertexAttrib2fvImmediate, header) == 0, - OffsetOf_VertexAttrib2fvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(VertexAttrib2fvImmediate, indx) == 4, - OffsetOf_VertexAttrib2fvImmediate_indx_not_4); +static_assert(sizeof(VertexAttrib2fvImmediate) == 8, + "size of VertexAttrib2fvImmediate should be 8"); +static_assert(offsetof(VertexAttrib2fvImmediate, header) == 0, + "offset of VertexAttrib2fvImmediate header should be 0"); +static_assert(offsetof(VertexAttrib2fvImmediate, indx) == 4, + "offset of VertexAttrib2fvImmediate indx should be 4"); struct VertexAttrib3f { typedef VertexAttrib3f ValueType; @@ -6275,17 +10091,18 @@ struct VertexAttrib3f { float z; }; -COMPILE_ASSERT(sizeof(VertexAttrib3f) == 20, Sizeof_VertexAttrib3f_is_not_20); -COMPILE_ASSERT(offsetof(VertexAttrib3f, header) == 0, - OffsetOf_VertexAttrib3f_header_not_0); -COMPILE_ASSERT(offsetof(VertexAttrib3f, indx) == 4, - OffsetOf_VertexAttrib3f_indx_not_4); -COMPILE_ASSERT(offsetof(VertexAttrib3f, x) == 8, - OffsetOf_VertexAttrib3f_x_not_8); -COMPILE_ASSERT(offsetof(VertexAttrib3f, y) == 12, - OffsetOf_VertexAttrib3f_y_not_12); -COMPILE_ASSERT(offsetof(VertexAttrib3f, z) == 16, - OffsetOf_VertexAttrib3f_z_not_16); +static_assert(sizeof(VertexAttrib3f) == 20, + "size of VertexAttrib3f should be 20"); +static_assert(offsetof(VertexAttrib3f, header) == 0, + "offset of VertexAttrib3f header should be 0"); +static_assert(offsetof(VertexAttrib3f, indx) == 4, + "offset of VertexAttrib3f indx should be 4"); +static_assert(offsetof(VertexAttrib3f, x) == 8, + "offset of VertexAttrib3f x should be 8"); +static_assert(offsetof(VertexAttrib3f, y) == 12, + "offset of VertexAttrib3f y should be 12"); +static_assert(offsetof(VertexAttrib3f, z) == 16, + "offset of VertexAttrib3f z should be 16"); struct VertexAttrib3fvImmediate { typedef VertexAttrib3fvImmediate ValueType; @@ -6294,12 +10111,11 @@ struct VertexAttrib3fvImmediate { static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); static uint32_t ComputeDataSize() { - return static_cast<uint32_t>(sizeof(GLfloat) * 3); // NOLINT + return static_cast<uint32_t>(sizeof(GLfloat) * 3); } static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType) + - ComputeDataSize()); // NOLINT + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); } void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } @@ -6320,12 +10136,12 @@ struct VertexAttrib3fvImmediate { uint32_t indx; }; -COMPILE_ASSERT(sizeof(VertexAttrib3fvImmediate) == 8, - Sizeof_VertexAttrib3fvImmediate_is_not_8); -COMPILE_ASSERT(offsetof(VertexAttrib3fvImmediate, header) == 0, - OffsetOf_VertexAttrib3fvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(VertexAttrib3fvImmediate, indx) == 4, - OffsetOf_VertexAttrib3fvImmediate_indx_not_4); +static_assert(sizeof(VertexAttrib3fvImmediate) == 8, + "size of VertexAttrib3fvImmediate should be 8"); +static_assert(offsetof(VertexAttrib3fvImmediate, header) == 0, + "offset of VertexAttrib3fvImmediate header should be 0"); +static_assert(offsetof(VertexAttrib3fvImmediate, indx) == 4, + "offset of VertexAttrib3fvImmediate indx should be 4"); struct VertexAttrib4f { typedef VertexAttrib4f ValueType; @@ -6366,19 +10182,20 @@ struct VertexAttrib4f { float w; }; -COMPILE_ASSERT(sizeof(VertexAttrib4f) == 24, Sizeof_VertexAttrib4f_is_not_24); -COMPILE_ASSERT(offsetof(VertexAttrib4f, header) == 0, - OffsetOf_VertexAttrib4f_header_not_0); -COMPILE_ASSERT(offsetof(VertexAttrib4f, indx) == 4, - OffsetOf_VertexAttrib4f_indx_not_4); -COMPILE_ASSERT(offsetof(VertexAttrib4f, x) == 8, - OffsetOf_VertexAttrib4f_x_not_8); -COMPILE_ASSERT(offsetof(VertexAttrib4f, y) == 12, - OffsetOf_VertexAttrib4f_y_not_12); -COMPILE_ASSERT(offsetof(VertexAttrib4f, z) == 16, - OffsetOf_VertexAttrib4f_z_not_16); -COMPILE_ASSERT(offsetof(VertexAttrib4f, w) == 20, - OffsetOf_VertexAttrib4f_w_not_20); +static_assert(sizeof(VertexAttrib4f) == 24, + "size of VertexAttrib4f should be 24"); +static_assert(offsetof(VertexAttrib4f, header) == 0, + "offset of VertexAttrib4f header should be 0"); +static_assert(offsetof(VertexAttrib4f, indx) == 4, + "offset of VertexAttrib4f indx should be 4"); +static_assert(offsetof(VertexAttrib4f, x) == 8, + "offset of VertexAttrib4f x should be 8"); +static_assert(offsetof(VertexAttrib4f, y) == 12, + "offset of VertexAttrib4f y should be 12"); +static_assert(offsetof(VertexAttrib4f, z) == 16, + "offset of VertexAttrib4f z should be 16"); +static_assert(offsetof(VertexAttrib4f, w) == 20, + "offset of VertexAttrib4f w should be 20"); struct VertexAttrib4fvImmediate { typedef VertexAttrib4fvImmediate ValueType; @@ -6387,12 +10204,11 @@ struct VertexAttrib4fvImmediate { static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); static uint32_t ComputeDataSize() { - return static_cast<uint32_t>(sizeof(GLfloat) * 4); // NOLINT + return static_cast<uint32_t>(sizeof(GLfloat) * 4); } static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType) + - ComputeDataSize()); // NOLINT + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); } void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } @@ -6413,12 +10229,251 @@ struct VertexAttrib4fvImmediate { uint32_t indx; }; -COMPILE_ASSERT(sizeof(VertexAttrib4fvImmediate) == 8, - Sizeof_VertexAttrib4fvImmediate_is_not_8); -COMPILE_ASSERT(offsetof(VertexAttrib4fvImmediate, header) == 0, - OffsetOf_VertexAttrib4fvImmediate_header_not_0); -COMPILE_ASSERT(offsetof(VertexAttrib4fvImmediate, indx) == 4, - OffsetOf_VertexAttrib4fvImmediate_indx_not_4); +static_assert(sizeof(VertexAttrib4fvImmediate) == 8, + "size of VertexAttrib4fvImmediate should be 8"); +static_assert(offsetof(VertexAttrib4fvImmediate, header) == 0, + "offset of VertexAttrib4fvImmediate header should be 0"); +static_assert(offsetof(VertexAttrib4fvImmediate, indx) == 4, + "offset of VertexAttrib4fvImmediate indx should be 4"); + +struct VertexAttribI4i { + typedef VertexAttribI4i ValueType; + static const CommandId kCmdId = kVertexAttribI4i; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _indx, GLint _x, GLint _y, GLint _z, GLint _w) { + SetHeader(); + indx = _indx; + x = _x; + y = _y; + z = _z; + w = _w; + } + + void* Set(void* cmd, GLuint _indx, GLint _x, GLint _y, GLint _z, GLint _w) { + static_cast<ValueType*>(cmd)->Init(_indx, _x, _y, _z, _w); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t indx; + int32_t x; + int32_t y; + int32_t z; + int32_t w; +}; + +static_assert(sizeof(VertexAttribI4i) == 24, + "size of VertexAttribI4i should be 24"); +static_assert(offsetof(VertexAttribI4i, header) == 0, + "offset of VertexAttribI4i header should be 0"); +static_assert(offsetof(VertexAttribI4i, indx) == 4, + "offset of VertexAttribI4i indx should be 4"); +static_assert(offsetof(VertexAttribI4i, x) == 8, + "offset of VertexAttribI4i x should be 8"); +static_assert(offsetof(VertexAttribI4i, y) == 12, + "offset of VertexAttribI4i y should be 12"); +static_assert(offsetof(VertexAttribI4i, z) == 16, + "offset of VertexAttribI4i z should be 16"); +static_assert(offsetof(VertexAttribI4i, w) == 20, + "offset of VertexAttribI4i w should be 20"); + +struct VertexAttribI4ivImmediate { + typedef VertexAttribI4ivImmediate ValueType; + static const CommandId kCmdId = kVertexAttribI4ivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize() { + return static_cast<uint32_t>(sizeof(GLint) * 4); + } + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); + } + + void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } + + void Init(GLuint _indx, const GLint* _values) { + SetHeader(); + indx = _indx; + memcpy(ImmediateDataAddress(this), _values, ComputeDataSize()); + } + + void* Set(void* cmd, GLuint _indx, const GLint* _values) { + static_cast<ValueType*>(cmd)->Init(_indx, _values); + const uint32_t size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + uint32_t indx; +}; + +static_assert(sizeof(VertexAttribI4ivImmediate) == 8, + "size of VertexAttribI4ivImmediate should be 8"); +static_assert(offsetof(VertexAttribI4ivImmediate, header) == 0, + "offset of VertexAttribI4ivImmediate header should be 0"); +static_assert(offsetof(VertexAttribI4ivImmediate, indx) == 4, + "offset of VertexAttribI4ivImmediate indx should be 4"); + +struct VertexAttribI4ui { + typedef VertexAttribI4ui ValueType; + static const CommandId kCmdId = kVertexAttribI4ui; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _indx, GLuint _x, GLuint _y, GLuint _z, GLuint _w) { + SetHeader(); + indx = _indx; + x = _x; + y = _y; + z = _z; + w = _w; + } + + void* Set(void* cmd, + GLuint _indx, + GLuint _x, + GLuint _y, + GLuint _z, + GLuint _w) { + static_cast<ValueType*>(cmd)->Init(_indx, _x, _y, _z, _w); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t indx; + uint32_t x; + uint32_t y; + uint32_t z; + uint32_t w; +}; + +static_assert(sizeof(VertexAttribI4ui) == 24, + "size of VertexAttribI4ui should be 24"); +static_assert(offsetof(VertexAttribI4ui, header) == 0, + "offset of VertexAttribI4ui header should be 0"); +static_assert(offsetof(VertexAttribI4ui, indx) == 4, + "offset of VertexAttribI4ui indx should be 4"); +static_assert(offsetof(VertexAttribI4ui, x) == 8, + "offset of VertexAttribI4ui x should be 8"); +static_assert(offsetof(VertexAttribI4ui, y) == 12, + "offset of VertexAttribI4ui y should be 12"); +static_assert(offsetof(VertexAttribI4ui, z) == 16, + "offset of VertexAttribI4ui z should be 16"); +static_assert(offsetof(VertexAttribI4ui, w) == 20, + "offset of VertexAttribI4ui w should be 20"); + +struct VertexAttribI4uivImmediate { + typedef VertexAttribI4uivImmediate ValueType; + static const CommandId kCmdId = kVertexAttribI4uivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeDataSize() { + return static_cast<uint32_t>(sizeof(GLuint) * 4); + } + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); + } + + void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } + + void Init(GLuint _indx, const GLuint* _values) { + SetHeader(); + indx = _indx; + memcpy(ImmediateDataAddress(this), _values, ComputeDataSize()); + } + + void* Set(void* cmd, GLuint _indx, const GLuint* _values) { + static_cast<ValueType*>(cmd)->Init(_indx, _values); + const uint32_t size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + gpu::CommandHeader header; + uint32_t indx; +}; + +static_assert(sizeof(VertexAttribI4uivImmediate) == 8, + "size of VertexAttribI4uivImmediate should be 8"); +static_assert(offsetof(VertexAttribI4uivImmediate, header) == 0, + "offset of VertexAttribI4uivImmediate header should be 0"); +static_assert(offsetof(VertexAttribI4uivImmediate, indx) == 4, + "offset of VertexAttribI4uivImmediate indx should be 4"); + +struct VertexAttribIPointer { + typedef VertexAttribIPointer ValueType; + static const CommandId kCmdId = kVertexAttribIPointer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _indx, + GLint _size, + GLenum _type, + GLsizei _stride, + GLuint _offset) { + SetHeader(); + indx = _indx; + size = _size; + type = _type; + stride = _stride; + offset = _offset; + } + + void* Set(void* cmd, + GLuint _indx, + GLint _size, + GLenum _type, + GLsizei _stride, + GLuint _offset) { + static_cast<ValueType*>(cmd)->Init(_indx, _size, _type, _stride, _offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t indx; + int32_t size; + uint32_t type; + int32_t stride; + uint32_t offset; +}; + +static_assert(sizeof(VertexAttribIPointer) == 24, + "size of VertexAttribIPointer should be 24"); +static_assert(offsetof(VertexAttribIPointer, header) == 0, + "offset of VertexAttribIPointer header should be 0"); +static_assert(offsetof(VertexAttribIPointer, indx) == 4, + "offset of VertexAttribIPointer indx should be 4"); +static_assert(offsetof(VertexAttribIPointer, size) == 8, + "offset of VertexAttribIPointer size should be 8"); +static_assert(offsetof(VertexAttribIPointer, type) == 12, + "offset of VertexAttribIPointer type should be 12"); +static_assert(offsetof(VertexAttribIPointer, stride) == 16, + "offset of VertexAttribIPointer stride should be 16"); +static_assert(offsetof(VertexAttribIPointer, offset) == 20, + "offset of VertexAttribIPointer offset should be 20"); struct VertexAttribPointer { typedef VertexAttribPointer ValueType; @@ -6468,22 +10523,22 @@ struct VertexAttribPointer { uint32_t offset; }; -COMPILE_ASSERT(sizeof(VertexAttribPointer) == 28, - Sizeof_VertexAttribPointer_is_not_28); -COMPILE_ASSERT(offsetof(VertexAttribPointer, header) == 0, - OffsetOf_VertexAttribPointer_header_not_0); -COMPILE_ASSERT(offsetof(VertexAttribPointer, indx) == 4, - OffsetOf_VertexAttribPointer_indx_not_4); -COMPILE_ASSERT(offsetof(VertexAttribPointer, size) == 8, - OffsetOf_VertexAttribPointer_size_not_8); -COMPILE_ASSERT(offsetof(VertexAttribPointer, type) == 12, - OffsetOf_VertexAttribPointer_type_not_12); -COMPILE_ASSERT(offsetof(VertexAttribPointer, normalized) == 16, - OffsetOf_VertexAttribPointer_normalized_not_16); -COMPILE_ASSERT(offsetof(VertexAttribPointer, stride) == 20, - OffsetOf_VertexAttribPointer_stride_not_20); -COMPILE_ASSERT(offsetof(VertexAttribPointer, offset) == 24, - OffsetOf_VertexAttribPointer_offset_not_24); +static_assert(sizeof(VertexAttribPointer) == 28, + "size of VertexAttribPointer should be 28"); +static_assert(offsetof(VertexAttribPointer, header) == 0, + "offset of VertexAttribPointer header should be 0"); +static_assert(offsetof(VertexAttribPointer, indx) == 4, + "offset of VertexAttribPointer indx should be 4"); +static_assert(offsetof(VertexAttribPointer, size) == 8, + "offset of VertexAttribPointer size should be 8"); +static_assert(offsetof(VertexAttribPointer, type) == 12, + "offset of VertexAttribPointer type should be 12"); +static_assert(offsetof(VertexAttribPointer, normalized) == 16, + "offset of VertexAttribPointer normalized should be 16"); +static_assert(offsetof(VertexAttribPointer, stride) == 20, + "offset of VertexAttribPointer stride should be 20"); +static_assert(offsetof(VertexAttribPointer, offset) == 24, + "offset of VertexAttribPointer offset should be 24"); struct Viewport { typedef Viewport ValueType; @@ -6517,13 +10572,66 @@ struct Viewport { int32_t height; }; -COMPILE_ASSERT(sizeof(Viewport) == 20, Sizeof_Viewport_is_not_20); -COMPILE_ASSERT(offsetof(Viewport, header) == 0, OffsetOf_Viewport_header_not_0); -COMPILE_ASSERT(offsetof(Viewport, x) == 4, OffsetOf_Viewport_x_not_4); -COMPILE_ASSERT(offsetof(Viewport, y) == 8, OffsetOf_Viewport_y_not_8); -COMPILE_ASSERT(offsetof(Viewport, width) == 12, OffsetOf_Viewport_width_not_12); -COMPILE_ASSERT(offsetof(Viewport, height) == 16, - OffsetOf_Viewport_height_not_16); +static_assert(sizeof(Viewport) == 20, "size of Viewport should be 20"); +static_assert(offsetof(Viewport, header) == 0, + "offset of Viewport header should be 0"); +static_assert(offsetof(Viewport, x) == 4, "offset of Viewport x should be 4"); +static_assert(offsetof(Viewport, y) == 8, "offset of Viewport y should be 8"); +static_assert(offsetof(Viewport, width) == 12, + "offset of Viewport width should be 12"); +static_assert(offsetof(Viewport, height) == 16, + "offset of Viewport height should be 16"); + +struct WaitSync { + typedef WaitSync ValueType; + static const CommandId kCmdId = kWaitSync; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _sync, + GLbitfield _flags, + GLuint _timeout_0, + GLuint _timeout_1) { + SetHeader(); + sync = _sync; + flags = _flags; + timeout_0 = _timeout_0; + timeout_1 = _timeout_1; + } + + void* Set(void* cmd, + GLuint _sync, + GLbitfield _flags, + GLuint _timeout_0, + GLuint _timeout_1) { + static_cast<ValueType*>(cmd)->Init(_sync, _flags, _timeout_0, _timeout_1); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t sync; + uint32_t flags; + uint32_t timeout_0; + uint32_t timeout_1; +}; + +static_assert(sizeof(WaitSync) == 20, "size of WaitSync should be 20"); +static_assert(offsetof(WaitSync, header) == 0, + "offset of WaitSync header should be 0"); +static_assert(offsetof(WaitSync, sync) == 4, + "offset of WaitSync sync should be 4"); +static_assert(offsetof(WaitSync, flags) == 8, + "offset of WaitSync flags should be 8"); +static_assert(offsetof(WaitSync, timeout_0) == 12, + "offset of WaitSync timeout_0 should be 12"); +static_assert(offsetof(WaitSync, timeout_1) == 16, + "offset of WaitSync timeout_1 should be 16"); struct BlitFramebufferCHROMIUM { typedef BlitFramebufferCHROMIUM ValueType; @@ -6589,30 +10697,30 @@ struct BlitFramebufferCHROMIUM { uint32_t filter; }; -COMPILE_ASSERT(sizeof(BlitFramebufferCHROMIUM) == 44, - Sizeof_BlitFramebufferCHROMIUM_is_not_44); -COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, header) == 0, - OffsetOf_BlitFramebufferCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, srcX0) == 4, - OffsetOf_BlitFramebufferCHROMIUM_srcX0_not_4); -COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, srcY0) == 8, - OffsetOf_BlitFramebufferCHROMIUM_srcY0_not_8); -COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, srcX1) == 12, - OffsetOf_BlitFramebufferCHROMIUM_srcX1_not_12); -COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, srcY1) == 16, - OffsetOf_BlitFramebufferCHROMIUM_srcY1_not_16); -COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, dstX0) == 20, - OffsetOf_BlitFramebufferCHROMIUM_dstX0_not_20); -COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, dstY0) == 24, - OffsetOf_BlitFramebufferCHROMIUM_dstY0_not_24); -COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, dstX1) == 28, - OffsetOf_BlitFramebufferCHROMIUM_dstX1_not_28); -COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, dstY1) == 32, - OffsetOf_BlitFramebufferCHROMIUM_dstY1_not_32); -COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, mask) == 36, - OffsetOf_BlitFramebufferCHROMIUM_mask_not_36); -COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, filter) == 40, - OffsetOf_BlitFramebufferCHROMIUM_filter_not_40); +static_assert(sizeof(BlitFramebufferCHROMIUM) == 44, + "size of BlitFramebufferCHROMIUM should be 44"); +static_assert(offsetof(BlitFramebufferCHROMIUM, header) == 0, + "offset of BlitFramebufferCHROMIUM header should be 0"); +static_assert(offsetof(BlitFramebufferCHROMIUM, srcX0) == 4, + "offset of BlitFramebufferCHROMIUM srcX0 should be 4"); +static_assert(offsetof(BlitFramebufferCHROMIUM, srcY0) == 8, + "offset of BlitFramebufferCHROMIUM srcY0 should be 8"); +static_assert(offsetof(BlitFramebufferCHROMIUM, srcX1) == 12, + "offset of BlitFramebufferCHROMIUM srcX1 should be 12"); +static_assert(offsetof(BlitFramebufferCHROMIUM, srcY1) == 16, + "offset of BlitFramebufferCHROMIUM srcY1 should be 16"); +static_assert(offsetof(BlitFramebufferCHROMIUM, dstX0) == 20, + "offset of BlitFramebufferCHROMIUM dstX0 should be 20"); +static_assert(offsetof(BlitFramebufferCHROMIUM, dstY0) == 24, + "offset of BlitFramebufferCHROMIUM dstY0 should be 24"); +static_assert(offsetof(BlitFramebufferCHROMIUM, dstX1) == 28, + "offset of BlitFramebufferCHROMIUM dstX1 should be 28"); +static_assert(offsetof(BlitFramebufferCHROMIUM, dstY1) == 32, + "offset of BlitFramebufferCHROMIUM dstY1 should be 32"); +static_assert(offsetof(BlitFramebufferCHROMIUM, mask) == 36, + "offset of BlitFramebufferCHROMIUM mask should be 36"); +static_assert(offsetof(BlitFramebufferCHROMIUM, filter) == 40, + "offset of BlitFramebufferCHROMIUM filter should be 40"); // GL_CHROMIUM_framebuffer_multisample struct RenderbufferStorageMultisampleCHROMIUM { @@ -6659,21 +10767,27 @@ struct RenderbufferStorageMultisampleCHROMIUM { int32_t height; }; -COMPILE_ASSERT(sizeof(RenderbufferStorageMultisampleCHROMIUM) == 24, - Sizeof_RenderbufferStorageMultisampleCHROMIUM_is_not_24); -COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleCHROMIUM, header) == 0, - OffsetOf_RenderbufferStorageMultisampleCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleCHROMIUM, target) == 4, - OffsetOf_RenderbufferStorageMultisampleCHROMIUM_target_not_4); -COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleCHROMIUM, samples) == 8, - OffsetOf_RenderbufferStorageMultisampleCHROMIUM_samples_not_8); -COMPILE_ASSERT( - offsetof(RenderbufferStorageMultisampleCHROMIUM, internalformat) == 12, - OffsetOf_RenderbufferStorageMultisampleCHROMIUM_internalformat_not_12); -COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleCHROMIUM, width) == 16, - OffsetOf_RenderbufferStorageMultisampleCHROMIUM_width_not_16); -COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleCHROMIUM, height) == 20, - OffsetOf_RenderbufferStorageMultisampleCHROMIUM_height_not_20); +static_assert(sizeof(RenderbufferStorageMultisampleCHROMIUM) == 24, + "size of RenderbufferStorageMultisampleCHROMIUM should be 24"); +static_assert( + offsetof(RenderbufferStorageMultisampleCHROMIUM, header) == 0, + "offset of RenderbufferStorageMultisampleCHROMIUM header should be 0"); +static_assert( + offsetof(RenderbufferStorageMultisampleCHROMIUM, target) == 4, + "offset of RenderbufferStorageMultisampleCHROMIUM target should be 4"); +static_assert( + offsetof(RenderbufferStorageMultisampleCHROMIUM, samples) == 8, + "offset of RenderbufferStorageMultisampleCHROMIUM samples should be 8"); +static_assert(offsetof(RenderbufferStorageMultisampleCHROMIUM, + internalformat) == 12, + "offset of RenderbufferStorageMultisampleCHROMIUM internalformat " + "should be 12"); +static_assert( + offsetof(RenderbufferStorageMultisampleCHROMIUM, width) == 16, + "offset of RenderbufferStorageMultisampleCHROMIUM width should be 16"); +static_assert( + offsetof(RenderbufferStorageMultisampleCHROMIUM, height) == 20, + "offset of RenderbufferStorageMultisampleCHROMIUM height should be 20"); // GL_EXT_multisampled_render_to_texture struct RenderbufferStorageMultisampleEXT { @@ -6720,21 +10834,23 @@ struct RenderbufferStorageMultisampleEXT { int32_t height; }; -COMPILE_ASSERT(sizeof(RenderbufferStorageMultisampleEXT) == 24, - Sizeof_RenderbufferStorageMultisampleEXT_is_not_24); -COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, header) == 0, - OffsetOf_RenderbufferStorageMultisampleEXT_header_not_0); -COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, target) == 4, - OffsetOf_RenderbufferStorageMultisampleEXT_target_not_4); -COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, samples) == 8, - OffsetOf_RenderbufferStorageMultisampleEXT_samples_not_8); -COMPILE_ASSERT( +static_assert(sizeof(RenderbufferStorageMultisampleEXT) == 24, + "size of RenderbufferStorageMultisampleEXT should be 24"); +static_assert(offsetof(RenderbufferStorageMultisampleEXT, header) == 0, + "offset of RenderbufferStorageMultisampleEXT header should be 0"); +static_assert(offsetof(RenderbufferStorageMultisampleEXT, target) == 4, + "offset of RenderbufferStorageMultisampleEXT target should be 4"); +static_assert( + offsetof(RenderbufferStorageMultisampleEXT, samples) == 8, + "offset of RenderbufferStorageMultisampleEXT samples should be 8"); +static_assert( offsetof(RenderbufferStorageMultisampleEXT, internalformat) == 12, - OffsetOf_RenderbufferStorageMultisampleEXT_internalformat_not_12); -COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, width) == 16, - OffsetOf_RenderbufferStorageMultisampleEXT_width_not_16); -COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, height) == 20, - OffsetOf_RenderbufferStorageMultisampleEXT_height_not_20); + "offset of RenderbufferStorageMultisampleEXT internalformat should be 12"); +static_assert(offsetof(RenderbufferStorageMultisampleEXT, width) == 16, + "offset of RenderbufferStorageMultisampleEXT width should be 16"); +static_assert( + offsetof(RenderbufferStorageMultisampleEXT, height) == 20, + "offset of RenderbufferStorageMultisampleEXT height should be 20"); struct FramebufferTexture2DMultisampleEXT { typedef FramebufferTexture2DMultisampleEXT ValueType; @@ -6781,20 +10897,26 @@ struct FramebufferTexture2DMultisampleEXT { static const int32_t level = 0; }; -COMPILE_ASSERT(sizeof(FramebufferTexture2DMultisampleEXT) == 24, - Sizeof_FramebufferTexture2DMultisampleEXT_is_not_24); -COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, header) == 0, - OffsetOf_FramebufferTexture2DMultisampleEXT_header_not_0); -COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, target) == 4, - OffsetOf_FramebufferTexture2DMultisampleEXT_target_not_4); -COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, attachment) == 8, - OffsetOf_FramebufferTexture2DMultisampleEXT_attachment_not_8); -COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, textarget) == 12, - OffsetOf_FramebufferTexture2DMultisampleEXT_textarget_not_12); -COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, texture) == 16, - OffsetOf_FramebufferTexture2DMultisampleEXT_texture_not_16); -COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, samples) == 20, - OffsetOf_FramebufferTexture2DMultisampleEXT_samples_not_20); +static_assert(sizeof(FramebufferTexture2DMultisampleEXT) == 24, + "size of FramebufferTexture2DMultisampleEXT should be 24"); +static_assert( + offsetof(FramebufferTexture2DMultisampleEXT, header) == 0, + "offset of FramebufferTexture2DMultisampleEXT header should be 0"); +static_assert( + offsetof(FramebufferTexture2DMultisampleEXT, target) == 4, + "offset of FramebufferTexture2DMultisampleEXT target should be 4"); +static_assert( + offsetof(FramebufferTexture2DMultisampleEXT, attachment) == 8, + "offset of FramebufferTexture2DMultisampleEXT attachment should be 8"); +static_assert( + offsetof(FramebufferTexture2DMultisampleEXT, textarget) == 12, + "offset of FramebufferTexture2DMultisampleEXT textarget should be 12"); +static_assert( + offsetof(FramebufferTexture2DMultisampleEXT, texture) == 16, + "offset of FramebufferTexture2DMultisampleEXT texture should be 16"); +static_assert( + offsetof(FramebufferTexture2DMultisampleEXT, samples) == 20, + "offset of FramebufferTexture2DMultisampleEXT samples should be 20"); struct TexStorage2DEXT { typedef TexStorage2DEXT ValueType; @@ -6840,19 +10962,20 @@ struct TexStorage2DEXT { int32_t height; }; -COMPILE_ASSERT(sizeof(TexStorage2DEXT) == 24, Sizeof_TexStorage2DEXT_is_not_24); -COMPILE_ASSERT(offsetof(TexStorage2DEXT, header) == 0, - OffsetOf_TexStorage2DEXT_header_not_0); -COMPILE_ASSERT(offsetof(TexStorage2DEXT, target) == 4, - OffsetOf_TexStorage2DEXT_target_not_4); -COMPILE_ASSERT(offsetof(TexStorage2DEXT, levels) == 8, - OffsetOf_TexStorage2DEXT_levels_not_8); -COMPILE_ASSERT(offsetof(TexStorage2DEXT, internalFormat) == 12, - OffsetOf_TexStorage2DEXT_internalFormat_not_12); -COMPILE_ASSERT(offsetof(TexStorage2DEXT, width) == 16, - OffsetOf_TexStorage2DEXT_width_not_16); -COMPILE_ASSERT(offsetof(TexStorage2DEXT, height) == 20, - OffsetOf_TexStorage2DEXT_height_not_20); +static_assert(sizeof(TexStorage2DEXT) == 24, + "size of TexStorage2DEXT should be 24"); +static_assert(offsetof(TexStorage2DEXT, header) == 0, + "offset of TexStorage2DEXT header should be 0"); +static_assert(offsetof(TexStorage2DEXT, target) == 4, + "offset of TexStorage2DEXT target should be 4"); +static_assert(offsetof(TexStorage2DEXT, levels) == 8, + "offset of TexStorage2DEXT levels should be 8"); +static_assert(offsetof(TexStorage2DEXT, internalFormat) == 12, + "offset of TexStorage2DEXT internalFormat should be 12"); +static_assert(offsetof(TexStorage2DEXT, width) == 16, + "offset of TexStorage2DEXT width should be 16"); +static_assert(offsetof(TexStorage2DEXT, height) == 20, + "offset of TexStorage2DEXT height should be 20"); struct GenQueriesEXTImmediate { typedef GenQueriesEXTImmediate ValueType; @@ -6889,12 +11012,12 @@ struct GenQueriesEXTImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(GenQueriesEXTImmediate) == 8, - Sizeof_GenQueriesEXTImmediate_is_not_8); -COMPILE_ASSERT(offsetof(GenQueriesEXTImmediate, header) == 0, - OffsetOf_GenQueriesEXTImmediate_header_not_0); -COMPILE_ASSERT(offsetof(GenQueriesEXTImmediate, n) == 4, - OffsetOf_GenQueriesEXTImmediate_n_not_4); +static_assert(sizeof(GenQueriesEXTImmediate) == 8, + "size of GenQueriesEXTImmediate should be 8"); +static_assert(offsetof(GenQueriesEXTImmediate, header) == 0, + "offset of GenQueriesEXTImmediate header should be 0"); +static_assert(offsetof(GenQueriesEXTImmediate, n) == 4, + "offset of GenQueriesEXTImmediate n should be 4"); struct DeleteQueriesEXTImmediate { typedef DeleteQueriesEXTImmediate ValueType; @@ -6931,12 +11054,12 @@ struct DeleteQueriesEXTImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(DeleteQueriesEXTImmediate) == 8, - Sizeof_DeleteQueriesEXTImmediate_is_not_8); -COMPILE_ASSERT(offsetof(DeleteQueriesEXTImmediate, header) == 0, - OffsetOf_DeleteQueriesEXTImmediate_header_not_0); -COMPILE_ASSERT(offsetof(DeleteQueriesEXTImmediate, n) == 4, - OffsetOf_DeleteQueriesEXTImmediate_n_not_4); +static_assert(sizeof(DeleteQueriesEXTImmediate) == 8, + "size of DeleteQueriesEXTImmediate should be 8"); +static_assert(offsetof(DeleteQueriesEXTImmediate, header) == 0, + "offset of DeleteQueriesEXTImmediate header should be 0"); +static_assert(offsetof(DeleteQueriesEXTImmediate, n) == 4, + "offset of DeleteQueriesEXTImmediate n should be 4"); struct BeginQueryEXT { typedef BeginQueryEXT ValueType; @@ -6978,17 +11101,51 @@ struct BeginQueryEXT { uint32_t sync_data_shm_offset; }; -COMPILE_ASSERT(sizeof(BeginQueryEXT) == 20, Sizeof_BeginQueryEXT_is_not_20); -COMPILE_ASSERT(offsetof(BeginQueryEXT, header) == 0, - OffsetOf_BeginQueryEXT_header_not_0); -COMPILE_ASSERT(offsetof(BeginQueryEXT, target) == 4, - OffsetOf_BeginQueryEXT_target_not_4); -COMPILE_ASSERT(offsetof(BeginQueryEXT, id) == 8, - OffsetOf_BeginQueryEXT_id_not_8); -COMPILE_ASSERT(offsetof(BeginQueryEXT, sync_data_shm_id) == 12, - OffsetOf_BeginQueryEXT_sync_data_shm_id_not_12); -COMPILE_ASSERT(offsetof(BeginQueryEXT, sync_data_shm_offset) == 16, - OffsetOf_BeginQueryEXT_sync_data_shm_offset_not_16); +static_assert(sizeof(BeginQueryEXT) == 20, + "size of BeginQueryEXT should be 20"); +static_assert(offsetof(BeginQueryEXT, header) == 0, + "offset of BeginQueryEXT header should be 0"); +static_assert(offsetof(BeginQueryEXT, target) == 4, + "offset of BeginQueryEXT target should be 4"); +static_assert(offsetof(BeginQueryEXT, id) == 8, + "offset of BeginQueryEXT id should be 8"); +static_assert(offsetof(BeginQueryEXT, sync_data_shm_id) == 12, + "offset of BeginQueryEXT sync_data_shm_id should be 12"); +static_assert(offsetof(BeginQueryEXT, sync_data_shm_offset) == 16, + "offset of BeginQueryEXT sync_data_shm_offset should be 16"); + +struct BeginTransformFeedback { + typedef BeginTransformFeedback ValueType; + static const CommandId kCmdId = kBeginTransformFeedback; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _primitivemode) { + SetHeader(); + primitivemode = _primitivemode; + } + + void* Set(void* cmd, GLenum _primitivemode) { + static_cast<ValueType*>(cmd)->Init(_primitivemode); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t primitivemode; +}; + +static_assert(sizeof(BeginTransformFeedback) == 8, + "size of BeginTransformFeedback should be 8"); +static_assert(offsetof(BeginTransformFeedback, header) == 0, + "offset of BeginTransformFeedback header should be 0"); +static_assert(offsetof(BeginTransformFeedback, primitivemode) == 4, + "offset of BeginTransformFeedback primitivemode should be 4"); struct EndQueryEXT { typedef EndQueryEXT ValueType; @@ -7018,13 +11175,40 @@ struct EndQueryEXT { uint32_t submit_count; }; -COMPILE_ASSERT(sizeof(EndQueryEXT) == 12, Sizeof_EndQueryEXT_is_not_12); -COMPILE_ASSERT(offsetof(EndQueryEXT, header) == 0, - OffsetOf_EndQueryEXT_header_not_0); -COMPILE_ASSERT(offsetof(EndQueryEXT, target) == 4, - OffsetOf_EndQueryEXT_target_not_4); -COMPILE_ASSERT(offsetof(EndQueryEXT, submit_count) == 8, - OffsetOf_EndQueryEXT_submit_count_not_8); +static_assert(sizeof(EndQueryEXT) == 12, "size of EndQueryEXT should be 12"); +static_assert(offsetof(EndQueryEXT, header) == 0, + "offset of EndQueryEXT header should be 0"); +static_assert(offsetof(EndQueryEXT, target) == 4, + "offset of EndQueryEXT target should be 4"); +static_assert(offsetof(EndQueryEXT, submit_count) == 8, + "offset of EndQueryEXT submit_count should be 8"); + +struct EndTransformFeedback { + typedef EndTransformFeedback ValueType; + static const CommandId kCmdId = kEndTransformFeedback; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init() { SetHeader(); } + + void* Set(void* cmd) { + static_cast<ValueType*>(cmd)->Init(); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; +}; + +static_assert(sizeof(EndTransformFeedback) == 4, + "size of EndTransformFeedback should be 4"); +static_assert(offsetof(EndTransformFeedback, header) == 0, + "offset of EndTransformFeedback header should be 0"); struct InsertEventMarkerEXT { typedef InsertEventMarkerEXT ValueType; @@ -7052,12 +11236,12 @@ struct InsertEventMarkerEXT { uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(InsertEventMarkerEXT) == 8, - Sizeof_InsertEventMarkerEXT_is_not_8); -COMPILE_ASSERT(offsetof(InsertEventMarkerEXT, header) == 0, - OffsetOf_InsertEventMarkerEXT_header_not_0); -COMPILE_ASSERT(offsetof(InsertEventMarkerEXT, bucket_id) == 4, - OffsetOf_InsertEventMarkerEXT_bucket_id_not_4); +static_assert(sizeof(InsertEventMarkerEXT) == 8, + "size of InsertEventMarkerEXT should be 8"); +static_assert(offsetof(InsertEventMarkerEXT, header) == 0, + "offset of InsertEventMarkerEXT header should be 0"); +static_assert(offsetof(InsertEventMarkerEXT, bucket_id) == 4, + "offset of InsertEventMarkerEXT bucket_id should be 4"); struct PushGroupMarkerEXT { typedef PushGroupMarkerEXT ValueType; @@ -7085,12 +11269,12 @@ struct PushGroupMarkerEXT { uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(PushGroupMarkerEXT) == 8, - Sizeof_PushGroupMarkerEXT_is_not_8); -COMPILE_ASSERT(offsetof(PushGroupMarkerEXT, header) == 0, - OffsetOf_PushGroupMarkerEXT_header_not_0); -COMPILE_ASSERT(offsetof(PushGroupMarkerEXT, bucket_id) == 4, - OffsetOf_PushGroupMarkerEXT_bucket_id_not_4); +static_assert(sizeof(PushGroupMarkerEXT) == 8, + "size of PushGroupMarkerEXT should be 8"); +static_assert(offsetof(PushGroupMarkerEXT, header) == 0, + "offset of PushGroupMarkerEXT header should be 0"); +static_assert(offsetof(PushGroupMarkerEXT, bucket_id) == 4, + "offset of PushGroupMarkerEXT bucket_id should be 4"); struct PopGroupMarkerEXT { typedef PopGroupMarkerEXT ValueType; @@ -7114,10 +11298,10 @@ struct PopGroupMarkerEXT { gpu::CommandHeader header; }; -COMPILE_ASSERT(sizeof(PopGroupMarkerEXT) == 4, - Sizeof_PopGroupMarkerEXT_is_not_4); -COMPILE_ASSERT(offsetof(PopGroupMarkerEXT, header) == 0, - OffsetOf_PopGroupMarkerEXT_header_not_0); +static_assert(sizeof(PopGroupMarkerEXT) == 4, + "size of PopGroupMarkerEXT should be 4"); +static_assert(offsetof(PopGroupMarkerEXT, header) == 0, + "offset of PopGroupMarkerEXT header should be 0"); struct GenVertexArraysOESImmediate { typedef GenVertexArraysOESImmediate ValueType; @@ -7154,12 +11338,12 @@ struct GenVertexArraysOESImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(GenVertexArraysOESImmediate) == 8, - Sizeof_GenVertexArraysOESImmediate_is_not_8); -COMPILE_ASSERT(offsetof(GenVertexArraysOESImmediate, header) == 0, - OffsetOf_GenVertexArraysOESImmediate_header_not_0); -COMPILE_ASSERT(offsetof(GenVertexArraysOESImmediate, n) == 4, - OffsetOf_GenVertexArraysOESImmediate_n_not_4); +static_assert(sizeof(GenVertexArraysOESImmediate) == 8, + "size of GenVertexArraysOESImmediate should be 8"); +static_assert(offsetof(GenVertexArraysOESImmediate, header) == 0, + "offset of GenVertexArraysOESImmediate header should be 0"); +static_assert(offsetof(GenVertexArraysOESImmediate, n) == 4, + "offset of GenVertexArraysOESImmediate n should be 4"); struct DeleteVertexArraysOESImmediate { typedef DeleteVertexArraysOESImmediate ValueType; @@ -7196,12 +11380,12 @@ struct DeleteVertexArraysOESImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(DeleteVertexArraysOESImmediate) == 8, - Sizeof_DeleteVertexArraysOESImmediate_is_not_8); -COMPILE_ASSERT(offsetof(DeleteVertexArraysOESImmediate, header) == 0, - OffsetOf_DeleteVertexArraysOESImmediate_header_not_0); -COMPILE_ASSERT(offsetof(DeleteVertexArraysOESImmediate, n) == 4, - OffsetOf_DeleteVertexArraysOESImmediate_n_not_4); +static_assert(sizeof(DeleteVertexArraysOESImmediate) == 8, + "size of DeleteVertexArraysOESImmediate should be 8"); +static_assert(offsetof(DeleteVertexArraysOESImmediate, header) == 0, + "offset of DeleteVertexArraysOESImmediate header should be 0"); +static_assert(offsetof(DeleteVertexArraysOESImmediate, n) == 4, + "offset of DeleteVertexArraysOESImmediate n should be 4"); struct IsVertexArrayOES { typedef IsVertexArrayOES ValueType; @@ -7241,16 +11425,16 @@ struct IsVertexArrayOES { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(IsVertexArrayOES) == 16, - Sizeof_IsVertexArrayOES_is_not_16); -COMPILE_ASSERT(offsetof(IsVertexArrayOES, header) == 0, - OffsetOf_IsVertexArrayOES_header_not_0); -COMPILE_ASSERT(offsetof(IsVertexArrayOES, array) == 4, - OffsetOf_IsVertexArrayOES_array_not_4); -COMPILE_ASSERT(offsetof(IsVertexArrayOES, result_shm_id) == 8, - OffsetOf_IsVertexArrayOES_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(IsVertexArrayOES, result_shm_offset) == 12, - OffsetOf_IsVertexArrayOES_result_shm_offset_not_12); +static_assert(sizeof(IsVertexArrayOES) == 16, + "size of IsVertexArrayOES should be 16"); +static_assert(offsetof(IsVertexArrayOES, header) == 0, + "offset of IsVertexArrayOES header should be 0"); +static_assert(offsetof(IsVertexArrayOES, array) == 4, + "offset of IsVertexArrayOES array should be 4"); +static_assert(offsetof(IsVertexArrayOES, result_shm_id) == 8, + "offset of IsVertexArrayOES result_shm_id should be 8"); +static_assert(offsetof(IsVertexArrayOES, result_shm_offset) == 12, + "offset of IsVertexArrayOES result_shm_offset should be 12"); struct BindVertexArrayOES { typedef BindVertexArrayOES ValueType; @@ -7278,12 +11462,12 @@ struct BindVertexArrayOES { uint32_t array; }; -COMPILE_ASSERT(sizeof(BindVertexArrayOES) == 8, - Sizeof_BindVertexArrayOES_is_not_8); -COMPILE_ASSERT(offsetof(BindVertexArrayOES, header) == 0, - OffsetOf_BindVertexArrayOES_header_not_0); -COMPILE_ASSERT(offsetof(BindVertexArrayOES, array) == 4, - OffsetOf_BindVertexArrayOES_array_not_4); +static_assert(sizeof(BindVertexArrayOES) == 8, + "size of BindVertexArrayOES should be 8"); +static_assert(offsetof(BindVertexArrayOES, header) == 0, + "offset of BindVertexArrayOES header should be 0"); +static_assert(offsetof(BindVertexArrayOES, array) == 4, + "offset of BindVertexArrayOES array should be 4"); struct SwapBuffers { typedef SwapBuffers ValueType; @@ -7307,9 +11491,9 @@ struct SwapBuffers { gpu::CommandHeader header; }; -COMPILE_ASSERT(sizeof(SwapBuffers) == 4, Sizeof_SwapBuffers_is_not_4); -COMPILE_ASSERT(offsetof(SwapBuffers, header) == 0, - OffsetOf_SwapBuffers_header_not_0); +static_assert(sizeof(SwapBuffers) == 4, "size of SwapBuffers should be 4"); +static_assert(offsetof(SwapBuffers, header) == 0, + "offset of SwapBuffers header should be 0"); struct GetMaxValueInBufferCHROMIUM { typedef GetMaxValueInBufferCHROMIUM ValueType; @@ -7361,22 +11545,24 @@ struct GetMaxValueInBufferCHROMIUM { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(GetMaxValueInBufferCHROMIUM) == 28, - Sizeof_GetMaxValueInBufferCHROMIUM_is_not_28); -COMPILE_ASSERT(offsetof(GetMaxValueInBufferCHROMIUM, header) == 0, - OffsetOf_GetMaxValueInBufferCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(GetMaxValueInBufferCHROMIUM, buffer_id) == 4, - OffsetOf_GetMaxValueInBufferCHROMIUM_buffer_id_not_4); -COMPILE_ASSERT(offsetof(GetMaxValueInBufferCHROMIUM, count) == 8, - OffsetOf_GetMaxValueInBufferCHROMIUM_count_not_8); -COMPILE_ASSERT(offsetof(GetMaxValueInBufferCHROMIUM, type) == 12, - OffsetOf_GetMaxValueInBufferCHROMIUM_type_not_12); -COMPILE_ASSERT(offsetof(GetMaxValueInBufferCHROMIUM, offset) == 16, - OffsetOf_GetMaxValueInBufferCHROMIUM_offset_not_16); -COMPILE_ASSERT(offsetof(GetMaxValueInBufferCHROMIUM, result_shm_id) == 20, - OffsetOf_GetMaxValueInBufferCHROMIUM_result_shm_id_not_20); -COMPILE_ASSERT(offsetof(GetMaxValueInBufferCHROMIUM, result_shm_offset) == 24, - OffsetOf_GetMaxValueInBufferCHROMIUM_result_shm_offset_not_24); +static_assert(sizeof(GetMaxValueInBufferCHROMIUM) == 28, + "size of GetMaxValueInBufferCHROMIUM should be 28"); +static_assert(offsetof(GetMaxValueInBufferCHROMIUM, header) == 0, + "offset of GetMaxValueInBufferCHROMIUM header should be 0"); +static_assert(offsetof(GetMaxValueInBufferCHROMIUM, buffer_id) == 4, + "offset of GetMaxValueInBufferCHROMIUM buffer_id should be 4"); +static_assert(offsetof(GetMaxValueInBufferCHROMIUM, count) == 8, + "offset of GetMaxValueInBufferCHROMIUM count should be 8"); +static_assert(offsetof(GetMaxValueInBufferCHROMIUM, type) == 12, + "offset of GetMaxValueInBufferCHROMIUM type should be 12"); +static_assert(offsetof(GetMaxValueInBufferCHROMIUM, offset) == 16, + "offset of GetMaxValueInBufferCHROMIUM offset should be 16"); +static_assert( + offsetof(GetMaxValueInBufferCHROMIUM, result_shm_id) == 20, + "offset of GetMaxValueInBufferCHROMIUM result_shm_id should be 20"); +static_assert( + offsetof(GetMaxValueInBufferCHROMIUM, result_shm_offset) == 24, + "offset of GetMaxValueInBufferCHROMIUM result_shm_offset should be 24"); struct EnableFeatureCHROMIUM { typedef EnableFeatureCHROMIUM ValueType; @@ -7416,16 +11602,128 @@ struct EnableFeatureCHROMIUM { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(EnableFeatureCHROMIUM) == 16, - Sizeof_EnableFeatureCHROMIUM_is_not_16); -COMPILE_ASSERT(offsetof(EnableFeatureCHROMIUM, header) == 0, - OffsetOf_EnableFeatureCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(EnableFeatureCHROMIUM, bucket_id) == 4, - OffsetOf_EnableFeatureCHROMIUM_bucket_id_not_4); -COMPILE_ASSERT(offsetof(EnableFeatureCHROMIUM, result_shm_id) == 8, - OffsetOf_EnableFeatureCHROMIUM_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(EnableFeatureCHROMIUM, result_shm_offset) == 12, - OffsetOf_EnableFeatureCHROMIUM_result_shm_offset_not_12); +static_assert(sizeof(EnableFeatureCHROMIUM) == 16, + "size of EnableFeatureCHROMIUM should be 16"); +static_assert(offsetof(EnableFeatureCHROMIUM, header) == 0, + "offset of EnableFeatureCHROMIUM header should be 0"); +static_assert(offsetof(EnableFeatureCHROMIUM, bucket_id) == 4, + "offset of EnableFeatureCHROMIUM bucket_id should be 4"); +static_assert(offsetof(EnableFeatureCHROMIUM, result_shm_id) == 8, + "offset of EnableFeatureCHROMIUM result_shm_id should be 8"); +static_assert(offsetof(EnableFeatureCHROMIUM, result_shm_offset) == 12, + "offset of EnableFeatureCHROMIUM result_shm_offset should be 12"); + +struct MapBufferRange { + typedef MapBufferRange ValueType; + static const CommandId kCmdId = kMapBufferRange; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef uint32_t Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLintptr _offset, + GLsizeiptr _size, + GLbitfield _access, + uint32_t _data_shm_id, + uint32_t _data_shm_offset, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + SetHeader(); + target = _target; + offset = _offset; + size = _size; + access = _access; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set(void* cmd, + GLenum _target, + GLintptr _offset, + GLsizeiptr _size, + GLbitfield _access, + uint32_t _data_shm_id, + uint32_t _data_shm_offset, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_target, _offset, _size, _access, + _data_shm_id, _data_shm_offset, + _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t offset; + int32_t size; + uint32_t access; + uint32_t data_shm_id; + uint32_t data_shm_offset; + uint32_t result_shm_id; + uint32_t result_shm_offset; +}; + +static_assert(sizeof(MapBufferRange) == 36, + "size of MapBufferRange should be 36"); +static_assert(offsetof(MapBufferRange, header) == 0, + "offset of MapBufferRange header should be 0"); +static_assert(offsetof(MapBufferRange, target) == 4, + "offset of MapBufferRange target should be 4"); +static_assert(offsetof(MapBufferRange, offset) == 8, + "offset of MapBufferRange offset should be 8"); +static_assert(offsetof(MapBufferRange, size) == 12, + "offset of MapBufferRange size should be 12"); +static_assert(offsetof(MapBufferRange, access) == 16, + "offset of MapBufferRange access should be 16"); +static_assert(offsetof(MapBufferRange, data_shm_id) == 20, + "offset of MapBufferRange data_shm_id should be 20"); +static_assert(offsetof(MapBufferRange, data_shm_offset) == 24, + "offset of MapBufferRange data_shm_offset should be 24"); +static_assert(offsetof(MapBufferRange, result_shm_id) == 28, + "offset of MapBufferRange result_shm_id should be 28"); +static_assert(offsetof(MapBufferRange, result_shm_offset) == 32, + "offset of MapBufferRange result_shm_offset should be 32"); + +struct UnmapBuffer { + typedef UnmapBuffer ValueType; + static const CommandId kCmdId = kUnmapBuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target) { + SetHeader(); + target = _target; + } + + void* Set(void* cmd, GLenum _target) { + static_cast<ValueType*>(cmd)->Init(_target); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; +}; + +static_assert(sizeof(UnmapBuffer) == 8, "size of UnmapBuffer should be 8"); +static_assert(offsetof(UnmapBuffer, header) == 0, + "offset of UnmapBuffer header should be 0"); +static_assert(offsetof(UnmapBuffer, target) == 4, + "offset of UnmapBuffer target should be 4"); struct ResizeCHROMIUM { typedef ResizeCHROMIUM ValueType; @@ -7457,15 +11755,16 @@ struct ResizeCHROMIUM { float scale_factor; }; -COMPILE_ASSERT(sizeof(ResizeCHROMIUM) == 16, Sizeof_ResizeCHROMIUM_is_not_16); -COMPILE_ASSERT(offsetof(ResizeCHROMIUM, header) == 0, - OffsetOf_ResizeCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(ResizeCHROMIUM, width) == 4, - OffsetOf_ResizeCHROMIUM_width_not_4); -COMPILE_ASSERT(offsetof(ResizeCHROMIUM, height) == 8, - OffsetOf_ResizeCHROMIUM_height_not_8); -COMPILE_ASSERT(offsetof(ResizeCHROMIUM, scale_factor) == 12, - OffsetOf_ResizeCHROMIUM_scale_factor_not_12); +static_assert(sizeof(ResizeCHROMIUM) == 16, + "size of ResizeCHROMIUM should be 16"); +static_assert(offsetof(ResizeCHROMIUM, header) == 0, + "offset of ResizeCHROMIUM header should be 0"); +static_assert(offsetof(ResizeCHROMIUM, width) == 4, + "offset of ResizeCHROMIUM width should be 4"); +static_assert(offsetof(ResizeCHROMIUM, height) == 8, + "offset of ResizeCHROMIUM height should be 8"); +static_assert(offsetof(ResizeCHROMIUM, scale_factor) == 12, + "offset of ResizeCHROMIUM scale_factor should be 12"); struct GetRequestableExtensionsCHROMIUM { typedef GetRequestableExtensionsCHROMIUM ValueType; @@ -7493,12 +11792,13 @@ struct GetRequestableExtensionsCHROMIUM { uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(GetRequestableExtensionsCHROMIUM) == 8, - Sizeof_GetRequestableExtensionsCHROMIUM_is_not_8); -COMPILE_ASSERT(offsetof(GetRequestableExtensionsCHROMIUM, header) == 0, - OffsetOf_GetRequestableExtensionsCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(GetRequestableExtensionsCHROMIUM, bucket_id) == 4, - OffsetOf_GetRequestableExtensionsCHROMIUM_bucket_id_not_4); +static_assert(sizeof(GetRequestableExtensionsCHROMIUM) == 8, + "size of GetRequestableExtensionsCHROMIUM should be 8"); +static_assert(offsetof(GetRequestableExtensionsCHROMIUM, header) == 0, + "offset of GetRequestableExtensionsCHROMIUM header should be 0"); +static_assert( + offsetof(GetRequestableExtensionsCHROMIUM, bucket_id) == 4, + "offset of GetRequestableExtensionsCHROMIUM bucket_id should be 4"); struct RequestExtensionCHROMIUM { typedef RequestExtensionCHROMIUM ValueType; @@ -7526,90 +11826,153 @@ struct RequestExtensionCHROMIUM { uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(RequestExtensionCHROMIUM) == 8, - Sizeof_RequestExtensionCHROMIUM_is_not_8); -COMPILE_ASSERT(offsetof(RequestExtensionCHROMIUM, header) == 0, - OffsetOf_RequestExtensionCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(RequestExtensionCHROMIUM, bucket_id) == 4, - OffsetOf_RequestExtensionCHROMIUM_bucket_id_not_4); +static_assert(sizeof(RequestExtensionCHROMIUM) == 8, + "size of RequestExtensionCHROMIUM should be 8"); +static_assert(offsetof(RequestExtensionCHROMIUM, header) == 0, + "offset of RequestExtensionCHROMIUM header should be 0"); +static_assert(offsetof(RequestExtensionCHROMIUM, bucket_id) == 4, + "offset of RequestExtensionCHROMIUM bucket_id should be 4"); -struct GetMultipleIntegervCHROMIUM { - typedef GetMultipleIntegervCHROMIUM ValueType; - static const CommandId kCmdId = kGetMultipleIntegervCHROMIUM; +struct GetProgramInfoCHROMIUM { + typedef GetProgramInfoCHROMIUM ValueType; + static const CommandId kCmdId = kGetProgramInfoCHROMIUM; static const cmd::ArgFlags kArgFlags = cmd::kFixed; static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + struct Result { + uint32_t link_status; + uint32_t num_attribs; + uint32_t num_uniforms; + }; + static uint32_t ComputeSize() { return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT } void SetHeader() { header.SetCmd<ValueType>(); } - void Init(uint32_t _pnames_shm_id, - uint32_t _pnames_shm_offset, - GLuint _count, - uint32_t _results_shm_id, - uint32_t _results_shm_offset, - GLsizeiptr _size) { + void Init(GLuint _program, uint32_t _bucket_id) { SetHeader(); - pnames_shm_id = _pnames_shm_id; - pnames_shm_offset = _pnames_shm_offset; - count = _count; - results_shm_id = _results_shm_id; - results_shm_offset = _results_shm_offset; - size = _size; + program = _program; + bucket_id = _bucket_id; } - void* Set(void* cmd, - uint32_t _pnames_shm_id, - uint32_t _pnames_shm_offset, - GLuint _count, - uint32_t _results_shm_id, - uint32_t _results_shm_offset, - GLsizeiptr _size) { - static_cast<ValueType*>(cmd)->Init(_pnames_shm_id, _pnames_shm_offset, - _count, _results_shm_id, - _results_shm_offset, _size); + void* Set(void* cmd, GLuint _program, uint32_t _bucket_id) { + static_cast<ValueType*>(cmd)->Init(_program, _bucket_id); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; - uint32_t pnames_shm_id; - uint32_t pnames_shm_offset; - uint32_t count; - uint32_t results_shm_id; - uint32_t results_shm_offset; - int32_t size; + uint32_t program; + uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(GetMultipleIntegervCHROMIUM) == 28, - Sizeof_GetMultipleIntegervCHROMIUM_is_not_28); -COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, header) == 0, - OffsetOf_GetMultipleIntegervCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, pnames_shm_id) == 4, - OffsetOf_GetMultipleIntegervCHROMIUM_pnames_shm_id_not_4); -COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, pnames_shm_offset) == 8, - OffsetOf_GetMultipleIntegervCHROMIUM_pnames_shm_offset_not_8); -COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, count) == 12, - OffsetOf_GetMultipleIntegervCHROMIUM_count_not_12); -COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, results_shm_id) == 16, - OffsetOf_GetMultipleIntegervCHROMIUM_results_shm_id_not_16); -COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, results_shm_offset) == 20, - OffsetOf_GetMultipleIntegervCHROMIUM_results_shm_offset_not_20); -COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, size) == 24, - OffsetOf_GetMultipleIntegervCHROMIUM_size_not_24); +static_assert(sizeof(GetProgramInfoCHROMIUM) == 12, + "size of GetProgramInfoCHROMIUM should be 12"); +static_assert(offsetof(GetProgramInfoCHROMIUM, header) == 0, + "offset of GetProgramInfoCHROMIUM header should be 0"); +static_assert(offsetof(GetProgramInfoCHROMIUM, program) == 4, + "offset of GetProgramInfoCHROMIUM program should be 4"); +static_assert(offsetof(GetProgramInfoCHROMIUM, bucket_id) == 8, + "offset of GetProgramInfoCHROMIUM bucket_id should be 8"); +static_assert(offsetof(GetProgramInfoCHROMIUM::Result, link_status) == 0, + "offset of GetProgramInfoCHROMIUM Result link_status should be " + "0"); +static_assert(offsetof(GetProgramInfoCHROMIUM::Result, num_attribs) == 4, + "offset of GetProgramInfoCHROMIUM Result num_attribs should be " + "4"); +static_assert(offsetof(GetProgramInfoCHROMIUM::Result, num_uniforms) == 8, + "offset of GetProgramInfoCHROMIUM Result num_uniforms should be " + "8"); -struct GetProgramInfoCHROMIUM { - typedef GetProgramInfoCHROMIUM ValueType; - static const CommandId kCmdId = kGetProgramInfoCHROMIUM; +struct GetUniformBlocksCHROMIUM { + typedef GetUniformBlocksCHROMIUM ValueType; + static const CommandId kCmdId = kGetUniformBlocksCHROMIUM; static const cmd::ArgFlags kArgFlags = cmd::kFixed; static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); - struct Result { - uint32_t link_status; - uint32_t num_attribs; - uint32_t num_uniforms; - }; + typedef uint32_t Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, uint32_t _bucket_id) { + SetHeader(); + program = _program; + bucket_id = _bucket_id; + } + + void* Set(void* cmd, GLuint _program, uint32_t _bucket_id) { + static_cast<ValueType*>(cmd)->Init(_program, _bucket_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t bucket_id; +}; + +static_assert(sizeof(GetUniformBlocksCHROMIUM) == 12, + "size of GetUniformBlocksCHROMIUM should be 12"); +static_assert(offsetof(GetUniformBlocksCHROMIUM, header) == 0, + "offset of GetUniformBlocksCHROMIUM header should be 0"); +static_assert(offsetof(GetUniformBlocksCHROMIUM, program) == 4, + "offset of GetUniformBlocksCHROMIUM program should be 4"); +static_assert(offsetof(GetUniformBlocksCHROMIUM, bucket_id) == 8, + "offset of GetUniformBlocksCHROMIUM bucket_id should be 8"); + +struct GetTransformFeedbackVaryingsCHROMIUM { + typedef GetTransformFeedbackVaryingsCHROMIUM ValueType; + static const CommandId kCmdId = kGetTransformFeedbackVaryingsCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef uint32_t Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, uint32_t _bucket_id) { + SetHeader(); + program = _program; + bucket_id = _bucket_id; + } + + void* Set(void* cmd, GLuint _program, uint32_t _bucket_id) { + static_cast<ValueType*>(cmd)->Init(_program, _bucket_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t bucket_id; +}; + +static_assert(sizeof(GetTransformFeedbackVaryingsCHROMIUM) == 12, + "size of GetTransformFeedbackVaryingsCHROMIUM should be 12"); +static_assert( + offsetof(GetTransformFeedbackVaryingsCHROMIUM, header) == 0, + "offset of GetTransformFeedbackVaryingsCHROMIUM header should be 0"); +static_assert( + offsetof(GetTransformFeedbackVaryingsCHROMIUM, program) == 4, + "offset of GetTransformFeedbackVaryingsCHROMIUM program should be 4"); +static_assert( + offsetof(GetTransformFeedbackVaryingsCHROMIUM, bucket_id) == 8, + "offset of GetTransformFeedbackVaryingsCHROMIUM bucket_id should be 8"); + +struct GetUniformsES3CHROMIUM { + typedef GetUniformsES3CHROMIUM ValueType; + static const CommandId kCmdId = kGetUniformsES3CHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef uint32_t Result; static uint32_t ComputeSize() { return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT @@ -7633,20 +11996,14 @@ struct GetProgramInfoCHROMIUM { uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(GetProgramInfoCHROMIUM) == 12, - Sizeof_GetProgramInfoCHROMIUM_is_not_12); -COMPILE_ASSERT(offsetof(GetProgramInfoCHROMIUM, header) == 0, - OffsetOf_GetProgramInfoCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(GetProgramInfoCHROMIUM, program) == 4, - OffsetOf_GetProgramInfoCHROMIUM_program_not_4); -COMPILE_ASSERT(offsetof(GetProgramInfoCHROMIUM, bucket_id) == 8, - OffsetOf_GetProgramInfoCHROMIUM_bucket_id_not_8); -COMPILE_ASSERT(offsetof(GetProgramInfoCHROMIUM::Result, link_status) == 0, - OffsetOf_GetProgramInfoCHROMIUM_Result_link_status_not_0); -COMPILE_ASSERT(offsetof(GetProgramInfoCHROMIUM::Result, num_attribs) == 4, - OffsetOf_GetProgramInfoCHROMIUM_Result_num_attribs_not_4); -COMPILE_ASSERT(offsetof(GetProgramInfoCHROMIUM::Result, num_uniforms) == 8, - OffsetOf_GetProgramInfoCHROMIUM_Result_num_uniforms_not_8); +static_assert(sizeof(GetUniformsES3CHROMIUM) == 12, + "size of GetUniformsES3CHROMIUM should be 12"); +static_assert(offsetof(GetUniformsES3CHROMIUM, header) == 0, + "offset of GetUniformsES3CHROMIUM header should be 0"); +static_assert(offsetof(GetUniformsES3CHROMIUM, program) == 4, + "offset of GetUniformsES3CHROMIUM program should be 4"); +static_assert(offsetof(GetUniformsES3CHROMIUM, bucket_id) == 8, + "offset of GetUniformsES3CHROMIUM bucket_id should be 8"); struct GetTranslatedShaderSourceANGLE { typedef GetTranslatedShaderSourceANGLE ValueType; @@ -7676,14 +12033,14 @@ struct GetTranslatedShaderSourceANGLE { uint32_t bucket_id; }; -COMPILE_ASSERT(sizeof(GetTranslatedShaderSourceANGLE) == 12, - Sizeof_GetTranslatedShaderSourceANGLE_is_not_12); -COMPILE_ASSERT(offsetof(GetTranslatedShaderSourceANGLE, header) == 0, - OffsetOf_GetTranslatedShaderSourceANGLE_header_not_0); -COMPILE_ASSERT(offsetof(GetTranslatedShaderSourceANGLE, shader) == 4, - OffsetOf_GetTranslatedShaderSourceANGLE_shader_not_4); -COMPILE_ASSERT(offsetof(GetTranslatedShaderSourceANGLE, bucket_id) == 8, - OffsetOf_GetTranslatedShaderSourceANGLE_bucket_id_not_8); +static_assert(sizeof(GetTranslatedShaderSourceANGLE) == 12, + "size of GetTranslatedShaderSourceANGLE should be 12"); +static_assert(offsetof(GetTranslatedShaderSourceANGLE, header) == 0, + "offset of GetTranslatedShaderSourceANGLE header should be 0"); +static_assert(offsetof(GetTranslatedShaderSourceANGLE, shader) == 4, + "offset of GetTranslatedShaderSourceANGLE shader should be 4"); +static_assert(offsetof(GetTranslatedShaderSourceANGLE, bucket_id) == 8, + "offset of GetTranslatedShaderSourceANGLE bucket_id should be 8"); struct PostSubBufferCHROMIUM { typedef PostSubBufferCHROMIUM ValueType; @@ -7717,18 +12074,18 @@ struct PostSubBufferCHROMIUM { int32_t height; }; -COMPILE_ASSERT(sizeof(PostSubBufferCHROMIUM) == 20, - Sizeof_PostSubBufferCHROMIUM_is_not_20); -COMPILE_ASSERT(offsetof(PostSubBufferCHROMIUM, header) == 0, - OffsetOf_PostSubBufferCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(PostSubBufferCHROMIUM, x) == 4, - OffsetOf_PostSubBufferCHROMIUM_x_not_4); -COMPILE_ASSERT(offsetof(PostSubBufferCHROMIUM, y) == 8, - OffsetOf_PostSubBufferCHROMIUM_y_not_8); -COMPILE_ASSERT(offsetof(PostSubBufferCHROMIUM, width) == 12, - OffsetOf_PostSubBufferCHROMIUM_width_not_12); -COMPILE_ASSERT(offsetof(PostSubBufferCHROMIUM, height) == 16, - OffsetOf_PostSubBufferCHROMIUM_height_not_16); +static_assert(sizeof(PostSubBufferCHROMIUM) == 20, + "size of PostSubBufferCHROMIUM should be 20"); +static_assert(offsetof(PostSubBufferCHROMIUM, header) == 0, + "offset of PostSubBufferCHROMIUM header should be 0"); +static_assert(offsetof(PostSubBufferCHROMIUM, x) == 4, + "offset of PostSubBufferCHROMIUM x should be 4"); +static_assert(offsetof(PostSubBufferCHROMIUM, y) == 8, + "offset of PostSubBufferCHROMIUM y should be 8"); +static_assert(offsetof(PostSubBufferCHROMIUM, width) == 12, + "offset of PostSubBufferCHROMIUM width should be 12"); +static_assert(offsetof(PostSubBufferCHROMIUM, height) == 16, + "offset of PostSubBufferCHROMIUM height should be 16"); struct TexImageIOSurface2DCHROMIUM { typedef TexImageIOSurface2DCHROMIUM ValueType; @@ -7774,20 +12131,20 @@ struct TexImageIOSurface2DCHROMIUM { uint32_t plane; }; -COMPILE_ASSERT(sizeof(TexImageIOSurface2DCHROMIUM) == 24, - Sizeof_TexImageIOSurface2DCHROMIUM_is_not_24); -COMPILE_ASSERT(offsetof(TexImageIOSurface2DCHROMIUM, header) == 0, - OffsetOf_TexImageIOSurface2DCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(TexImageIOSurface2DCHROMIUM, target) == 4, - OffsetOf_TexImageIOSurface2DCHROMIUM_target_not_4); -COMPILE_ASSERT(offsetof(TexImageIOSurface2DCHROMIUM, width) == 8, - OffsetOf_TexImageIOSurface2DCHROMIUM_width_not_8); -COMPILE_ASSERT(offsetof(TexImageIOSurface2DCHROMIUM, height) == 12, - OffsetOf_TexImageIOSurface2DCHROMIUM_height_not_12); -COMPILE_ASSERT(offsetof(TexImageIOSurface2DCHROMIUM, ioSurfaceId) == 16, - OffsetOf_TexImageIOSurface2DCHROMIUM_ioSurfaceId_not_16); -COMPILE_ASSERT(offsetof(TexImageIOSurface2DCHROMIUM, plane) == 20, - OffsetOf_TexImageIOSurface2DCHROMIUM_plane_not_20); +static_assert(sizeof(TexImageIOSurface2DCHROMIUM) == 24, + "size of TexImageIOSurface2DCHROMIUM should be 24"); +static_assert(offsetof(TexImageIOSurface2DCHROMIUM, header) == 0, + "offset of TexImageIOSurface2DCHROMIUM header should be 0"); +static_assert(offsetof(TexImageIOSurface2DCHROMIUM, target) == 4, + "offset of TexImageIOSurface2DCHROMIUM target should be 4"); +static_assert(offsetof(TexImageIOSurface2DCHROMIUM, width) == 8, + "offset of TexImageIOSurface2DCHROMIUM width should be 8"); +static_assert(offsetof(TexImageIOSurface2DCHROMIUM, height) == 12, + "offset of TexImageIOSurface2DCHROMIUM height should be 12"); +static_assert(offsetof(TexImageIOSurface2DCHROMIUM, ioSurfaceId) == 16, + "offset of TexImageIOSurface2DCHROMIUM ioSurfaceId should be 16"); +static_assert(offsetof(TexImageIOSurface2DCHROMIUM, plane) == 20, + "offset of TexImageIOSurface2DCHROMIUM plane should be 20"); struct CopyTextureCHROMIUM { typedef CopyTextureCHROMIUM ValueType; @@ -7804,14 +12161,12 @@ struct CopyTextureCHROMIUM { void Init(GLenum _target, GLenum _source_id, GLenum _dest_id, - GLint _level, GLint _internalformat, GLenum _dest_type) { SetHeader(); target = _target; source_id = _source_id; dest_id = _dest_id; - level = _level; internalformat = _internalformat; dest_type = _dest_type; } @@ -7820,11 +12175,10 @@ struct CopyTextureCHROMIUM { GLenum _target, GLenum _source_id, GLenum _dest_id, - GLint _level, GLint _internalformat, GLenum _dest_type) { - static_cast<ValueType*>(cmd)->Init(_target, _source_id, _dest_id, _level, - _internalformat, _dest_type); + static_cast<ValueType*>(cmd) + ->Init(_target, _source_id, _dest_id, _internalformat, _dest_type); return NextCmdAddress<ValueType>(cmd); } @@ -7832,27 +12186,83 @@ struct CopyTextureCHROMIUM { uint32_t target; uint32_t source_id; uint32_t dest_id; - int32_t level; int32_t internalformat; uint32_t dest_type; }; -COMPILE_ASSERT(sizeof(CopyTextureCHROMIUM) == 28, - Sizeof_CopyTextureCHROMIUM_is_not_28); -COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, header) == 0, - OffsetOf_CopyTextureCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, target) == 4, - OffsetOf_CopyTextureCHROMIUM_target_not_4); -COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, source_id) == 8, - OffsetOf_CopyTextureCHROMIUM_source_id_not_8); -COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, dest_id) == 12, - OffsetOf_CopyTextureCHROMIUM_dest_id_not_12); -COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, level) == 16, - OffsetOf_CopyTextureCHROMIUM_level_not_16); -COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, internalformat) == 20, - OffsetOf_CopyTextureCHROMIUM_internalformat_not_20); -COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, dest_type) == 24, - OffsetOf_CopyTextureCHROMIUM_dest_type_not_24); +static_assert(sizeof(CopyTextureCHROMIUM) == 24, + "size of CopyTextureCHROMIUM should be 24"); +static_assert(offsetof(CopyTextureCHROMIUM, header) == 0, + "offset of CopyTextureCHROMIUM header should be 0"); +static_assert(offsetof(CopyTextureCHROMIUM, target) == 4, + "offset of CopyTextureCHROMIUM target should be 4"); +static_assert(offsetof(CopyTextureCHROMIUM, source_id) == 8, + "offset of CopyTextureCHROMIUM source_id should be 8"); +static_assert(offsetof(CopyTextureCHROMIUM, dest_id) == 12, + "offset of CopyTextureCHROMIUM dest_id should be 12"); +static_assert(offsetof(CopyTextureCHROMIUM, internalformat) == 16, + "offset of CopyTextureCHROMIUM internalformat should be 16"); +static_assert(offsetof(CopyTextureCHROMIUM, dest_type) == 20, + "offset of CopyTextureCHROMIUM dest_type should be 20"); + +struct CopySubTextureCHROMIUM { + typedef CopySubTextureCHROMIUM ValueType; + static const CommandId kCmdId = kCopySubTextureCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLenum _source_id, + GLenum _dest_id, + GLint _xoffset, + GLint _yoffset) { + SetHeader(); + target = _target; + source_id = _source_id; + dest_id = _dest_id; + xoffset = _xoffset; + yoffset = _yoffset; + } + + void* Set(void* cmd, + GLenum _target, + GLenum _source_id, + GLenum _dest_id, + GLint _xoffset, + GLint _yoffset) { + static_cast<ValueType*>(cmd) + ->Init(_target, _source_id, _dest_id, _xoffset, _yoffset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + uint32_t source_id; + uint32_t dest_id; + int32_t xoffset; + int32_t yoffset; +}; + +static_assert(sizeof(CopySubTextureCHROMIUM) == 24, + "size of CopySubTextureCHROMIUM should be 24"); +static_assert(offsetof(CopySubTextureCHROMIUM, header) == 0, + "offset of CopySubTextureCHROMIUM header should be 0"); +static_assert(offsetof(CopySubTextureCHROMIUM, target) == 4, + "offset of CopySubTextureCHROMIUM target should be 4"); +static_assert(offsetof(CopySubTextureCHROMIUM, source_id) == 8, + "offset of CopySubTextureCHROMIUM source_id should be 8"); +static_assert(offsetof(CopySubTextureCHROMIUM, dest_id) == 12, + "offset of CopySubTextureCHROMIUM dest_id should be 12"); +static_assert(offsetof(CopySubTextureCHROMIUM, xoffset) == 16, + "offset of CopySubTextureCHROMIUM xoffset should be 16"); +static_assert(offsetof(CopySubTextureCHROMIUM, yoffset) == 20, + "offset of CopySubTextureCHROMIUM yoffset should be 20"); struct DrawArraysInstancedANGLE { typedef DrawArraysInstancedANGLE ValueType; @@ -7890,18 +12300,18 @@ struct DrawArraysInstancedANGLE { int32_t primcount; }; -COMPILE_ASSERT(sizeof(DrawArraysInstancedANGLE) == 20, - Sizeof_DrawArraysInstancedANGLE_is_not_20); -COMPILE_ASSERT(offsetof(DrawArraysInstancedANGLE, header) == 0, - OffsetOf_DrawArraysInstancedANGLE_header_not_0); -COMPILE_ASSERT(offsetof(DrawArraysInstancedANGLE, mode) == 4, - OffsetOf_DrawArraysInstancedANGLE_mode_not_4); -COMPILE_ASSERT(offsetof(DrawArraysInstancedANGLE, first) == 8, - OffsetOf_DrawArraysInstancedANGLE_first_not_8); -COMPILE_ASSERT(offsetof(DrawArraysInstancedANGLE, count) == 12, - OffsetOf_DrawArraysInstancedANGLE_count_not_12); -COMPILE_ASSERT(offsetof(DrawArraysInstancedANGLE, primcount) == 16, - OffsetOf_DrawArraysInstancedANGLE_primcount_not_16); +static_assert(sizeof(DrawArraysInstancedANGLE) == 20, + "size of DrawArraysInstancedANGLE should be 20"); +static_assert(offsetof(DrawArraysInstancedANGLE, header) == 0, + "offset of DrawArraysInstancedANGLE header should be 0"); +static_assert(offsetof(DrawArraysInstancedANGLE, mode) == 4, + "offset of DrawArraysInstancedANGLE mode should be 4"); +static_assert(offsetof(DrawArraysInstancedANGLE, first) == 8, + "offset of DrawArraysInstancedANGLE first should be 8"); +static_assert(offsetof(DrawArraysInstancedANGLE, count) == 12, + "offset of DrawArraysInstancedANGLE count should be 12"); +static_assert(offsetof(DrawArraysInstancedANGLE, primcount) == 16, + "offset of DrawArraysInstancedANGLE primcount should be 16"); struct DrawElementsInstancedANGLE { typedef DrawElementsInstancedANGLE ValueType; @@ -7947,20 +12357,20 @@ struct DrawElementsInstancedANGLE { int32_t primcount; }; -COMPILE_ASSERT(sizeof(DrawElementsInstancedANGLE) == 24, - Sizeof_DrawElementsInstancedANGLE_is_not_24); -COMPILE_ASSERT(offsetof(DrawElementsInstancedANGLE, header) == 0, - OffsetOf_DrawElementsInstancedANGLE_header_not_0); -COMPILE_ASSERT(offsetof(DrawElementsInstancedANGLE, mode) == 4, - OffsetOf_DrawElementsInstancedANGLE_mode_not_4); -COMPILE_ASSERT(offsetof(DrawElementsInstancedANGLE, count) == 8, - OffsetOf_DrawElementsInstancedANGLE_count_not_8); -COMPILE_ASSERT(offsetof(DrawElementsInstancedANGLE, type) == 12, - OffsetOf_DrawElementsInstancedANGLE_type_not_12); -COMPILE_ASSERT(offsetof(DrawElementsInstancedANGLE, index_offset) == 16, - OffsetOf_DrawElementsInstancedANGLE_index_offset_not_16); -COMPILE_ASSERT(offsetof(DrawElementsInstancedANGLE, primcount) == 20, - OffsetOf_DrawElementsInstancedANGLE_primcount_not_20); +static_assert(sizeof(DrawElementsInstancedANGLE) == 24, + "size of DrawElementsInstancedANGLE should be 24"); +static_assert(offsetof(DrawElementsInstancedANGLE, header) == 0, + "offset of DrawElementsInstancedANGLE header should be 0"); +static_assert(offsetof(DrawElementsInstancedANGLE, mode) == 4, + "offset of DrawElementsInstancedANGLE mode should be 4"); +static_assert(offsetof(DrawElementsInstancedANGLE, count) == 8, + "offset of DrawElementsInstancedANGLE count should be 8"); +static_assert(offsetof(DrawElementsInstancedANGLE, type) == 12, + "offset of DrawElementsInstancedANGLE type should be 12"); +static_assert(offsetof(DrawElementsInstancedANGLE, index_offset) == 16, + "offset of DrawElementsInstancedANGLE index_offset should be 16"); +static_assert(offsetof(DrawElementsInstancedANGLE, primcount) == 20, + "offset of DrawElementsInstancedANGLE primcount should be 20"); struct VertexAttribDivisorANGLE { typedef VertexAttribDivisorANGLE ValueType; @@ -7990,14 +12400,14 @@ struct VertexAttribDivisorANGLE { uint32_t divisor; }; -COMPILE_ASSERT(sizeof(VertexAttribDivisorANGLE) == 12, - Sizeof_VertexAttribDivisorANGLE_is_not_12); -COMPILE_ASSERT(offsetof(VertexAttribDivisorANGLE, header) == 0, - OffsetOf_VertexAttribDivisorANGLE_header_not_0); -COMPILE_ASSERT(offsetof(VertexAttribDivisorANGLE, index) == 4, - OffsetOf_VertexAttribDivisorANGLE_index_not_4); -COMPILE_ASSERT(offsetof(VertexAttribDivisorANGLE, divisor) == 8, - OffsetOf_VertexAttribDivisorANGLE_divisor_not_8); +static_assert(sizeof(VertexAttribDivisorANGLE) == 12, + "size of VertexAttribDivisorANGLE should be 12"); +static_assert(offsetof(VertexAttribDivisorANGLE, header) == 0, + "offset of VertexAttribDivisorANGLE header should be 0"); +static_assert(offsetof(VertexAttribDivisorANGLE, index) == 4, + "offset of VertexAttribDivisorANGLE index should be 4"); +static_assert(offsetof(VertexAttribDivisorANGLE, divisor) == 8, + "offset of VertexAttribDivisorANGLE divisor should be 8"); struct ProduceTextureCHROMIUMImmediate { typedef ProduceTextureCHROMIUMImmediate ValueType; @@ -8006,12 +12416,11 @@ struct ProduceTextureCHROMIUMImmediate { static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1); static uint32_t ComputeDataSize() { - return static_cast<uint32_t>(sizeof(GLbyte) * 64); // NOLINT + return static_cast<uint32_t>(sizeof(GLbyte) * 64); } static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType) + - ComputeDataSize()); // NOLINT + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); } void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } @@ -8032,12 +12441,12 @@ struct ProduceTextureCHROMIUMImmediate { uint32_t target; }; -COMPILE_ASSERT(sizeof(ProduceTextureCHROMIUMImmediate) == 8, - Sizeof_ProduceTextureCHROMIUMImmediate_is_not_8); -COMPILE_ASSERT(offsetof(ProduceTextureCHROMIUMImmediate, header) == 0, - OffsetOf_ProduceTextureCHROMIUMImmediate_header_not_0); -COMPILE_ASSERT(offsetof(ProduceTextureCHROMIUMImmediate, target) == 4, - OffsetOf_ProduceTextureCHROMIUMImmediate_target_not_4); +static_assert(sizeof(ProduceTextureCHROMIUMImmediate) == 8, + "size of ProduceTextureCHROMIUMImmediate should be 8"); +static_assert(offsetof(ProduceTextureCHROMIUMImmediate, header) == 0, + "offset of ProduceTextureCHROMIUMImmediate header should be 0"); +static_assert(offsetof(ProduceTextureCHROMIUMImmediate, target) == 4, + "offset of ProduceTextureCHROMIUMImmediate target should be 4"); struct ProduceTextureDirectCHROMIUMImmediate { typedef ProduceTextureDirectCHROMIUMImmediate ValueType; @@ -8046,12 +12455,11 @@ struct ProduceTextureDirectCHROMIUMImmediate { static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1); static uint32_t ComputeDataSize() { - return static_cast<uint32_t>(sizeof(GLbyte) * 64); // NOLINT + return static_cast<uint32_t>(sizeof(GLbyte) * 64); } static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType) + - ComputeDataSize()); // NOLINT + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); } void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } @@ -8077,14 +12485,17 @@ struct ProduceTextureDirectCHROMIUMImmediate { uint32_t target; }; -COMPILE_ASSERT(sizeof(ProduceTextureDirectCHROMIUMImmediate) == 12, - Sizeof_ProduceTextureDirectCHROMIUMImmediate_is_not_12); -COMPILE_ASSERT(offsetof(ProduceTextureDirectCHROMIUMImmediate, header) == 0, - OffsetOf_ProduceTextureDirectCHROMIUMImmediate_header_not_0); -COMPILE_ASSERT(offsetof(ProduceTextureDirectCHROMIUMImmediate, texture) == 4, - OffsetOf_ProduceTextureDirectCHROMIUMImmediate_texture_not_4); -COMPILE_ASSERT(offsetof(ProduceTextureDirectCHROMIUMImmediate, target) == 8, - OffsetOf_ProduceTextureDirectCHROMIUMImmediate_target_not_8); +static_assert(sizeof(ProduceTextureDirectCHROMIUMImmediate) == 12, + "size of ProduceTextureDirectCHROMIUMImmediate should be 12"); +static_assert( + offsetof(ProduceTextureDirectCHROMIUMImmediate, header) == 0, + "offset of ProduceTextureDirectCHROMIUMImmediate header should be 0"); +static_assert( + offsetof(ProduceTextureDirectCHROMIUMImmediate, texture) == 4, + "offset of ProduceTextureDirectCHROMIUMImmediate texture should be 4"); +static_assert( + offsetof(ProduceTextureDirectCHROMIUMImmediate, target) == 8, + "offset of ProduceTextureDirectCHROMIUMImmediate target should be 8"); struct ConsumeTextureCHROMIUMImmediate { typedef ConsumeTextureCHROMIUMImmediate ValueType; @@ -8093,12 +12504,11 @@ struct ConsumeTextureCHROMIUMImmediate { static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1); static uint32_t ComputeDataSize() { - return static_cast<uint32_t>(sizeof(GLbyte) * 64); // NOLINT + return static_cast<uint32_t>(sizeof(GLbyte) * 64); } static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType) + - ComputeDataSize()); // NOLINT + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); } void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } @@ -8119,12 +12529,12 @@ struct ConsumeTextureCHROMIUMImmediate { uint32_t target; }; -COMPILE_ASSERT(sizeof(ConsumeTextureCHROMIUMImmediate) == 8, - Sizeof_ConsumeTextureCHROMIUMImmediate_is_not_8); -COMPILE_ASSERT(offsetof(ConsumeTextureCHROMIUMImmediate, header) == 0, - OffsetOf_ConsumeTextureCHROMIUMImmediate_header_not_0); -COMPILE_ASSERT(offsetof(ConsumeTextureCHROMIUMImmediate, target) == 4, - OffsetOf_ConsumeTextureCHROMIUMImmediate_target_not_4); +static_assert(sizeof(ConsumeTextureCHROMIUMImmediate) == 8, + "size of ConsumeTextureCHROMIUMImmediate should be 8"); +static_assert(offsetof(ConsumeTextureCHROMIUMImmediate, header) == 0, + "offset of ConsumeTextureCHROMIUMImmediate header should be 0"); +static_assert(offsetof(ConsumeTextureCHROMIUMImmediate, target) == 4, + "offset of ConsumeTextureCHROMIUMImmediate target should be 4"); struct BindUniformLocationCHROMIUMBucket { typedef BindUniformLocationCHROMIUMBucket ValueType; @@ -8159,17 +12569,19 @@ struct BindUniformLocationCHROMIUMBucket { uint32_t name_bucket_id; }; -COMPILE_ASSERT(sizeof(BindUniformLocationCHROMIUMBucket) == 16, - Sizeof_BindUniformLocationCHROMIUMBucket_is_not_16); -COMPILE_ASSERT(offsetof(BindUniformLocationCHROMIUMBucket, header) == 0, - OffsetOf_BindUniformLocationCHROMIUMBucket_header_not_0); -COMPILE_ASSERT(offsetof(BindUniformLocationCHROMIUMBucket, program) == 4, - OffsetOf_BindUniformLocationCHROMIUMBucket_program_not_4); -COMPILE_ASSERT(offsetof(BindUniformLocationCHROMIUMBucket, location) == 8, - OffsetOf_BindUniformLocationCHROMIUMBucket_location_not_8); -COMPILE_ASSERT( +static_assert(sizeof(BindUniformLocationCHROMIUMBucket) == 16, + "size of BindUniformLocationCHROMIUMBucket should be 16"); +static_assert(offsetof(BindUniformLocationCHROMIUMBucket, header) == 0, + "offset of BindUniformLocationCHROMIUMBucket header should be 0"); +static_assert( + offsetof(BindUniformLocationCHROMIUMBucket, program) == 4, + "offset of BindUniformLocationCHROMIUMBucket program should be 4"); +static_assert( + offsetof(BindUniformLocationCHROMIUMBucket, location) == 8, + "offset of BindUniformLocationCHROMIUMBucket location should be 8"); +static_assert( offsetof(BindUniformLocationCHROMIUMBucket, name_bucket_id) == 12, - OffsetOf_BindUniformLocationCHROMIUMBucket_name_bucket_id_not_12); + "offset of BindUniformLocationCHROMIUMBucket name_bucket_id should be 12"); struct GenValuebuffersCHROMIUMImmediate { typedef GenValuebuffersCHROMIUMImmediate ValueType; @@ -8206,12 +12618,12 @@ struct GenValuebuffersCHROMIUMImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(GenValuebuffersCHROMIUMImmediate) == 8, - Sizeof_GenValuebuffersCHROMIUMImmediate_is_not_8); -COMPILE_ASSERT(offsetof(GenValuebuffersCHROMIUMImmediate, header) == 0, - OffsetOf_GenValuebuffersCHROMIUMImmediate_header_not_0); -COMPILE_ASSERT(offsetof(GenValuebuffersCHROMIUMImmediate, n) == 4, - OffsetOf_GenValuebuffersCHROMIUMImmediate_n_not_4); +static_assert(sizeof(GenValuebuffersCHROMIUMImmediate) == 8, + "size of GenValuebuffersCHROMIUMImmediate should be 8"); +static_assert(offsetof(GenValuebuffersCHROMIUMImmediate, header) == 0, + "offset of GenValuebuffersCHROMIUMImmediate header should be 0"); +static_assert(offsetof(GenValuebuffersCHROMIUMImmediate, n) == 4, + "offset of GenValuebuffersCHROMIUMImmediate n should be 4"); struct DeleteValuebuffersCHROMIUMImmediate { typedef DeleteValuebuffersCHROMIUMImmediate ValueType; @@ -8248,12 +12660,13 @@ struct DeleteValuebuffersCHROMIUMImmediate { int32_t n; }; -COMPILE_ASSERT(sizeof(DeleteValuebuffersCHROMIUMImmediate) == 8, - Sizeof_DeleteValuebuffersCHROMIUMImmediate_is_not_8); -COMPILE_ASSERT(offsetof(DeleteValuebuffersCHROMIUMImmediate, header) == 0, - OffsetOf_DeleteValuebuffersCHROMIUMImmediate_header_not_0); -COMPILE_ASSERT(offsetof(DeleteValuebuffersCHROMIUMImmediate, n) == 4, - OffsetOf_DeleteValuebuffersCHROMIUMImmediate_n_not_4); +static_assert(sizeof(DeleteValuebuffersCHROMIUMImmediate) == 8, + "size of DeleteValuebuffersCHROMIUMImmediate should be 8"); +static_assert( + offsetof(DeleteValuebuffersCHROMIUMImmediate, header) == 0, + "offset of DeleteValuebuffersCHROMIUMImmediate header should be 0"); +static_assert(offsetof(DeleteValuebuffersCHROMIUMImmediate, n) == 4, + "offset of DeleteValuebuffersCHROMIUMImmediate n should be 4"); struct IsValuebufferCHROMIUM { typedef IsValuebufferCHROMIUM ValueType; @@ -8293,16 +12706,16 @@ struct IsValuebufferCHROMIUM { uint32_t result_shm_offset; }; -COMPILE_ASSERT(sizeof(IsValuebufferCHROMIUM) == 16, - Sizeof_IsValuebufferCHROMIUM_is_not_16); -COMPILE_ASSERT(offsetof(IsValuebufferCHROMIUM, header) == 0, - OffsetOf_IsValuebufferCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(IsValuebufferCHROMIUM, valuebuffer) == 4, - OffsetOf_IsValuebufferCHROMIUM_valuebuffer_not_4); -COMPILE_ASSERT(offsetof(IsValuebufferCHROMIUM, result_shm_id) == 8, - OffsetOf_IsValuebufferCHROMIUM_result_shm_id_not_8); -COMPILE_ASSERT(offsetof(IsValuebufferCHROMIUM, result_shm_offset) == 12, - OffsetOf_IsValuebufferCHROMIUM_result_shm_offset_not_12); +static_assert(sizeof(IsValuebufferCHROMIUM) == 16, + "size of IsValuebufferCHROMIUM should be 16"); +static_assert(offsetof(IsValuebufferCHROMIUM, header) == 0, + "offset of IsValuebufferCHROMIUM header should be 0"); +static_assert(offsetof(IsValuebufferCHROMIUM, valuebuffer) == 4, + "offset of IsValuebufferCHROMIUM valuebuffer should be 4"); +static_assert(offsetof(IsValuebufferCHROMIUM, result_shm_id) == 8, + "offset of IsValuebufferCHROMIUM result_shm_id should be 8"); +static_assert(offsetof(IsValuebufferCHROMIUM, result_shm_offset) == 12, + "offset of IsValuebufferCHROMIUM result_shm_offset should be 12"); struct BindValuebufferCHROMIUM { typedef BindValuebufferCHROMIUM ValueType; @@ -8332,14 +12745,14 @@ struct BindValuebufferCHROMIUM { uint32_t valuebuffer; }; -COMPILE_ASSERT(sizeof(BindValuebufferCHROMIUM) == 12, - Sizeof_BindValuebufferCHROMIUM_is_not_12); -COMPILE_ASSERT(offsetof(BindValuebufferCHROMIUM, header) == 0, - OffsetOf_BindValuebufferCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(BindValuebufferCHROMIUM, target) == 4, - OffsetOf_BindValuebufferCHROMIUM_target_not_4); -COMPILE_ASSERT(offsetof(BindValuebufferCHROMIUM, valuebuffer) == 8, - OffsetOf_BindValuebufferCHROMIUM_valuebuffer_not_8); +static_assert(sizeof(BindValuebufferCHROMIUM) == 12, + "size of BindValuebufferCHROMIUM should be 12"); +static_assert(offsetof(BindValuebufferCHROMIUM, header) == 0, + "offset of BindValuebufferCHROMIUM header should be 0"); +static_assert(offsetof(BindValuebufferCHROMIUM, target) == 4, + "offset of BindValuebufferCHROMIUM target should be 4"); +static_assert(offsetof(BindValuebufferCHROMIUM, valuebuffer) == 8, + "offset of BindValuebufferCHROMIUM valuebuffer should be 8"); struct SubscribeValueCHROMIUM { typedef SubscribeValueCHROMIUM ValueType; @@ -8369,14 +12782,14 @@ struct SubscribeValueCHROMIUM { uint32_t subscription; }; -COMPILE_ASSERT(sizeof(SubscribeValueCHROMIUM) == 12, - Sizeof_SubscribeValueCHROMIUM_is_not_12); -COMPILE_ASSERT(offsetof(SubscribeValueCHROMIUM, header) == 0, - OffsetOf_SubscribeValueCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(SubscribeValueCHROMIUM, target) == 4, - OffsetOf_SubscribeValueCHROMIUM_target_not_4); -COMPILE_ASSERT(offsetof(SubscribeValueCHROMIUM, subscription) == 8, - OffsetOf_SubscribeValueCHROMIUM_subscription_not_8); +static_assert(sizeof(SubscribeValueCHROMIUM) == 12, + "size of SubscribeValueCHROMIUM should be 12"); +static_assert(offsetof(SubscribeValueCHROMIUM, header) == 0, + "offset of SubscribeValueCHROMIUM header should be 0"); +static_assert(offsetof(SubscribeValueCHROMIUM, target) == 4, + "offset of SubscribeValueCHROMIUM target should be 4"); +static_assert(offsetof(SubscribeValueCHROMIUM, subscription) == 8, + "offset of SubscribeValueCHROMIUM subscription should be 8"); struct PopulateSubscribedValuesCHROMIUM { typedef PopulateSubscribedValuesCHROMIUM ValueType; @@ -8404,12 +12817,12 @@ struct PopulateSubscribedValuesCHROMIUM { uint32_t target; }; -COMPILE_ASSERT(sizeof(PopulateSubscribedValuesCHROMIUM) == 8, - Sizeof_PopulateSubscribedValuesCHROMIUM_is_not_8); -COMPILE_ASSERT(offsetof(PopulateSubscribedValuesCHROMIUM, header) == 0, - OffsetOf_PopulateSubscribedValuesCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(PopulateSubscribedValuesCHROMIUM, target) == 4, - OffsetOf_PopulateSubscribedValuesCHROMIUM_target_not_4); +static_assert(sizeof(PopulateSubscribedValuesCHROMIUM) == 8, + "size of PopulateSubscribedValuesCHROMIUM should be 8"); +static_assert(offsetof(PopulateSubscribedValuesCHROMIUM, header) == 0, + "offset of PopulateSubscribedValuesCHROMIUM header should be 0"); +static_assert(offsetof(PopulateSubscribedValuesCHROMIUM, target) == 4, + "offset of PopulateSubscribedValuesCHROMIUM target should be 4"); struct UniformValuebufferCHROMIUM { typedef UniformValuebufferCHROMIUM ValueType; @@ -8441,16 +12854,16 @@ struct UniformValuebufferCHROMIUM { uint32_t subscription; }; -COMPILE_ASSERT(sizeof(UniformValuebufferCHROMIUM) == 16, - Sizeof_UniformValuebufferCHROMIUM_is_not_16); -COMPILE_ASSERT(offsetof(UniformValuebufferCHROMIUM, header) == 0, - OffsetOf_UniformValuebufferCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(UniformValuebufferCHROMIUM, location) == 4, - OffsetOf_UniformValuebufferCHROMIUM_location_not_4); -COMPILE_ASSERT(offsetof(UniformValuebufferCHROMIUM, target) == 8, - OffsetOf_UniformValuebufferCHROMIUM_target_not_8); -COMPILE_ASSERT(offsetof(UniformValuebufferCHROMIUM, subscription) == 12, - OffsetOf_UniformValuebufferCHROMIUM_subscription_not_12); +static_assert(sizeof(UniformValuebufferCHROMIUM) == 16, + "size of UniformValuebufferCHROMIUM should be 16"); +static_assert(offsetof(UniformValuebufferCHROMIUM, header) == 0, + "offset of UniformValuebufferCHROMIUM header should be 0"); +static_assert(offsetof(UniformValuebufferCHROMIUM, location) == 4, + "offset of UniformValuebufferCHROMIUM location should be 4"); +static_assert(offsetof(UniformValuebufferCHROMIUM, target) == 8, + "offset of UniformValuebufferCHROMIUM target should be 8"); +static_assert(offsetof(UniformValuebufferCHROMIUM, subscription) == 12, + "offset of UniformValuebufferCHROMIUM subscription should be 12"); struct BindTexImage2DCHROMIUM { typedef BindTexImage2DCHROMIUM ValueType; @@ -8480,14 +12893,14 @@ struct BindTexImage2DCHROMIUM { int32_t imageId; }; -COMPILE_ASSERT(sizeof(BindTexImage2DCHROMIUM) == 12, - Sizeof_BindTexImage2DCHROMIUM_is_not_12); -COMPILE_ASSERT(offsetof(BindTexImage2DCHROMIUM, header) == 0, - OffsetOf_BindTexImage2DCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(BindTexImage2DCHROMIUM, target) == 4, - OffsetOf_BindTexImage2DCHROMIUM_target_not_4); -COMPILE_ASSERT(offsetof(BindTexImage2DCHROMIUM, imageId) == 8, - OffsetOf_BindTexImage2DCHROMIUM_imageId_not_8); +static_assert(sizeof(BindTexImage2DCHROMIUM) == 12, + "size of BindTexImage2DCHROMIUM should be 12"); +static_assert(offsetof(BindTexImage2DCHROMIUM, header) == 0, + "offset of BindTexImage2DCHROMIUM header should be 0"); +static_assert(offsetof(BindTexImage2DCHROMIUM, target) == 4, + "offset of BindTexImage2DCHROMIUM target should be 4"); +static_assert(offsetof(BindTexImage2DCHROMIUM, imageId) == 8, + "offset of BindTexImage2DCHROMIUM imageId should be 8"); struct ReleaseTexImage2DCHROMIUM { typedef ReleaseTexImage2DCHROMIUM ValueType; @@ -8517,14 +12930,14 @@ struct ReleaseTexImage2DCHROMIUM { int32_t imageId; }; -COMPILE_ASSERT(sizeof(ReleaseTexImage2DCHROMIUM) == 12, - Sizeof_ReleaseTexImage2DCHROMIUM_is_not_12); -COMPILE_ASSERT(offsetof(ReleaseTexImage2DCHROMIUM, header) == 0, - OffsetOf_ReleaseTexImage2DCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(ReleaseTexImage2DCHROMIUM, target) == 4, - OffsetOf_ReleaseTexImage2DCHROMIUM_target_not_4); -COMPILE_ASSERT(offsetof(ReleaseTexImage2DCHROMIUM, imageId) == 8, - OffsetOf_ReleaseTexImage2DCHROMIUM_imageId_not_8); +static_assert(sizeof(ReleaseTexImage2DCHROMIUM) == 12, + "size of ReleaseTexImage2DCHROMIUM should be 12"); +static_assert(offsetof(ReleaseTexImage2DCHROMIUM, header) == 0, + "offset of ReleaseTexImage2DCHROMIUM header should be 0"); +static_assert(offsetof(ReleaseTexImage2DCHROMIUM, target) == 4, + "offset of ReleaseTexImage2DCHROMIUM target should be 4"); +static_assert(offsetof(ReleaseTexImage2DCHROMIUM, imageId) == 8, + "offset of ReleaseTexImage2DCHROMIUM imageId should be 8"); struct TraceBeginCHROMIUM { typedef TraceBeginCHROMIUM ValueType; @@ -8538,26 +12951,30 @@ struct TraceBeginCHROMIUM { void SetHeader() { header.SetCmd<ValueType>(); } - void Init(GLuint _bucket_id) { + void Init(GLuint _category_bucket_id, GLuint _name_bucket_id) { SetHeader(); - bucket_id = _bucket_id; + category_bucket_id = _category_bucket_id; + name_bucket_id = _name_bucket_id; } - void* Set(void* cmd, GLuint _bucket_id) { - static_cast<ValueType*>(cmd)->Init(_bucket_id); + void* Set(void* cmd, GLuint _category_bucket_id, GLuint _name_bucket_id) { + static_cast<ValueType*>(cmd)->Init(_category_bucket_id, _name_bucket_id); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; - uint32_t bucket_id; + uint32_t category_bucket_id; + uint32_t name_bucket_id; }; -COMPILE_ASSERT(sizeof(TraceBeginCHROMIUM) == 8, - Sizeof_TraceBeginCHROMIUM_is_not_8); -COMPILE_ASSERT(offsetof(TraceBeginCHROMIUM, header) == 0, - OffsetOf_TraceBeginCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(TraceBeginCHROMIUM, bucket_id) == 4, - OffsetOf_TraceBeginCHROMIUM_bucket_id_not_4); +static_assert(sizeof(TraceBeginCHROMIUM) == 12, + "size of TraceBeginCHROMIUM should be 12"); +static_assert(offsetof(TraceBeginCHROMIUM, header) == 0, + "offset of TraceBeginCHROMIUM header should be 0"); +static_assert(offsetof(TraceBeginCHROMIUM, category_bucket_id) == 4, + "offset of TraceBeginCHROMIUM category_bucket_id should be 4"); +static_assert(offsetof(TraceBeginCHROMIUM, name_bucket_id) == 8, + "offset of TraceBeginCHROMIUM name_bucket_id should be 8"); struct TraceEndCHROMIUM { typedef TraceEndCHROMIUM ValueType; @@ -8581,9 +12998,10 @@ struct TraceEndCHROMIUM { gpu::CommandHeader header; }; -COMPILE_ASSERT(sizeof(TraceEndCHROMIUM) == 4, Sizeof_TraceEndCHROMIUM_is_not_4); -COMPILE_ASSERT(offsetof(TraceEndCHROMIUM, header) == 0, - OffsetOf_TraceEndCHROMIUM_header_not_0); +static_assert(sizeof(TraceEndCHROMIUM) == 4, + "size of TraceEndCHROMIUM should be 4"); +static_assert(offsetof(TraceEndCHROMIUM, header) == 0, + "offset of TraceEndCHROMIUM header should be 0"); struct AsyncTexSubImage2DCHROMIUM { typedef AsyncTexSubImage2DCHROMIUM ValueType; @@ -8663,36 +13081,40 @@ struct AsyncTexSubImage2DCHROMIUM { uint32_t sync_data_shm_offset; }; -COMPILE_ASSERT(sizeof(AsyncTexSubImage2DCHROMIUM) == 56, - Sizeof_AsyncTexSubImage2DCHROMIUM_is_not_56); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, header) == 0, - OffsetOf_AsyncTexSubImage2DCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, target) == 4, - OffsetOf_AsyncTexSubImage2DCHROMIUM_target_not_4); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, level) == 8, - OffsetOf_AsyncTexSubImage2DCHROMIUM_level_not_8); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, xoffset) == 12, - OffsetOf_AsyncTexSubImage2DCHROMIUM_xoffset_not_12); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, yoffset) == 16, - OffsetOf_AsyncTexSubImage2DCHROMIUM_yoffset_not_16); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, width) == 20, - OffsetOf_AsyncTexSubImage2DCHROMIUM_width_not_20); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, height) == 24, - OffsetOf_AsyncTexSubImage2DCHROMIUM_height_not_24); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, format) == 28, - OffsetOf_AsyncTexSubImage2DCHROMIUM_format_not_28); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, type) == 32, - OffsetOf_AsyncTexSubImage2DCHROMIUM_type_not_32); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, data_shm_id) == 36, - OffsetOf_AsyncTexSubImage2DCHROMIUM_data_shm_id_not_36); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, data_shm_offset) == 40, - OffsetOf_AsyncTexSubImage2DCHROMIUM_data_shm_offset_not_40); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, async_upload_token) == 44, - OffsetOf_AsyncTexSubImage2DCHROMIUM_async_upload_token_not_44); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, sync_data_shm_id) == 48, - OffsetOf_AsyncTexSubImage2DCHROMIUM_sync_data_shm_id_not_48); -COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, sync_data_shm_offset) == 52, - OffsetOf_AsyncTexSubImage2DCHROMIUM_sync_data_shm_offset_not_52); +static_assert(sizeof(AsyncTexSubImage2DCHROMIUM) == 56, + "size of AsyncTexSubImage2DCHROMIUM should be 56"); +static_assert(offsetof(AsyncTexSubImage2DCHROMIUM, header) == 0, + "offset of AsyncTexSubImage2DCHROMIUM header should be 0"); +static_assert(offsetof(AsyncTexSubImage2DCHROMIUM, target) == 4, + "offset of AsyncTexSubImage2DCHROMIUM target should be 4"); +static_assert(offsetof(AsyncTexSubImage2DCHROMIUM, level) == 8, + "offset of AsyncTexSubImage2DCHROMIUM level should be 8"); +static_assert(offsetof(AsyncTexSubImage2DCHROMIUM, xoffset) == 12, + "offset of AsyncTexSubImage2DCHROMIUM xoffset should be 12"); +static_assert(offsetof(AsyncTexSubImage2DCHROMIUM, yoffset) == 16, + "offset of AsyncTexSubImage2DCHROMIUM yoffset should be 16"); +static_assert(offsetof(AsyncTexSubImage2DCHROMIUM, width) == 20, + "offset of AsyncTexSubImage2DCHROMIUM width should be 20"); +static_assert(offsetof(AsyncTexSubImage2DCHROMIUM, height) == 24, + "offset of AsyncTexSubImage2DCHROMIUM height should be 24"); +static_assert(offsetof(AsyncTexSubImage2DCHROMIUM, format) == 28, + "offset of AsyncTexSubImage2DCHROMIUM format should be 28"); +static_assert(offsetof(AsyncTexSubImage2DCHROMIUM, type) == 32, + "offset of AsyncTexSubImage2DCHROMIUM type should be 32"); +static_assert(offsetof(AsyncTexSubImage2DCHROMIUM, data_shm_id) == 36, + "offset of AsyncTexSubImage2DCHROMIUM data_shm_id should be 36"); +static_assert( + offsetof(AsyncTexSubImage2DCHROMIUM, data_shm_offset) == 40, + "offset of AsyncTexSubImage2DCHROMIUM data_shm_offset should be 40"); +static_assert( + offsetof(AsyncTexSubImage2DCHROMIUM, async_upload_token) == 44, + "offset of AsyncTexSubImage2DCHROMIUM async_upload_token should be 44"); +static_assert( + offsetof(AsyncTexSubImage2DCHROMIUM, sync_data_shm_id) == 48, + "offset of AsyncTexSubImage2DCHROMIUM sync_data_shm_id should be 48"); +static_assert( + offsetof(AsyncTexSubImage2DCHROMIUM, sync_data_shm_offset) == 52, + "offset of AsyncTexSubImage2DCHROMIUM sync_data_shm_offset should be 52"); struct AsyncTexImage2DCHROMIUM { typedef AsyncTexImage2DCHROMIUM ValueType; @@ -8769,34 +13191,38 @@ struct AsyncTexImage2DCHROMIUM { static const int32_t border = 0; }; -COMPILE_ASSERT(sizeof(AsyncTexImage2DCHROMIUM) == 52, - Sizeof_AsyncTexImage2DCHROMIUM_is_not_52); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, header) == 0, - OffsetOf_AsyncTexImage2DCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, target) == 4, - OffsetOf_AsyncTexImage2DCHROMIUM_target_not_4); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, level) == 8, - OffsetOf_AsyncTexImage2DCHROMIUM_level_not_8); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, internalformat) == 12, - OffsetOf_AsyncTexImage2DCHROMIUM_internalformat_not_12); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, width) == 16, - OffsetOf_AsyncTexImage2DCHROMIUM_width_not_16); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, height) == 20, - OffsetOf_AsyncTexImage2DCHROMIUM_height_not_20); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, format) == 24, - OffsetOf_AsyncTexImage2DCHROMIUM_format_not_24); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, type) == 28, - OffsetOf_AsyncTexImage2DCHROMIUM_type_not_28); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, pixels_shm_id) == 32, - OffsetOf_AsyncTexImage2DCHROMIUM_pixels_shm_id_not_32); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, pixels_shm_offset) == 36, - OffsetOf_AsyncTexImage2DCHROMIUM_pixels_shm_offset_not_36); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, async_upload_token) == 40, - OffsetOf_AsyncTexImage2DCHROMIUM_async_upload_token_not_40); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, sync_data_shm_id) == 44, - OffsetOf_AsyncTexImage2DCHROMIUM_sync_data_shm_id_not_44); -COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, sync_data_shm_offset) == 48, - OffsetOf_AsyncTexImage2DCHROMIUM_sync_data_shm_offset_not_48); +static_assert(sizeof(AsyncTexImage2DCHROMIUM) == 52, + "size of AsyncTexImage2DCHROMIUM should be 52"); +static_assert(offsetof(AsyncTexImage2DCHROMIUM, header) == 0, + "offset of AsyncTexImage2DCHROMIUM header should be 0"); +static_assert(offsetof(AsyncTexImage2DCHROMIUM, target) == 4, + "offset of AsyncTexImage2DCHROMIUM target should be 4"); +static_assert(offsetof(AsyncTexImage2DCHROMIUM, level) == 8, + "offset of AsyncTexImage2DCHROMIUM level should be 8"); +static_assert(offsetof(AsyncTexImage2DCHROMIUM, internalformat) == 12, + "offset of AsyncTexImage2DCHROMIUM internalformat should be 12"); +static_assert(offsetof(AsyncTexImage2DCHROMIUM, width) == 16, + "offset of AsyncTexImage2DCHROMIUM width should be 16"); +static_assert(offsetof(AsyncTexImage2DCHROMIUM, height) == 20, + "offset of AsyncTexImage2DCHROMIUM height should be 20"); +static_assert(offsetof(AsyncTexImage2DCHROMIUM, format) == 24, + "offset of AsyncTexImage2DCHROMIUM format should be 24"); +static_assert(offsetof(AsyncTexImage2DCHROMIUM, type) == 28, + "offset of AsyncTexImage2DCHROMIUM type should be 28"); +static_assert(offsetof(AsyncTexImage2DCHROMIUM, pixels_shm_id) == 32, + "offset of AsyncTexImage2DCHROMIUM pixels_shm_id should be 32"); +static_assert( + offsetof(AsyncTexImage2DCHROMIUM, pixels_shm_offset) == 36, + "offset of AsyncTexImage2DCHROMIUM pixels_shm_offset should be 36"); +static_assert( + offsetof(AsyncTexImage2DCHROMIUM, async_upload_token) == 40, + "offset of AsyncTexImage2DCHROMIUM async_upload_token should be 40"); +static_assert( + offsetof(AsyncTexImage2DCHROMIUM, sync_data_shm_id) == 44, + "offset of AsyncTexImage2DCHROMIUM sync_data_shm_id should be 44"); +static_assert( + offsetof(AsyncTexImage2DCHROMIUM, sync_data_shm_offset) == 48, + "offset of AsyncTexImage2DCHROMIUM sync_data_shm_offset should be 48"); struct WaitAsyncTexImage2DCHROMIUM { typedef WaitAsyncTexImage2DCHROMIUM ValueType; @@ -8824,12 +13250,12 @@ struct WaitAsyncTexImage2DCHROMIUM { uint32_t target; }; -COMPILE_ASSERT(sizeof(WaitAsyncTexImage2DCHROMIUM) == 8, - Sizeof_WaitAsyncTexImage2DCHROMIUM_is_not_8); -COMPILE_ASSERT(offsetof(WaitAsyncTexImage2DCHROMIUM, header) == 0, - OffsetOf_WaitAsyncTexImage2DCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(WaitAsyncTexImage2DCHROMIUM, target) == 4, - OffsetOf_WaitAsyncTexImage2DCHROMIUM_target_not_4); +static_assert(sizeof(WaitAsyncTexImage2DCHROMIUM) == 8, + "size of WaitAsyncTexImage2DCHROMIUM should be 8"); +static_assert(offsetof(WaitAsyncTexImage2DCHROMIUM, header) == 0, + "offset of WaitAsyncTexImage2DCHROMIUM header should be 0"); +static_assert(offsetof(WaitAsyncTexImage2DCHROMIUM, target) == 4, + "offset of WaitAsyncTexImage2DCHROMIUM target should be 4"); struct WaitAllAsyncTexImage2DCHROMIUM { typedef WaitAllAsyncTexImage2DCHROMIUM ValueType; @@ -8853,10 +13279,10 @@ struct WaitAllAsyncTexImage2DCHROMIUM { gpu::CommandHeader header; }; -COMPILE_ASSERT(sizeof(WaitAllAsyncTexImage2DCHROMIUM) == 4, - Sizeof_WaitAllAsyncTexImage2DCHROMIUM_is_not_4); -COMPILE_ASSERT(offsetof(WaitAllAsyncTexImage2DCHROMIUM, header) == 0, - OffsetOf_WaitAllAsyncTexImage2DCHROMIUM_header_not_0); +static_assert(sizeof(WaitAllAsyncTexImage2DCHROMIUM) == 4, + "size of WaitAllAsyncTexImage2DCHROMIUM should be 4"); +static_assert(offsetof(WaitAllAsyncTexImage2DCHROMIUM, header) == 0, + "offset of WaitAllAsyncTexImage2DCHROMIUM header should be 0"); struct DiscardFramebufferEXTImmediate { typedef DiscardFramebufferEXTImmediate ValueType; @@ -8898,14 +13324,14 @@ struct DiscardFramebufferEXTImmediate { int32_t count; }; -COMPILE_ASSERT(sizeof(DiscardFramebufferEXTImmediate) == 12, - Sizeof_DiscardFramebufferEXTImmediate_is_not_12); -COMPILE_ASSERT(offsetof(DiscardFramebufferEXTImmediate, header) == 0, - OffsetOf_DiscardFramebufferEXTImmediate_header_not_0); -COMPILE_ASSERT(offsetof(DiscardFramebufferEXTImmediate, target) == 4, - OffsetOf_DiscardFramebufferEXTImmediate_target_not_4); -COMPILE_ASSERT(offsetof(DiscardFramebufferEXTImmediate, count) == 8, - OffsetOf_DiscardFramebufferEXTImmediate_count_not_8); +static_assert(sizeof(DiscardFramebufferEXTImmediate) == 12, + "size of DiscardFramebufferEXTImmediate should be 12"); +static_assert(offsetof(DiscardFramebufferEXTImmediate, header) == 0, + "offset of DiscardFramebufferEXTImmediate header should be 0"); +static_assert(offsetof(DiscardFramebufferEXTImmediate, target) == 4, + "offset of DiscardFramebufferEXTImmediate target should be 4"); +static_assert(offsetof(DiscardFramebufferEXTImmediate, count) == 8, + "offset of DiscardFramebufferEXTImmediate count should be 8"); struct LoseContextCHROMIUM { typedef LoseContextCHROMIUM ValueType; @@ -8935,14 +13361,14 @@ struct LoseContextCHROMIUM { uint32_t other; }; -COMPILE_ASSERT(sizeof(LoseContextCHROMIUM) == 12, - Sizeof_LoseContextCHROMIUM_is_not_12); -COMPILE_ASSERT(offsetof(LoseContextCHROMIUM, header) == 0, - OffsetOf_LoseContextCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(LoseContextCHROMIUM, current) == 4, - OffsetOf_LoseContextCHROMIUM_current_not_4); -COMPILE_ASSERT(offsetof(LoseContextCHROMIUM, other) == 8, - OffsetOf_LoseContextCHROMIUM_other_not_8); +static_assert(sizeof(LoseContextCHROMIUM) == 12, + "size of LoseContextCHROMIUM should be 12"); +static_assert(offsetof(LoseContextCHROMIUM, header) == 0, + "offset of LoseContextCHROMIUM header should be 0"); +static_assert(offsetof(LoseContextCHROMIUM, current) == 4, + "offset of LoseContextCHROMIUM current should be 4"); +static_assert(offsetof(LoseContextCHROMIUM, other) == 8, + "offset of LoseContextCHROMIUM other should be 8"); struct WaitSyncPointCHROMIUM { typedef WaitSyncPointCHROMIUM ValueType; @@ -8970,12 +13396,12 @@ struct WaitSyncPointCHROMIUM { uint32_t sync_point; }; -COMPILE_ASSERT(sizeof(WaitSyncPointCHROMIUM) == 8, - Sizeof_WaitSyncPointCHROMIUM_is_not_8); -COMPILE_ASSERT(offsetof(WaitSyncPointCHROMIUM, header) == 0, - OffsetOf_WaitSyncPointCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(WaitSyncPointCHROMIUM, sync_point) == 4, - OffsetOf_WaitSyncPointCHROMIUM_sync_point_not_4); +static_assert(sizeof(WaitSyncPointCHROMIUM) == 8, + "size of WaitSyncPointCHROMIUM should be 8"); +static_assert(offsetof(WaitSyncPointCHROMIUM, header) == 0, + "offset of WaitSyncPointCHROMIUM header should be 0"); +static_assert(offsetof(WaitSyncPointCHROMIUM, sync_point) == 4, + "offset of WaitSyncPointCHROMIUM sync_point should be 4"); struct DrawBuffersEXTImmediate { typedef DrawBuffersEXTImmediate ValueType; @@ -9012,12 +13438,12 @@ struct DrawBuffersEXTImmediate { int32_t count; }; -COMPILE_ASSERT(sizeof(DrawBuffersEXTImmediate) == 8, - Sizeof_DrawBuffersEXTImmediate_is_not_8); -COMPILE_ASSERT(offsetof(DrawBuffersEXTImmediate, header) == 0, - OffsetOf_DrawBuffersEXTImmediate_header_not_0); -COMPILE_ASSERT(offsetof(DrawBuffersEXTImmediate, count) == 4, - OffsetOf_DrawBuffersEXTImmediate_count_not_4); +static_assert(sizeof(DrawBuffersEXTImmediate) == 8, + "size of DrawBuffersEXTImmediate should be 8"); +static_assert(offsetof(DrawBuffersEXTImmediate, header) == 0, + "offset of DrawBuffersEXTImmediate header should be 0"); +static_assert(offsetof(DrawBuffersEXTImmediate, count) == 4, + "offset of DrawBuffersEXTImmediate count should be 4"); struct DiscardBackbufferCHROMIUM { typedef DiscardBackbufferCHROMIUM ValueType; @@ -9041,10 +13467,10 @@ struct DiscardBackbufferCHROMIUM { gpu::CommandHeader header; }; -COMPILE_ASSERT(sizeof(DiscardBackbufferCHROMIUM) == 4, - Sizeof_DiscardBackbufferCHROMIUM_is_not_4); -COMPILE_ASSERT(offsetof(DiscardBackbufferCHROMIUM, header) == 0, - OffsetOf_DiscardBackbufferCHROMIUM_header_not_0); +static_assert(sizeof(DiscardBackbufferCHROMIUM) == 4, + "size of DiscardBackbufferCHROMIUM should be 4"); +static_assert(offsetof(DiscardBackbufferCHROMIUM, header) == 0, + "offset of DiscardBackbufferCHROMIUM header should be 0"); struct ScheduleOverlayPlaneCHROMIUM { typedef ScheduleOverlayPlaneCHROMIUM ValueType; @@ -9116,32 +13542,69 @@ struct ScheduleOverlayPlaneCHROMIUM { float uv_height; }; -COMPILE_ASSERT(sizeof(ScheduleOverlayPlaneCHROMIUM) == 48, - Sizeof_ScheduleOverlayPlaneCHROMIUM_is_not_48); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, header) == 0, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, plane_z_order) == 4, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_plane_z_order_not_4); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, plane_transform) == 8, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_plane_transform_not_8); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, overlay_texture_id) == 12, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_overlay_texture_id_not_12); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, bounds_x) == 16, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_bounds_x_not_16); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, bounds_y) == 20, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_bounds_y_not_20); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, bounds_width) == 24, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_bounds_width_not_24); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, bounds_height) == 28, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_bounds_height_not_28); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, uv_x) == 32, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_uv_x_not_32); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, uv_y) == 36, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_uv_y_not_36); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, uv_width) == 40, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_uv_width_not_40); -COMPILE_ASSERT(offsetof(ScheduleOverlayPlaneCHROMIUM, uv_height) == 44, - OffsetOf_ScheduleOverlayPlaneCHROMIUM_uv_height_not_44); +static_assert(sizeof(ScheduleOverlayPlaneCHROMIUM) == 48, + "size of ScheduleOverlayPlaneCHROMIUM should be 48"); +static_assert(offsetof(ScheduleOverlayPlaneCHROMIUM, header) == 0, + "offset of ScheduleOverlayPlaneCHROMIUM header should be 0"); +static_assert( + offsetof(ScheduleOverlayPlaneCHROMIUM, plane_z_order) == 4, + "offset of ScheduleOverlayPlaneCHROMIUM plane_z_order should be 4"); +static_assert( + offsetof(ScheduleOverlayPlaneCHROMIUM, plane_transform) == 8, + "offset of ScheduleOverlayPlaneCHROMIUM plane_transform should be 8"); +static_assert( + offsetof(ScheduleOverlayPlaneCHROMIUM, overlay_texture_id) == 12, + "offset of ScheduleOverlayPlaneCHROMIUM overlay_texture_id should be 12"); +static_assert(offsetof(ScheduleOverlayPlaneCHROMIUM, bounds_x) == 16, + "offset of ScheduleOverlayPlaneCHROMIUM bounds_x should be 16"); +static_assert(offsetof(ScheduleOverlayPlaneCHROMIUM, bounds_y) == 20, + "offset of ScheduleOverlayPlaneCHROMIUM bounds_y should be 20"); +static_assert( + offsetof(ScheduleOverlayPlaneCHROMIUM, bounds_width) == 24, + "offset of ScheduleOverlayPlaneCHROMIUM bounds_width should be 24"); +static_assert( + offsetof(ScheduleOverlayPlaneCHROMIUM, bounds_height) == 28, + "offset of ScheduleOverlayPlaneCHROMIUM bounds_height should be 28"); +static_assert(offsetof(ScheduleOverlayPlaneCHROMIUM, uv_x) == 32, + "offset of ScheduleOverlayPlaneCHROMIUM uv_x should be 32"); +static_assert(offsetof(ScheduleOverlayPlaneCHROMIUM, uv_y) == 36, + "offset of ScheduleOverlayPlaneCHROMIUM uv_y should be 36"); +static_assert(offsetof(ScheduleOverlayPlaneCHROMIUM, uv_width) == 40, + "offset of ScheduleOverlayPlaneCHROMIUM uv_width should be 40"); +static_assert(offsetof(ScheduleOverlayPlaneCHROMIUM, uv_height) == 44, + "offset of ScheduleOverlayPlaneCHROMIUM uv_height should be 44"); + +struct SwapInterval { + typedef SwapInterval ValueType; + static const CommandId kCmdId = kSwapInterval; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLint _interval) { + SetHeader(); + interval = _interval; + } + + void* Set(void* cmd, GLint _interval) { + static_cast<ValueType*>(cmd)->Init(_interval); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + int32_t interval; +}; + +static_assert(sizeof(SwapInterval) == 8, "size of SwapInterval should be 8"); +static_assert(offsetof(SwapInterval, header) == 0, + "offset of SwapInterval header should be 0"); +static_assert(offsetof(SwapInterval, interval) == 4, + "offset of SwapInterval interval should be 4"); struct MatrixLoadfCHROMIUMImmediate { typedef MatrixLoadfCHROMIUMImmediate ValueType; @@ -9150,12 +13613,11 @@ struct MatrixLoadfCHROMIUMImmediate { static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); static uint32_t ComputeDataSize() { - return static_cast<uint32_t>(sizeof(GLfloat) * 16); // NOLINT + return static_cast<uint32_t>(sizeof(GLfloat) * 16); } static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType) + - ComputeDataSize()); // NOLINT + return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize()); } void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } @@ -9176,12 +13638,12 @@ struct MatrixLoadfCHROMIUMImmediate { uint32_t matrixMode; }; -COMPILE_ASSERT(sizeof(MatrixLoadfCHROMIUMImmediate) == 8, - Sizeof_MatrixLoadfCHROMIUMImmediate_is_not_8); -COMPILE_ASSERT(offsetof(MatrixLoadfCHROMIUMImmediate, header) == 0, - OffsetOf_MatrixLoadfCHROMIUMImmediate_header_not_0); -COMPILE_ASSERT(offsetof(MatrixLoadfCHROMIUMImmediate, matrixMode) == 4, - OffsetOf_MatrixLoadfCHROMIUMImmediate_matrixMode_not_4); +static_assert(sizeof(MatrixLoadfCHROMIUMImmediate) == 8, + "size of MatrixLoadfCHROMIUMImmediate should be 8"); +static_assert(offsetof(MatrixLoadfCHROMIUMImmediate, header) == 0, + "offset of MatrixLoadfCHROMIUMImmediate header should be 0"); +static_assert(offsetof(MatrixLoadfCHROMIUMImmediate, matrixMode) == 4, + "offset of MatrixLoadfCHROMIUMImmediate matrixMode should be 4"); struct MatrixLoadIdentityCHROMIUM { typedef MatrixLoadIdentityCHROMIUM ValueType; @@ -9209,12 +13671,12 @@ struct MatrixLoadIdentityCHROMIUM { uint32_t matrixMode; }; -COMPILE_ASSERT(sizeof(MatrixLoadIdentityCHROMIUM) == 8, - Sizeof_MatrixLoadIdentityCHROMIUM_is_not_8); -COMPILE_ASSERT(offsetof(MatrixLoadIdentityCHROMIUM, header) == 0, - OffsetOf_MatrixLoadIdentityCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(MatrixLoadIdentityCHROMIUM, matrixMode) == 4, - OffsetOf_MatrixLoadIdentityCHROMIUM_matrixMode_not_4); +static_assert(sizeof(MatrixLoadIdentityCHROMIUM) == 8, + "size of MatrixLoadIdentityCHROMIUM should be 8"); +static_assert(offsetof(MatrixLoadIdentityCHROMIUM, header) == 0, + "offset of MatrixLoadIdentityCHROMIUM header should be 0"); +static_assert(offsetof(MatrixLoadIdentityCHROMIUM, matrixMode) == 4, + "offset of MatrixLoadIdentityCHROMIUM matrixMode should be 4"); struct BlendBarrierKHR { typedef BlendBarrierKHR ValueType; @@ -9238,8 +13700,9 @@ struct BlendBarrierKHR { gpu::CommandHeader header; }; -COMPILE_ASSERT(sizeof(BlendBarrierKHR) == 4, Sizeof_BlendBarrierKHR_is_not_4); -COMPILE_ASSERT(offsetof(BlendBarrierKHR, header) == 0, - OffsetOf_BlendBarrierKHR_header_not_0); +static_assert(sizeof(BlendBarrierKHR) == 4, + "size of BlendBarrierKHR should be 4"); +static_assert(offsetof(BlendBarrierKHR, header) == 0, + "offset of BlendBarrierKHR header should be 0"); #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format_test.cc b/chromium/gpu/command_buffer/common/gles2_cmd_format_test.cc index ea683a668eb..d11b2c5d134 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format_test.cc +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format_test.cc @@ -7,10 +7,12 @@ #include <limits> #include "base/bind.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" -#include "testing/gtest/include/gtest/gtest.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" +#include "testing/gtest/include/gtest/gtest.h" namespace gpu { namespace gles2 { @@ -94,18 +96,16 @@ TEST(GLES2FormatAsyncUploadSyncTest, AsyncUploadSync) { // Set the async upload token on the fake upload thread and assert that // the associated buffer still has the given token. - thread.message_loop()->PostTask(FROM_HERE, - base::Bind(&SignalCompletion, - &buffer_tokens[buffer], - async_token, - &sync)); + thread.task_runner()->PostTask( + FROM_HERE, base::Bind(&SignalCompletion, &buffer_tokens[buffer], + async_token, &sync)); } // Flush the thread message loop before starting again. base::WaitableEvent waitable(false, false); - thread.message_loop()->PostTask(FROM_HERE, - base::Bind(&base::WaitableEvent::Signal, - base::Unretained(&waitable))); + thread.task_runner()->PostTask( + FROM_HERE, + base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waitable))); waitable.Wait(); } } diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index a21c8b8bb20..ad56c24d423 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -62,6 +62,36 @@ TEST_F(GLES2FormatTest, BindBuffer) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, BindBufferBase) { + cmds::BindBufferBase& cmd = *GetBufferAs<cmds::BindBufferBase>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), + static_cast<GLuint>(12), static_cast<GLuint>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::BindBufferBase::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<GLuint>(13), cmd.buffer); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, BindBufferRange) { + cmds::BindBufferRange& cmd = *GetBufferAs<cmds::BindBufferRange>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLuint>(12), + static_cast<GLuint>(13), static_cast<GLintptr>(14), + static_cast<GLsizeiptr>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::BindBufferRange::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<GLuint>(13), cmd.buffer); + EXPECT_EQ(static_cast<GLintptr>(14), cmd.offset); + EXPECT_EQ(static_cast<GLsizeiptr>(15), cmd.size); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, BindFramebuffer) { cmds::BindFramebuffer& cmd = *GetBufferAs<cmds::BindFramebuffer>(); void* next_cmd = @@ -86,6 +116,18 @@ TEST_F(GLES2FormatTest, BindRenderbuffer) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, BindSampler) { + cmds::BindSampler& cmd = *GetBufferAs<cmds::BindSampler>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12)); + EXPECT_EQ(static_cast<uint32_t>(cmds::BindSampler::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.unit); + EXPECT_EQ(static_cast<GLuint>(12), cmd.sampler); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, BindTexture) { cmds::BindTexture& cmd = *GetBufferAs<cmds::BindTexture>(); void* next_cmd = @@ -98,6 +140,19 @@ TEST_F(GLES2FormatTest, BindTexture) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, BindTransformFeedback) { + cmds::BindTransformFeedback& cmd = + *GetBufferAs<cmds::BindTransformFeedback>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLuint>(12)); + EXPECT_EQ(static_cast<uint32_t>(cmds::BindTransformFeedback::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLuint>(12), cmd.transformfeedback); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, BlendColor) { cmds::BlendColor& cmd = *GetBufferAs<cmds::BlendColor>(); void* next_cmd = @@ -220,6 +275,90 @@ TEST_F(GLES2FormatTest, Clear) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, ClearBufferfi) { + cmds::ClearBufferfi& cmd = *GetBufferAs<cmds::ClearBufferfi>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12), + static_cast<GLfloat>(13), static_cast<GLint>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::ClearBufferfi::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.buffer); + EXPECT_EQ(static_cast<GLint>(12), cmd.drawbuffers); + EXPECT_EQ(static_cast<GLfloat>(13), cmd.depth); + EXPECT_EQ(static_cast<GLint>(14), cmd.stencil); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, ClearBufferfvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + }; + cmds::ClearBufferfvImmediate& cmd = + *GetBufferAs<cmds::ClearBufferfvImmediate>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::ClearBufferfvImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.buffer); + EXPECT_EQ(static_cast<GLint>(12), cmd.drawbuffers); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + +TEST_F(GLES2FormatTest, ClearBufferivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLint data[] = { + static_cast<GLint>(kSomeBaseValueToTestWith + 0), + static_cast<GLint>(kSomeBaseValueToTestWith + 1), + static_cast<GLint>(kSomeBaseValueToTestWith + 2), + static_cast<GLint>(kSomeBaseValueToTestWith + 3), + }; + cmds::ClearBufferivImmediate& cmd = + *GetBufferAs<cmds::ClearBufferivImmediate>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::ClearBufferivImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.buffer); + EXPECT_EQ(static_cast<GLint>(12), cmd.drawbuffers); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + +TEST_F(GLES2FormatTest, ClearBufferuivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLuint data[] = { + static_cast<GLuint>(kSomeBaseValueToTestWith + 0), + static_cast<GLuint>(kSomeBaseValueToTestWith + 1), + static_cast<GLuint>(kSomeBaseValueToTestWith + 2), + static_cast<GLuint>(kSomeBaseValueToTestWith + 3), + }; + cmds::ClearBufferuivImmediate& cmd = + *GetBufferAs<cmds::ClearBufferuivImmediate>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::ClearBufferuivImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.buffer); + EXPECT_EQ(static_cast<GLint>(12), cmd.drawbuffers); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + TEST_F(GLES2FormatTest, ClearColor) { cmds::ClearColor& cmd = *GetBufferAs<cmds::ClearColor>(); void* next_cmd = @@ -255,6 +394,24 @@ TEST_F(GLES2FormatTest, ClearStencil) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, ClientWaitSync) { + cmds::ClientWaitSync& cmd = *GetBufferAs<cmds::ClientWaitSync>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLbitfield>(12), + static_cast<GLuint>(13), static_cast<GLuint>(14), + static_cast<uint32_t>(15), static_cast<uint32_t>(16)); + EXPECT_EQ(static_cast<uint32_t>(cmds::ClientWaitSync::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sync); + EXPECT_EQ(static_cast<GLbitfield>(12), cmd.flags); + EXPECT_EQ(static_cast<GLuint>(13), cmd.timeout_0); + EXPECT_EQ(static_cast<GLuint>(14), cmd.timeout_1); + EXPECT_EQ(static_cast<uint32_t>(15), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32_t>(16), cmd.result_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, ColorMask) { cmds::ColorMask& cmd = *GetBufferAs<cmds::ColorMask>(); void* next_cmd = @@ -366,6 +523,119 @@ TEST_F(GLES2FormatTest, CompressedTexSubImage2D) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, CompressedTexImage3DBucket) { + cmds::CompressedTexImage3DBucket& cmd = + *GetBufferAs<cmds::CompressedTexImage3DBucket>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), + static_cast<GLint>(12), static_cast<GLenum>(13), + static_cast<GLsizei>(14), static_cast<GLsizei>(15), + static_cast<GLsizei>(16), static_cast<GLuint>(17)); + EXPECT_EQ(static_cast<uint32_t>(cmds::CompressedTexImage3DBucket::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLenum>(13), cmd.internalformat); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.height); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.depth); + EXPECT_EQ(static_cast<GLuint>(17), cmd.bucket_id); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, CompressedTexImage3D) { + cmds::CompressedTexImage3D& cmd = *GetBufferAs<cmds::CompressedTexImage3D>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12), + static_cast<GLenum>(13), static_cast<GLsizei>(14), + static_cast<GLsizei>(15), static_cast<GLsizei>(16), + static_cast<GLsizei>(17), static_cast<uint32_t>(18), + static_cast<uint32_t>(19)); + EXPECT_EQ(static_cast<uint32_t>(cmds::CompressedTexImage3D::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLenum>(13), cmd.internalformat); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.height); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.depth); + EXPECT_EQ(static_cast<GLsizei>(17), cmd.imageSize); + EXPECT_EQ(static_cast<uint32_t>(18), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32_t>(19), cmd.data_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, CompressedTexSubImage3DBucket) { + cmds::CompressedTexSubImage3DBucket& cmd = + *GetBufferAs<cmds::CompressedTexSubImage3DBucket>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12), + static_cast<GLint>(13), static_cast<GLint>(14), + static_cast<GLint>(15), static_cast<GLsizei>(16), + static_cast<GLsizei>(17), static_cast<GLsizei>(18), + static_cast<GLenum>(19), static_cast<GLuint>(20)); + EXPECT_EQ(static_cast<uint32_t>(cmds::CompressedTexSubImage3DBucket::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.xoffset); + EXPECT_EQ(static_cast<GLint>(14), cmd.yoffset); + EXPECT_EQ(static_cast<GLint>(15), cmd.zoffset); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(17), cmd.height); + EXPECT_EQ(static_cast<GLsizei>(18), cmd.depth); + EXPECT_EQ(static_cast<GLenum>(19), cmd.format); + EXPECT_EQ(static_cast<GLuint>(20), cmd.bucket_id); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, CompressedTexSubImage3D) { + cmds::CompressedTexSubImage3D& cmd = + *GetBufferAs<cmds::CompressedTexSubImage3D>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12), + static_cast<GLint>(13), static_cast<GLint>(14), + static_cast<GLint>(15), static_cast<GLsizei>(16), + static_cast<GLsizei>(17), static_cast<GLsizei>(18), + static_cast<GLenum>(19), static_cast<GLsizei>(20), + static_cast<uint32_t>(21), static_cast<uint32_t>(22)); + EXPECT_EQ(static_cast<uint32_t>(cmds::CompressedTexSubImage3D::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.xoffset); + EXPECT_EQ(static_cast<GLint>(14), cmd.yoffset); + EXPECT_EQ(static_cast<GLint>(15), cmd.zoffset); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(17), cmd.height); + EXPECT_EQ(static_cast<GLsizei>(18), cmd.depth); + EXPECT_EQ(static_cast<GLenum>(19), cmd.format); + EXPECT_EQ(static_cast<GLsizei>(20), cmd.imageSize); + EXPECT_EQ(static_cast<uint32_t>(21), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32_t>(22), cmd.data_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, CopyBufferSubData) { + cmds::CopyBufferSubData& cmd = *GetBufferAs<cmds::CopyBufferSubData>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLenum>(12), + static_cast<GLintptr>(13), static_cast<GLintptr>(14), + static_cast<GLsizeiptr>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::CopyBufferSubData::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.readtarget); + EXPECT_EQ(static_cast<GLenum>(12), cmd.writetarget); + EXPECT_EQ(static_cast<GLintptr>(13), cmd.readoffset); + EXPECT_EQ(static_cast<GLintptr>(14), cmd.writeoffset); + EXPECT_EQ(static_cast<GLsizeiptr>(15), cmd.size); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, CopyTexImage2D) { cmds::CopyTexImage2D& cmd = *GetBufferAs<cmds::CopyTexImage2D>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), @@ -406,6 +676,28 @@ TEST_F(GLES2FormatTest, CopyTexSubImage2D) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, CopyTexSubImage3D) { + cmds::CopyTexSubImage3D& cmd = *GetBufferAs<cmds::CopyTexSubImage3D>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), + static_cast<GLint>(12), static_cast<GLint>(13), + static_cast<GLint>(14), static_cast<GLint>(15), + static_cast<GLint>(16), static_cast<GLint>(17), + static_cast<GLsizei>(18), static_cast<GLsizei>(19)); + EXPECT_EQ(static_cast<uint32_t>(cmds::CopyTexSubImage3D::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.xoffset); + EXPECT_EQ(static_cast<GLint>(14), cmd.yoffset); + EXPECT_EQ(static_cast<GLint>(15), cmd.zoffset); + EXPECT_EQ(static_cast<GLint>(16), cmd.x); + EXPECT_EQ(static_cast<GLint>(17), cmd.y); + EXPECT_EQ(static_cast<GLsizei>(18), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(19), cmd.height); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, CreateProgram) { cmds::CreateProgram& cmd = *GetBufferAs<cmds::CreateProgram>(); void* next_cmd = cmd.Set(&cmd, static_cast<uint32_t>(11)); @@ -501,6 +793,34 @@ TEST_F(GLES2FormatTest, DeleteRenderbuffersImmediate) { // TODO(gman): Check that ids were inserted; } +TEST_F(GLES2FormatTest, DeleteSamplersImmediate) { + static GLuint ids[] = { + 12, 23, 34, + }; + cmds::DeleteSamplersImmediate& cmd = + *GetBufferAs<cmds::DeleteSamplersImmediate>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids); + EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteSamplersImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u), + cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, + sizeof(cmd) + RoundSizeToMultipleOfEntries(arraysize(ids) * 4u)); + // TODO(gman): Check that ids were inserted; +} + +TEST_F(GLES2FormatTest, DeleteSync) { + cmds::DeleteSync& cmd = *GetBufferAs<cmds::DeleteSync>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11)); + EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteSync::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sync); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, DeleteShader) { cmds::DeleteShader& cmd = *GetBufferAs<cmds::DeleteShader>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11)); @@ -529,6 +849,25 @@ TEST_F(GLES2FormatTest, DeleteTexturesImmediate) { // TODO(gman): Check that ids were inserted; } +TEST_F(GLES2FormatTest, DeleteTransformFeedbacksImmediate) { + static GLuint ids[] = { + 12, 23, 34, + }; + cmds::DeleteTransformFeedbacksImmediate& cmd = + *GetBufferAs<cmds::DeleteTransformFeedbacksImmediate>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids); + EXPECT_EQ( + static_cast<uint32_t>(cmds::DeleteTransformFeedbacksImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u), + cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, + sizeof(cmd) + RoundSizeToMultipleOfEntries(arraysize(ids) * 4u)); + // TODO(gman): Check that ids were inserted; +} + TEST_F(GLES2FormatTest, DepthFunc) { cmds::DepthFunc& cmd = *GetBufferAs<cmds::DepthFunc>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11)); @@ -639,6 +978,15 @@ TEST_F(GLES2FormatTest, EnableVertexAttribArray) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, FenceSync) { + cmds::FenceSync& cmd = *GetBufferAs<cmds::FenceSync>(); + void* next_cmd = cmd.Set(&cmd, static_cast<uint32_t>(11)); + EXPECT_EQ(static_cast<uint32_t>(cmds::FenceSync::kCmdId), cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<uint32_t>(11), cmd.client_id); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, Finish) { cmds::Finish& cmd = *GetBufferAs<cmds::Finish>(); void* next_cmd = cmd.Set(&cmd); @@ -686,6 +1034,23 @@ TEST_F(GLES2FormatTest, FramebufferTexture2D) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, FramebufferTextureLayer) { + cmds::FramebufferTextureLayer& cmd = + *GetBufferAs<cmds::FramebufferTextureLayer>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), + static_cast<GLenum>(12), static_cast<GLuint>(13), + static_cast<GLint>(14), static_cast<GLint>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::FramebufferTextureLayer::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.attachment); + EXPECT_EQ(static_cast<GLuint>(13), cmd.texture); + EXPECT_EQ(static_cast<GLint>(14), cmd.level); + EXPECT_EQ(static_cast<GLint>(15), cmd.layer); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, FrontFace) { cmds::FrontFace& cmd = *GetBufferAs<cmds::FrontFace>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11)); @@ -758,6 +1123,23 @@ TEST_F(GLES2FormatTest, GenRenderbuffersImmediate) { // TODO(gman): Check that ids were inserted; } +TEST_F(GLES2FormatTest, GenSamplersImmediate) { + static GLuint ids[] = { + 12, 23, 34, + }; + cmds::GenSamplersImmediate& cmd = *GetBufferAs<cmds::GenSamplersImmediate>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids); + EXPECT_EQ(static_cast<uint32_t>(cmds::GenSamplersImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u), + cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, + sizeof(cmd) + RoundSizeToMultipleOfEntries(arraysize(ids) * 4u)); + // TODO(gman): Check that ids were inserted; +} + TEST_F(GLES2FormatTest, GenTexturesImmediate) { static GLuint ids[] = { 12, 23, 34, @@ -775,6 +1157,24 @@ TEST_F(GLES2FormatTest, GenTexturesImmediate) { // TODO(gman): Check that ids were inserted; } +TEST_F(GLES2FormatTest, GenTransformFeedbacksImmediate) { + static GLuint ids[] = { + 12, 23, 34, + }; + cmds::GenTransformFeedbacksImmediate& cmd = + *GetBufferAs<cmds::GenTransformFeedbacksImmediate>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids); + EXPECT_EQ(static_cast<uint32_t>(cmds::GenTransformFeedbacksImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u), + cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, + sizeof(cmd) + RoundSizeToMultipleOfEntries(arraysize(ids) * 4u)); + // TODO(gman): Check that ids were inserted; +} + TEST_F(GLES2FormatTest, GetActiveAttrib) { cmds::GetActiveAttrib& cmd = *GetBufferAs<cmds::GetActiveAttrib>(); void* next_cmd = @@ -809,6 +1209,59 @@ TEST_F(GLES2FormatTest, GetActiveUniform) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetActiveUniformBlockiv) { + cmds::GetActiveUniformBlockiv& cmd = + *GetBufferAs<cmds::GetActiveUniformBlockiv>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), + static_cast<GLenum>(13), static_cast<uint32_t>(14), + static_cast<uint32_t>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetActiveUniformBlockiv::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<GLenum>(13), cmd.pname); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32_t>(15), cmd.params_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetActiveUniformBlockName) { + cmds::GetActiveUniformBlockName& cmd = + *GetBufferAs<cmds::GetActiveUniformBlockName>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14), + static_cast<uint32_t>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetActiveUniformBlockName::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.name_bucket_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32_t>(15), cmd.result_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetActiveUniformsiv) { + cmds::GetActiveUniformsiv& cmd = *GetBufferAs<cmds::GetActiveUniformsiv>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12), + static_cast<GLenum>(13), static_cast<uint32_t>(14), + static_cast<uint32_t>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetActiveUniformsiv::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.indices_bucket_id); + EXPECT_EQ(static_cast<GLenum>(13), cmd.pname); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32_t>(15), cmd.params_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetAttachedShaders) { cmds::GetAttachedShaders& cmd = *GetBufferAs<cmds::GetAttachedShaders>(); void* next_cmd = @@ -892,6 +1345,21 @@ TEST_F(GLES2FormatTest, GetFloatv) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetFragDataLocation) { + cmds::GetFragDataLocation& cmd = *GetBufferAs<cmds::GetFragDataLocation>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetFragDataLocation::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.name_bucket_id); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.location_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.location_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetFramebufferAttachmentParameteriv) { cmds::GetFramebufferAttachmentParameteriv& cmd = *GetBufferAs<cmds::GetFramebufferAttachmentParameteriv>(); @@ -911,6 +1379,50 @@ TEST_F(GLES2FormatTest, GetFramebufferAttachmentParameteriv) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetInteger64v) { + cmds::GetInteger64v& cmd = *GetBufferAs<cmds::GetInteger64v>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetInteger64v::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.pname); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetIntegeri_v) { + cmds::GetIntegeri_v& cmd = *GetBufferAs<cmds::GetIntegeri_v>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLuint>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetIntegeri_v::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.pname); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.data_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetInteger64i_v) { + cmds::GetInteger64i_v& cmd = *GetBufferAs<cmds::GetInteger64i_v>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLuint>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetInteger64i_v::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.pname); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.data_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetIntegerv) { cmds::GetIntegerv& cmd = *GetBufferAs<cmds::GetIntegerv>(); void* next_cmd = @@ -925,6 +1437,24 @@ TEST_F(GLES2FormatTest, GetIntegerv) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetInternalformativ) { + cmds::GetInternalformativ& cmd = *GetBufferAs<cmds::GetInternalformativ>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLenum>(12), + static_cast<GLenum>(13), static_cast<GLsizei>(14), + static_cast<uint32_t>(15), static_cast<uint32_t>(16)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetInternalformativ::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.format); + EXPECT_EQ(static_cast<GLenum>(13), cmd.pname); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.bufSize); + EXPECT_EQ(static_cast<uint32_t>(15), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32_t>(16), cmd.params_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetProgramiv) { cmds::GetProgramiv& cmd = *GetBufferAs<cmds::GetProgramiv>(); void* next_cmd = @@ -968,6 +1498,38 @@ TEST_F(GLES2FormatTest, GetRenderbufferParameteriv) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetSamplerParameterfv) { + cmds::GetSamplerParameterfv& cmd = + *GetBufferAs<cmds::GetSamplerParameterfv>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetSamplerParameterfv::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetSamplerParameteriv) { + cmds::GetSamplerParameteriv& cmd = + *GetBufferAs<cmds::GetSamplerParameteriv>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetSamplerParameteriv::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetShaderiv) { cmds::GetShaderiv& cmd = *GetBufferAs<cmds::GetShaderiv>(); void* next_cmd = @@ -1034,6 +1596,20 @@ TEST_F(GLES2FormatTest, GetString) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetSynciv) { + cmds::GetSynciv& cmd = *GetBufferAs<cmds::GetSynciv>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetSynciv::kCmdId), cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sync); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.values_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.values_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetTexParameterfv) { cmds::GetTexParameterfv& cmd = *GetBufferAs<cmds::GetTexParameterfv>(); void* next_cmd = @@ -1064,6 +1640,39 @@ TEST_F(GLES2FormatTest, GetTexParameteriv) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetTransformFeedbackVarying) { + cmds::GetTransformFeedbackVarying& cmd = + *GetBufferAs<cmds::GetTransformFeedbackVarying>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14), + static_cast<uint32_t>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetTransformFeedbackVarying::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.name_bucket_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32_t>(15), cmd.result_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetUniformBlockIndex) { + cmds::GetUniformBlockIndex& cmd = *GetBufferAs<cmds::GetUniformBlockIndex>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetUniformBlockIndex::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.name_bucket_id); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.index_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.index_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetUniformfv) { cmds::GetUniformfv& cmd = *GetBufferAs<cmds::GetUniformfv>(); void* next_cmd = @@ -1094,6 +1703,36 @@ TEST_F(GLES2FormatTest, GetUniformiv) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetUniformuiv) { + cmds::GetUniformuiv& cmd = *GetBufferAs<cmds::GetUniformuiv>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLint>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetUniformuiv::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLint>(12), cmd.location); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetUniformIndices) { + cmds::GetUniformIndices& cmd = *GetBufferAs<cmds::GetUniformIndices>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetUniformIndices::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.names_bucket_id); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.indices_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.indices_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetUniformLocation) { cmds::GetUniformLocation& cmd = *GetBufferAs<cmds::GetUniformLocation>(); void* next_cmd = @@ -1139,6 +1778,36 @@ TEST_F(GLES2FormatTest, GetVertexAttribiv) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GetVertexAttribIiv) { + cmds::GetVertexAttribIiv& cmd = *GetBufferAs<cmds::GetVertexAttribIiv>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetVertexAttribIiv::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.index); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetVertexAttribIuiv) { + cmds::GetVertexAttribIuiv& cmd = *GetBufferAs<cmds::GetVertexAttribIuiv>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetVertexAttribIuiv::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.index); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetVertexAttribPointerv) { cmds::GetVertexAttribPointerv& cmd = *GetBufferAs<cmds::GetVertexAttribPointerv>(); @@ -1166,6 +1835,59 @@ TEST_F(GLES2FormatTest, Hint) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, InvalidateFramebufferImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLenum data[] = { + static_cast<GLenum>(kSomeBaseValueToTestWith + 0), + static_cast<GLenum>(kSomeBaseValueToTestWith + 1), + }; + cmds::InvalidateFramebufferImmediate& cmd = + *GetBufferAs<cmds::InvalidateFramebufferImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLenum) * 1; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(1), static_cast<GLsizei>(2), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::InvalidateFramebufferImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(1), cmd.target); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + +TEST_F(GLES2FormatTest, InvalidateSubFramebufferImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLenum data[] = { + static_cast<GLenum>(kSomeBaseValueToTestWith + 0), + static_cast<GLenum>(kSomeBaseValueToTestWith + 1), + }; + cmds::InvalidateSubFramebufferImmediate& cmd = + *GetBufferAs<cmds::InvalidateSubFramebufferImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLenum) * 1; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(1), static_cast<GLsizei>(2), data, + static_cast<GLint>(4), static_cast<GLint>(5), + static_cast<GLsizei>(6), static_cast<GLsizei>(7)); + EXPECT_EQ( + static_cast<uint32_t>(cmds::InvalidateSubFramebufferImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(1), cmd.target); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + EXPECT_EQ(static_cast<GLint>(4), cmd.x); + EXPECT_EQ(static_cast<GLint>(5), cmd.y); + EXPECT_EQ(static_cast<GLsizei>(6), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(7), cmd.height); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + TEST_F(GLES2FormatTest, IsBuffer) { cmds::IsBuffer& cmd = *GetBufferAs<cmds::IsBuffer>(); void* next_cmd = @@ -1233,6 +1955,19 @@ TEST_F(GLES2FormatTest, IsRenderbuffer) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, IsSampler) { + cmds::IsSampler& cmd = *GetBufferAs<cmds::IsSampler>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::IsSampler::kCmdId), cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, IsShader) { cmds::IsShader& cmd = *GetBufferAs<cmds::IsShader>(); void* next_cmd = @@ -1246,6 +1981,19 @@ TEST_F(GLES2FormatTest, IsShader) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, IsSync) { + cmds::IsSync& cmd = *GetBufferAs<cmds::IsSync>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::IsSync::kCmdId), cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sync); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, IsTexture) { cmds::IsTexture& cmd = *GetBufferAs<cmds::IsTexture>(); void* next_cmd = @@ -1259,6 +2007,20 @@ TEST_F(GLES2FormatTest, IsTexture) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, IsTransformFeedback) { + cmds::IsTransformFeedback& cmd = *GetBufferAs<cmds::IsTransformFeedback>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::IsTransformFeedback::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.transformfeedback); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, LineWidth) { cmds::LineWidth& cmd = *GetBufferAs<cmds::LineWidth>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLfloat>(11)); @@ -1278,6 +2040,16 @@ TEST_F(GLES2FormatTest, LinkProgram) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, PauseTransformFeedback) { + cmds::PauseTransformFeedback& cmd = + *GetBufferAs<cmds::PauseTransformFeedback>(); + void* next_cmd = cmd.Set(&cmd); + EXPECT_EQ(static_cast<uint32_t>(cmds::PauseTransformFeedback::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, PixelStorei) { cmds::PixelStorei& cmd = *GetBufferAs<cmds::PixelStorei>(); void* next_cmd = @@ -1302,6 +2074,16 @@ TEST_F(GLES2FormatTest, PolygonOffset) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, ReadBuffer) { + cmds::ReadBuffer& cmd = *GetBufferAs<cmds::ReadBuffer>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11)); + EXPECT_EQ(static_cast<uint32_t>(cmds::ReadBuffer::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.src); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, ReadPixels) { cmds::ReadPixels& cmd = *GetBufferAs<cmds::ReadPixels>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLint>(11), static_cast<GLint>(12), @@ -1352,6 +2134,16 @@ TEST_F(GLES2FormatTest, RenderbufferStorage) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, ResumeTransformFeedback) { + cmds::ResumeTransformFeedback& cmd = + *GetBufferAs<cmds::ResumeTransformFeedback>(); + void* next_cmd = cmd.Set(&cmd); + EXPECT_EQ(static_cast<uint32_t>(cmds::ResumeTransformFeedback::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, SampleCoverage) { cmds::SampleCoverage& cmd = *GetBufferAs<cmds::SampleCoverage>(); void* next_cmd = @@ -1364,6 +2156,72 @@ TEST_F(GLES2FormatTest, SampleCoverage) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, SamplerParameterf) { + cmds::SamplerParameterf& cmd = *GetBufferAs<cmds::SamplerParameterf>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLenum>(12), static_cast<GLfloat>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::SamplerParameterf::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<GLfloat>(13), cmd.param); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, SamplerParameterfvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + }; + cmds::SamplerParameterfvImmediate& cmd = + *GetBufferAs<cmds::SamplerParameterfvImmediate>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::SamplerParameterfvImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + +TEST_F(GLES2FormatTest, SamplerParameteri) { + cmds::SamplerParameteri& cmd = *GetBufferAs<cmds::SamplerParameteri>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLenum>(12), static_cast<GLint>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::SamplerParameteri::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<GLint>(13), cmd.param); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, SamplerParameterivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLint data[] = { + static_cast<GLint>(kSomeBaseValueToTestWith + 0), + }; + cmds::SamplerParameterivImmediate& cmd = + *GetBufferAs<cmds::SamplerParameterivImmediate>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::SamplerParameterivImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + TEST_F(GLES2FormatTest, Scissor) { cmds::Scissor& cmd = *GetBufferAs<cmds::Scissor>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLint>(11), static_cast<GLint>(12), @@ -1404,7 +2262,7 @@ TEST_F(GLES2FormatTest, ShaderSourceBucket) { cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); EXPECT_EQ(static_cast<GLuint>(11), cmd.shader); - EXPECT_EQ(static_cast<uint32_t>(12), cmd.data_bucket_id); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.str_bucket_id); CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } @@ -1508,6 +2366,30 @@ TEST_F(GLES2FormatTest, TexImage2D) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, TexImage3D) { + cmds::TexImage3D& cmd = *GetBufferAs<cmds::TexImage3D>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12), + static_cast<GLint>(13), static_cast<GLsizei>(14), + static_cast<GLsizei>(15), static_cast<GLsizei>(16), + static_cast<GLenum>(17), static_cast<GLenum>(18), + static_cast<uint32_t>(19), static_cast<uint32_t>(20)); + EXPECT_EQ(static_cast<uint32_t>(cmds::TexImage3D::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.internalformat); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.height); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.depth); + EXPECT_EQ(static_cast<GLenum>(17), cmd.format); + EXPECT_EQ(static_cast<GLenum>(18), cmd.type); + EXPECT_EQ(static_cast<uint32_t>(19), cmd.pixels_shm_id); + EXPECT_EQ(static_cast<uint32_t>(20), cmd.pixels_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, TexParameterf) { cmds::TexParameterf& cmd = *GetBufferAs<cmds::TexParameterf>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), @@ -1574,6 +2456,24 @@ TEST_F(GLES2FormatTest, TexParameterivImmediate) { // TODO(gman): Check that data was inserted; } +TEST_F(GLES2FormatTest, TexStorage3D) { + cmds::TexStorage3D& cmd = *GetBufferAs<cmds::TexStorage3D>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLsizei>(12), + static_cast<GLenum>(13), static_cast<GLsizei>(14), + static_cast<GLsizei>(15), static_cast<GLsizei>(16)); + EXPECT_EQ(static_cast<uint32_t>(cmds::TexStorage3D::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.levels); + EXPECT_EQ(static_cast<GLenum>(13), cmd.internalFormat); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.height); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.depth); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, TexSubImage2D) { cmds::TexSubImage2D& cmd = *GetBufferAs<cmds::TexSubImage2D>(); void* next_cmd = cmd.Set( @@ -1599,6 +2499,49 @@ TEST_F(GLES2FormatTest, TexSubImage2D) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, TexSubImage3D) { + cmds::TexSubImage3D& cmd = *GetBufferAs<cmds::TexSubImage3D>(); + void* next_cmd = cmd.Set( + &cmd, static_cast<GLenum>(11), static_cast<GLint>(12), + static_cast<GLint>(13), static_cast<GLint>(14), static_cast<GLint>(15), + static_cast<GLsizei>(16), static_cast<GLsizei>(17), + static_cast<GLsizei>(18), static_cast<GLenum>(19), + static_cast<GLenum>(20), static_cast<uint32_t>(21), + static_cast<uint32_t>(22), static_cast<GLboolean>(23)); + EXPECT_EQ(static_cast<uint32_t>(cmds::TexSubImage3D::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.xoffset); + EXPECT_EQ(static_cast<GLint>(14), cmd.yoffset); + EXPECT_EQ(static_cast<GLint>(15), cmd.zoffset); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(17), cmd.height); + EXPECT_EQ(static_cast<GLsizei>(18), cmd.depth); + EXPECT_EQ(static_cast<GLenum>(19), cmd.format); + EXPECT_EQ(static_cast<GLenum>(20), cmd.type); + EXPECT_EQ(static_cast<uint32_t>(21), cmd.pixels_shm_id); + EXPECT_EQ(static_cast<uint32_t>(22), cmd.pixels_shm_offset); + EXPECT_EQ(static_cast<GLboolean>(23), cmd.internal); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, TransformFeedbackVaryingsBucket) { + cmds::TransformFeedbackVaryingsBucket& cmd = + *GetBufferAs<cmds::TransformFeedbackVaryingsBucket>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<uint32_t>(12), static_cast<GLenum>(13)); + EXPECT_EQ( + static_cast<uint32_t>(cmds::TransformFeedbackVaryingsBucket::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.varyings_bucket_id); + EXPECT_EQ(static_cast<GLenum>(13), cmd.buffermode); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, Uniform1f) { cmds::Uniform1f& cmd = *GetBufferAs<cmds::Uniform1f>(); void* next_cmd = @@ -1665,6 +2608,40 @@ TEST_F(GLES2FormatTest, Uniform1ivImmediate) { // TODO(gman): Check that data was inserted; } +TEST_F(GLES2FormatTest, Uniform1ui) { + cmds::Uniform1ui& cmd = *GetBufferAs<cmds::Uniform1ui>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(11), static_cast<GLuint>(12)); + EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform1ui::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLuint>(12), cmd.x); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, Uniform1uivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLuint data[] = { + static_cast<GLuint>(kSomeBaseValueToTestWith + 0), + static_cast<GLuint>(kSomeBaseValueToTestWith + 1), + }; + cmds::Uniform1uivImmediate& cmd = *GetBufferAs<cmds::Uniform1uivImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLuint) * 1; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform1uivImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + TEST_F(GLES2FormatTest, Uniform2f) { cmds::Uniform2f& cmd = *GetBufferAs<cmds::Uniform2f>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLint>(11), @@ -1737,6 +2714,43 @@ TEST_F(GLES2FormatTest, Uniform2ivImmediate) { // TODO(gman): Check that data was inserted; } +TEST_F(GLES2FormatTest, Uniform2ui) { + cmds::Uniform2ui& cmd = *GetBufferAs<cmds::Uniform2ui>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLint>(11), + static_cast<GLuint>(12), static_cast<GLuint>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform2ui::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLuint>(12), cmd.x); + EXPECT_EQ(static_cast<GLuint>(13), cmd.y); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, Uniform2uivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLuint data[] = { + static_cast<GLuint>(kSomeBaseValueToTestWith + 0), + static_cast<GLuint>(kSomeBaseValueToTestWith + 1), + static_cast<GLuint>(kSomeBaseValueToTestWith + 2), + static_cast<GLuint>(kSomeBaseValueToTestWith + 3), + }; + cmds::Uniform2uivImmediate& cmd = *GetBufferAs<cmds::Uniform2uivImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLuint) * 2; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform2uivImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + TEST_F(GLES2FormatTest, Uniform3f) { cmds::Uniform3f& cmd = *GetBufferAs<cmds::Uniform3f>(); void* next_cmd = @@ -1816,6 +2830,47 @@ TEST_F(GLES2FormatTest, Uniform3ivImmediate) { // TODO(gman): Check that data was inserted; } +TEST_F(GLES2FormatTest, Uniform3ui) { + cmds::Uniform3ui& cmd = *GetBufferAs<cmds::Uniform3ui>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(11), static_cast<GLuint>(12), + static_cast<GLuint>(13), static_cast<GLuint>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform3ui::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLuint>(12), cmd.x); + EXPECT_EQ(static_cast<GLuint>(13), cmd.y); + EXPECT_EQ(static_cast<GLuint>(14), cmd.z); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, Uniform3uivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLuint data[] = { + static_cast<GLuint>(kSomeBaseValueToTestWith + 0), + static_cast<GLuint>(kSomeBaseValueToTestWith + 1), + static_cast<GLuint>(kSomeBaseValueToTestWith + 2), + static_cast<GLuint>(kSomeBaseValueToTestWith + 3), + static_cast<GLuint>(kSomeBaseValueToTestWith + 4), + static_cast<GLuint>(kSomeBaseValueToTestWith + 5), + }; + cmds::Uniform3uivImmediate& cmd = *GetBufferAs<cmds::Uniform3uivImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLuint) * 3; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform3uivImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + TEST_F(GLES2FormatTest, Uniform4f) { cmds::Uniform4f& cmd = *GetBufferAs<cmds::Uniform4f>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLint>(11), @@ -1902,6 +2957,63 @@ TEST_F(GLES2FormatTest, Uniform4ivImmediate) { // TODO(gman): Check that data was inserted; } +TEST_F(GLES2FormatTest, Uniform4ui) { + cmds::Uniform4ui& cmd = *GetBufferAs<cmds::Uniform4ui>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLint>(11), + static_cast<GLuint>(12), static_cast<GLuint>(13), + static_cast<GLuint>(14), static_cast<GLuint>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform4ui::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLuint>(12), cmd.x); + EXPECT_EQ(static_cast<GLuint>(13), cmd.y); + EXPECT_EQ(static_cast<GLuint>(14), cmd.z); + EXPECT_EQ(static_cast<GLuint>(15), cmd.w); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, Uniform4uivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLuint data[] = { + static_cast<GLuint>(kSomeBaseValueToTestWith + 0), + static_cast<GLuint>(kSomeBaseValueToTestWith + 1), + static_cast<GLuint>(kSomeBaseValueToTestWith + 2), + static_cast<GLuint>(kSomeBaseValueToTestWith + 3), + static_cast<GLuint>(kSomeBaseValueToTestWith + 4), + static_cast<GLuint>(kSomeBaseValueToTestWith + 5), + static_cast<GLuint>(kSomeBaseValueToTestWith + 6), + static_cast<GLuint>(kSomeBaseValueToTestWith + 7), + }; + cmds::Uniform4uivImmediate& cmd = *GetBufferAs<cmds::Uniform4uivImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLuint) * 4; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform4uivImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + +TEST_F(GLES2FormatTest, UniformBlockBinding) { + cmds::UniformBlockBinding& cmd = *GetBufferAs<cmds::UniformBlockBinding>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLuint>(12), static_cast<GLuint>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::UniformBlockBinding::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<GLuint>(13), cmd.binding); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, UniformMatrix2fvImmediate) { const int kSomeBaseValueToTestWith = 51; static GLfloat data[] = { @@ -1931,6 +3043,76 @@ TEST_F(GLES2FormatTest, UniformMatrix2fvImmediate) { // TODO(gman): Check that data was inserted; } +TEST_F(GLES2FormatTest, UniformMatrix2x3fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 4), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 5), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 6), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 7), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 8), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 9), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 10), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 11), + }; + cmds::UniformMatrix2x3fvImmediate& cmd = + *GetBufferAs<cmds::UniformMatrix2x3fvImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLfloat) * 6; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix2x3fvImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + +TEST_F(GLES2FormatTest, UniformMatrix2x4fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 4), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 5), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 6), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 7), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 8), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 9), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 10), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 11), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 12), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 13), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 14), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 15), + }; + cmds::UniformMatrix2x4fvImmediate& cmd = + *GetBufferAs<cmds::UniformMatrix2x4fvImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLfloat) * 8; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix2x4fvImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + TEST_F(GLES2FormatTest, UniformMatrix3fvImmediate) { const int kSomeBaseValueToTestWith = 51; static GLfloat data[] = { @@ -1970,6 +3152,84 @@ TEST_F(GLES2FormatTest, UniformMatrix3fvImmediate) { // TODO(gman): Check that data was inserted; } +TEST_F(GLES2FormatTest, UniformMatrix3x2fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 4), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 5), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 6), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 7), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 8), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 9), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 10), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 11), + }; + cmds::UniformMatrix3x2fvImmediate& cmd = + *GetBufferAs<cmds::UniformMatrix3x2fvImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLfloat) * 6; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix3x2fvImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + +TEST_F(GLES2FormatTest, UniformMatrix3x4fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 4), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 5), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 6), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 7), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 8), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 9), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 10), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 11), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 12), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 13), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 14), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 15), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 16), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 17), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 18), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 19), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 20), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 21), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 22), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 23), + }; + cmds::UniformMatrix3x4fvImmediate& cmd = + *GetBufferAs<cmds::UniformMatrix3x4fvImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLfloat) * 12; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix3x4fvImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + TEST_F(GLES2FormatTest, UniformMatrix4fvImmediate) { const int kSomeBaseValueToTestWith = 51; static GLfloat data[] = { @@ -2023,6 +3283,88 @@ TEST_F(GLES2FormatTest, UniformMatrix4fvImmediate) { // TODO(gman): Check that data was inserted; } +TEST_F(GLES2FormatTest, UniformMatrix4x2fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 4), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 5), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 6), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 7), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 8), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 9), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 10), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 11), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 12), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 13), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 14), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 15), + }; + cmds::UniformMatrix4x2fvImmediate& cmd = + *GetBufferAs<cmds::UniformMatrix4x2fvImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLfloat) * 8; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix4x2fvImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + +TEST_F(GLES2FormatTest, UniformMatrix4x3fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 4), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 5), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 6), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 7), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 8), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 9), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 10), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 11), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 12), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 13), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 14), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 15), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 16), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 17), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 18), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 19), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 20), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 21), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 22), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 23), + }; + cmds::UniformMatrix4x3fvImmediate& cmd = + *GetBufferAs<cmds::UniformMatrix4x3fvImmediate>(); + const GLsizei kNumElements = 2; + const size_t kExpectedCmdSize = + sizeof(cmd) + kNumElements * sizeof(GLfloat) * 12; + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix4x3fvImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + TEST_F(GLES2FormatTest, UseProgram) { cmds::UseProgram& cmd = *GetBufferAs<cmds::UseProgram>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11)); @@ -2177,6 +3519,96 @@ TEST_F(GLES2FormatTest, VertexAttrib4fvImmediate) { // TODO(gman): Check that data was inserted; } +TEST_F(GLES2FormatTest, VertexAttribI4i) { + cmds::VertexAttribI4i& cmd = *GetBufferAs<cmds::VertexAttribI4i>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLint>(12), static_cast<GLint>(13), + static_cast<GLint>(14), static_cast<GLint>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttribI4i::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<GLint>(12), cmd.x); + EXPECT_EQ(static_cast<GLint>(13), cmd.y); + EXPECT_EQ(static_cast<GLint>(14), cmd.z); + EXPECT_EQ(static_cast<GLint>(15), cmd.w); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, VertexAttribI4ivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLint data[] = { + static_cast<GLint>(kSomeBaseValueToTestWith + 0), + static_cast<GLint>(kSomeBaseValueToTestWith + 1), + static_cast<GLint>(kSomeBaseValueToTestWith + 2), + static_cast<GLint>(kSomeBaseValueToTestWith + 3), + }; + cmds::VertexAttribI4ivImmediate& cmd = + *GetBufferAs<cmds::VertexAttribI4ivImmediate>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttribI4ivImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + +TEST_F(GLES2FormatTest, VertexAttribI4ui) { + cmds::VertexAttribI4ui& cmd = *GetBufferAs<cmds::VertexAttribI4ui>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLuint>(12), static_cast<GLuint>(13), + static_cast<GLuint>(14), static_cast<GLuint>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttribI4ui::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<GLuint>(12), cmd.x); + EXPECT_EQ(static_cast<GLuint>(13), cmd.y); + EXPECT_EQ(static_cast<GLuint>(14), cmd.z); + EXPECT_EQ(static_cast<GLuint>(15), cmd.w); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, VertexAttribI4uivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLuint data[] = { + static_cast<GLuint>(kSomeBaseValueToTestWith + 0), + static_cast<GLuint>(kSomeBaseValueToTestWith + 1), + static_cast<GLuint>(kSomeBaseValueToTestWith + 2), + static_cast<GLuint>(kSomeBaseValueToTestWith + 3), + }; + cmds::VertexAttribI4uivImmediate& cmd = + *GetBufferAs<cmds::VertexAttribI4uivImmediate>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), data); + EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttribI4uivImmediate::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data))); + // TODO(gman): Check that data was inserted; +} + +TEST_F(GLES2FormatTest, VertexAttribIPointer) { + cmds::VertexAttribIPointer& cmd = *GetBufferAs<cmds::VertexAttribIPointer>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLint>(12), static_cast<GLenum>(13), + static_cast<GLsizei>(14), static_cast<GLuint>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttribIPointer::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<GLint>(12), cmd.size); + EXPECT_EQ(static_cast<GLenum>(13), cmd.type); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.stride); + EXPECT_EQ(static_cast<GLuint>(15), cmd.offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, VertexAttribPointer) { cmds::VertexAttribPointer& cmd = *GetBufferAs<cmds::VertexAttribPointer>(); void* next_cmd = @@ -2208,6 +3640,20 @@ TEST_F(GLES2FormatTest, Viewport) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, WaitSync) { + cmds::WaitSync& cmd = *GetBufferAs<cmds::WaitSync>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLbitfield>(12), + static_cast<GLuint>(13), static_cast<GLuint>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::WaitSync::kCmdId), cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.sync); + EXPECT_EQ(static_cast<GLbitfield>(12), cmd.flags); + EXPECT_EQ(static_cast<GLuint>(13), cmd.timeout_0); + EXPECT_EQ(static_cast<GLuint>(14), cmd.timeout_1); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, BlitFramebufferCHROMIUM) { cmds::BlitFramebufferCHROMIUM& cmd = *GetBufferAs<cmds::BlitFramebufferCHROMIUM>(); @@ -2353,6 +3799,17 @@ TEST_F(GLES2FormatTest, BeginQueryEXT) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, BeginTransformFeedback) { + cmds::BeginTransformFeedback& cmd = + *GetBufferAs<cmds::BeginTransformFeedback>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11)); + EXPECT_EQ(static_cast<uint32_t>(cmds::BeginTransformFeedback::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.primitivemode); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, EndQueryEXT) { cmds::EndQueryEXT& cmd = *GetBufferAs<cmds::EndQueryEXT>(); void* next_cmd = @@ -2365,6 +3822,15 @@ TEST_F(GLES2FormatTest, EndQueryEXT) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, EndTransformFeedback) { + cmds::EndTransformFeedback& cmd = *GetBufferAs<cmds::EndTransformFeedback>(); + void* next_cmd = cmd.Set(&cmd); + EXPECT_EQ(static_cast<uint32_t>(cmds::EndTransformFeedback::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, InsertEventMarkerEXT) { cmds::InsertEventMarkerEXT& cmd = *GetBufferAs<cmds::InsertEventMarkerEXT>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11)); @@ -2497,6 +3963,37 @@ TEST_F(GLES2FormatTest, EnableFeatureCHROMIUM) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, MapBufferRange) { + cmds::MapBufferRange& cmd = *GetBufferAs<cmds::MapBufferRange>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLintptr>(12), + static_cast<GLsizeiptr>(13), static_cast<GLbitfield>(14), + static_cast<uint32_t>(15), static_cast<uint32_t>(16), + static_cast<uint32_t>(17), static_cast<uint32_t>(18)); + EXPECT_EQ(static_cast<uint32_t>(cmds::MapBufferRange::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLintptr>(12), cmd.offset); + EXPECT_EQ(static_cast<GLsizeiptr>(13), cmd.size); + EXPECT_EQ(static_cast<GLbitfield>(14), cmd.access); + EXPECT_EQ(static_cast<uint32_t>(15), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32_t>(16), cmd.data_shm_offset); + EXPECT_EQ(static_cast<uint32_t>(17), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32_t>(18), cmd.result_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, UnmapBuffer) { + cmds::UnmapBuffer& cmd = *GetBufferAs<cmds::UnmapBuffer>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11)); + EXPECT_EQ(static_cast<uint32_t>(cmds::UnmapBuffer::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, ResizeCHROMIUM) { cmds::ResizeCHROMIUM& cmd = *GetBufferAs<cmds::ResizeCHROMIUM>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), @@ -2533,31 +4030,52 @@ TEST_F(GLES2FormatTest, RequestExtensionCHROMIUM) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } -TEST_F(GLES2FormatTest, GetMultipleIntegervCHROMIUM) { - cmds::GetMultipleIntegervCHROMIUM& cmd = - *GetBufferAs<cmds::GetMultipleIntegervCHROMIUM>(); +TEST_F(GLES2FormatTest, GetProgramInfoCHROMIUM) { + cmds::GetProgramInfoCHROMIUM& cmd = + *GetBufferAs<cmds::GetProgramInfoCHROMIUM>(); void* next_cmd = - cmd.Set(&cmd, static_cast<uint32_t>(11), static_cast<uint32_t>(12), - static_cast<GLuint>(13), static_cast<uint32_t>(14), - static_cast<uint32_t>(15), static_cast<GLsizeiptr>(16)); - EXPECT_EQ(static_cast<uint32_t>(cmds::GetMultipleIntegervCHROMIUM::kCmdId), + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetProgramInfoCHROMIUM::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<uint32_t>(11), cmd.pnames_shm_id); - EXPECT_EQ(static_cast<uint32_t>(12), cmd.pnames_shm_offset); - EXPECT_EQ(static_cast<GLuint>(13), cmd.count); - EXPECT_EQ(static_cast<uint32_t>(14), cmd.results_shm_id); - EXPECT_EQ(static_cast<uint32_t>(15), cmd.results_shm_offset); - EXPECT_EQ(static_cast<GLsizeiptr>(16), cmd.size); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.bucket_id); CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } -TEST_F(GLES2FormatTest, GetProgramInfoCHROMIUM) { - cmds::GetProgramInfoCHROMIUM& cmd = - *GetBufferAs<cmds::GetProgramInfoCHROMIUM>(); +TEST_F(GLES2FormatTest, GetUniformBlocksCHROMIUM) { + cmds::GetUniformBlocksCHROMIUM& cmd = + *GetBufferAs<cmds::GetUniformBlocksCHROMIUM>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12)); - EXPECT_EQ(static_cast<uint32_t>(cmds::GetProgramInfoCHROMIUM::kCmdId), + EXPECT_EQ(static_cast<uint32_t>(cmds::GetUniformBlocksCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.bucket_id); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetTransformFeedbackVaryingsCHROMIUM) { + cmds::GetTransformFeedbackVaryingsCHROMIUM& cmd = + *GetBufferAs<cmds::GetTransformFeedbackVaryingsCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12)); + EXPECT_EQ( + static_cast<uint32_t>(cmds::GetTransformFeedbackVaryingsCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.bucket_id); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetUniformsES3CHROMIUM) { + cmds::GetUniformsES3CHROMIUM& cmd = + *GetBufferAs<cmds::GetUniformsES3CHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetUniformsES3CHROMIUM::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); EXPECT_EQ(static_cast<GLuint>(11), cmd.program); @@ -2612,19 +4130,34 @@ TEST_F(GLES2FormatTest, TexImageIOSurface2DCHROMIUM) { TEST_F(GLES2FormatTest, CopyTextureCHROMIUM) { cmds::CopyTextureCHROMIUM& cmd = *GetBufferAs<cmds::CopyTextureCHROMIUM>(); - void* next_cmd = - cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLenum>(12), - static_cast<GLenum>(13), static_cast<GLint>(14), - static_cast<GLint>(15), static_cast<GLenum>(16)); + void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), + static_cast<GLenum>(12), static_cast<GLenum>(13), + static_cast<GLint>(14), static_cast<GLenum>(15)); EXPECT_EQ(static_cast<uint32_t>(cmds::CopyTextureCHROMIUM::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); EXPECT_EQ(static_cast<GLenum>(11), cmd.target); EXPECT_EQ(static_cast<GLenum>(12), cmd.source_id); EXPECT_EQ(static_cast<GLenum>(13), cmd.dest_id); - EXPECT_EQ(static_cast<GLint>(14), cmd.level); - EXPECT_EQ(static_cast<GLint>(15), cmd.internalformat); - EXPECT_EQ(static_cast<GLenum>(16), cmd.dest_type); + EXPECT_EQ(static_cast<GLint>(14), cmd.internalformat); + EXPECT_EQ(static_cast<GLenum>(15), cmd.dest_type); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, CopySubTextureCHROMIUM) { + cmds::CopySubTextureCHROMIUM& cmd = + *GetBufferAs<cmds::CopySubTextureCHROMIUM>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), + static_cast<GLenum>(12), static_cast<GLenum>(13), + static_cast<GLint>(14), static_cast<GLint>(15)); + EXPECT_EQ(static_cast<uint32_t>(cmds::CopySubTextureCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.source_id); + EXPECT_EQ(static_cast<GLenum>(13), cmd.dest_id); + EXPECT_EQ(static_cast<GLint>(14), cmd.xoffset); + EXPECT_EQ(static_cast<GLint>(15), cmd.yoffset); CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } @@ -3072,11 +4605,13 @@ TEST_F(GLES2FormatTest, ReleaseTexImage2DCHROMIUM) { TEST_F(GLES2FormatTest, TraceBeginCHROMIUM) { cmds::TraceBeginCHROMIUM& cmd = *GetBufferAs<cmds::TraceBeginCHROMIUM>(); - void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11)); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12)); EXPECT_EQ(static_cast<uint32_t>(cmds::TraceBeginCHROMIUM::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<GLuint>(11), cmd.bucket_id); + EXPECT_EQ(static_cast<GLuint>(11), cmd.category_bucket_id); + EXPECT_EQ(static_cast<GLuint>(12), cmd.name_bucket_id); CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } @@ -3270,6 +4805,16 @@ TEST_F(GLES2FormatTest, ScheduleOverlayPlaneCHROMIUM) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, SwapInterval) { + cmds::SwapInterval& cmd = *GetBufferAs<cmds::SwapInterval>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLint>(11)); + EXPECT_EQ(static_cast<uint32_t>(cmds::SwapInterval::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(11), cmd.interval); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, MatrixLoadfCHROMIUMImmediate) { const int kSomeBaseValueToTestWith = 51; static GLfloat data[] = { diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index a34e7d2b6c8..ba8f073ca42 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -16,208 +16,292 @@ OP(AttachShader) /* 257 */ \ OP(BindAttribLocationBucket) /* 258 */ \ OP(BindBuffer) /* 259 */ \ - OP(BindFramebuffer) /* 260 */ \ - OP(BindRenderbuffer) /* 261 */ \ - OP(BindTexture) /* 262 */ \ - OP(BlendColor) /* 263 */ \ - OP(BlendEquation) /* 264 */ \ - OP(BlendEquationSeparate) /* 265 */ \ - OP(BlendFunc) /* 266 */ \ - OP(BlendFuncSeparate) /* 267 */ \ - OP(BufferData) /* 268 */ \ - OP(BufferSubData) /* 269 */ \ - OP(CheckFramebufferStatus) /* 270 */ \ - OP(Clear) /* 271 */ \ - OP(ClearColor) /* 272 */ \ - OP(ClearDepthf) /* 273 */ \ - OP(ClearStencil) /* 274 */ \ - OP(ColorMask) /* 275 */ \ - OP(CompileShader) /* 276 */ \ - OP(CompressedTexImage2DBucket) /* 277 */ \ - OP(CompressedTexImage2D) /* 278 */ \ - OP(CompressedTexSubImage2DBucket) /* 279 */ \ - OP(CompressedTexSubImage2D) /* 280 */ \ - OP(CopyTexImage2D) /* 281 */ \ - OP(CopyTexSubImage2D) /* 282 */ \ - OP(CreateProgram) /* 283 */ \ - OP(CreateShader) /* 284 */ \ - OP(CullFace) /* 285 */ \ - OP(DeleteBuffersImmediate) /* 286 */ \ - OP(DeleteFramebuffersImmediate) /* 287 */ \ - OP(DeleteProgram) /* 288 */ \ - OP(DeleteRenderbuffersImmediate) /* 289 */ \ - OP(DeleteShader) /* 290 */ \ - OP(DeleteTexturesImmediate) /* 291 */ \ - OP(DepthFunc) /* 292 */ \ - OP(DepthMask) /* 293 */ \ - OP(DepthRangef) /* 294 */ \ - OP(DetachShader) /* 295 */ \ - OP(Disable) /* 296 */ \ - OP(DisableVertexAttribArray) /* 297 */ \ - OP(DrawArrays) /* 298 */ \ - OP(DrawElements) /* 299 */ \ - OP(Enable) /* 300 */ \ - OP(EnableVertexAttribArray) /* 301 */ \ - OP(Finish) /* 302 */ \ - OP(Flush) /* 303 */ \ - OP(FramebufferRenderbuffer) /* 304 */ \ - OP(FramebufferTexture2D) /* 305 */ \ - OP(FrontFace) /* 306 */ \ - OP(GenBuffersImmediate) /* 307 */ \ - OP(GenerateMipmap) /* 308 */ \ - OP(GenFramebuffersImmediate) /* 309 */ \ - OP(GenRenderbuffersImmediate) /* 310 */ \ - OP(GenTexturesImmediate) /* 311 */ \ - OP(GetActiveAttrib) /* 312 */ \ - OP(GetActiveUniform) /* 313 */ \ - OP(GetAttachedShaders) /* 314 */ \ - OP(GetAttribLocation) /* 315 */ \ - OP(GetBooleanv) /* 316 */ \ - OP(GetBufferParameteriv) /* 317 */ \ - OP(GetError) /* 318 */ \ - OP(GetFloatv) /* 319 */ \ - OP(GetFramebufferAttachmentParameteriv) /* 320 */ \ - OP(GetIntegerv) /* 321 */ \ - OP(GetProgramiv) /* 322 */ \ - OP(GetProgramInfoLog) /* 323 */ \ - OP(GetRenderbufferParameteriv) /* 324 */ \ - OP(GetShaderiv) /* 325 */ \ - OP(GetShaderInfoLog) /* 326 */ \ - OP(GetShaderPrecisionFormat) /* 327 */ \ - OP(GetShaderSource) /* 328 */ \ - OP(GetString) /* 329 */ \ - OP(GetTexParameterfv) /* 330 */ \ - OP(GetTexParameteriv) /* 331 */ \ - OP(GetUniformfv) /* 332 */ \ - OP(GetUniformiv) /* 333 */ \ - OP(GetUniformLocation) /* 334 */ \ - OP(GetVertexAttribfv) /* 335 */ \ - OP(GetVertexAttribiv) /* 336 */ \ - OP(GetVertexAttribPointerv) /* 337 */ \ - OP(Hint) /* 338 */ \ - OP(IsBuffer) /* 339 */ \ - OP(IsEnabled) /* 340 */ \ - OP(IsFramebuffer) /* 341 */ \ - OP(IsProgram) /* 342 */ \ - OP(IsRenderbuffer) /* 343 */ \ - OP(IsShader) /* 344 */ \ - OP(IsTexture) /* 345 */ \ - OP(LineWidth) /* 346 */ \ - OP(LinkProgram) /* 347 */ \ - OP(PixelStorei) /* 348 */ \ - OP(PolygonOffset) /* 349 */ \ - OP(ReadPixels) /* 350 */ \ - OP(ReleaseShaderCompiler) /* 351 */ \ - OP(RenderbufferStorage) /* 352 */ \ - OP(SampleCoverage) /* 353 */ \ - OP(Scissor) /* 354 */ \ - OP(ShaderBinary) /* 355 */ \ - OP(ShaderSourceBucket) /* 356 */ \ - OP(StencilFunc) /* 357 */ \ - OP(StencilFuncSeparate) /* 358 */ \ - OP(StencilMask) /* 359 */ \ - OP(StencilMaskSeparate) /* 360 */ \ - OP(StencilOp) /* 361 */ \ - OP(StencilOpSeparate) /* 362 */ \ - OP(TexImage2D) /* 363 */ \ - OP(TexParameterf) /* 364 */ \ - OP(TexParameterfvImmediate) /* 365 */ \ - OP(TexParameteri) /* 366 */ \ - OP(TexParameterivImmediate) /* 367 */ \ - OP(TexSubImage2D) /* 368 */ \ - OP(Uniform1f) /* 369 */ \ - OP(Uniform1fvImmediate) /* 370 */ \ - OP(Uniform1i) /* 371 */ \ - OP(Uniform1ivImmediate) /* 372 */ \ - OP(Uniform2f) /* 373 */ \ - OP(Uniform2fvImmediate) /* 374 */ \ - OP(Uniform2i) /* 375 */ \ - OP(Uniform2ivImmediate) /* 376 */ \ - OP(Uniform3f) /* 377 */ \ - OP(Uniform3fvImmediate) /* 378 */ \ - OP(Uniform3i) /* 379 */ \ - OP(Uniform3ivImmediate) /* 380 */ \ - OP(Uniform4f) /* 381 */ \ - OP(Uniform4fvImmediate) /* 382 */ \ - OP(Uniform4i) /* 383 */ \ - OP(Uniform4ivImmediate) /* 384 */ \ - OP(UniformMatrix2fvImmediate) /* 385 */ \ - OP(UniformMatrix3fvImmediate) /* 386 */ \ - OP(UniformMatrix4fvImmediate) /* 387 */ \ - OP(UseProgram) /* 388 */ \ - OP(ValidateProgram) /* 389 */ \ - OP(VertexAttrib1f) /* 390 */ \ - OP(VertexAttrib1fvImmediate) /* 391 */ \ - OP(VertexAttrib2f) /* 392 */ \ - OP(VertexAttrib2fvImmediate) /* 393 */ \ - OP(VertexAttrib3f) /* 394 */ \ - OP(VertexAttrib3fvImmediate) /* 395 */ \ - OP(VertexAttrib4f) /* 396 */ \ - OP(VertexAttrib4fvImmediate) /* 397 */ \ - OP(VertexAttribPointer) /* 398 */ \ - OP(Viewport) /* 399 */ \ - OP(BlitFramebufferCHROMIUM) /* 400 */ \ - OP(RenderbufferStorageMultisampleCHROMIUM) /* 401 */ \ - OP(RenderbufferStorageMultisampleEXT) /* 402 */ \ - OP(FramebufferTexture2DMultisampleEXT) /* 403 */ \ - OP(TexStorage2DEXT) /* 404 */ \ - OP(GenQueriesEXTImmediate) /* 405 */ \ - OP(DeleteQueriesEXTImmediate) /* 406 */ \ - OP(BeginQueryEXT) /* 407 */ \ - OP(EndQueryEXT) /* 408 */ \ - OP(InsertEventMarkerEXT) /* 409 */ \ - OP(PushGroupMarkerEXT) /* 410 */ \ - OP(PopGroupMarkerEXT) /* 411 */ \ - OP(GenVertexArraysOESImmediate) /* 412 */ \ - OP(DeleteVertexArraysOESImmediate) /* 413 */ \ - OP(IsVertexArrayOES) /* 414 */ \ - OP(BindVertexArrayOES) /* 415 */ \ - OP(SwapBuffers) /* 416 */ \ - OP(GetMaxValueInBufferCHROMIUM) /* 417 */ \ - OP(EnableFeatureCHROMIUM) /* 418 */ \ - OP(ResizeCHROMIUM) /* 419 */ \ - OP(GetRequestableExtensionsCHROMIUM) /* 420 */ \ - OP(RequestExtensionCHROMIUM) /* 421 */ \ - OP(GetMultipleIntegervCHROMIUM) /* 422 */ \ - OP(GetProgramInfoCHROMIUM) /* 423 */ \ - OP(GetTranslatedShaderSourceANGLE) /* 424 */ \ - OP(PostSubBufferCHROMIUM) /* 425 */ \ - OP(TexImageIOSurface2DCHROMIUM) /* 426 */ \ - OP(CopyTextureCHROMIUM) /* 427 */ \ - OP(DrawArraysInstancedANGLE) /* 428 */ \ - OP(DrawElementsInstancedANGLE) /* 429 */ \ - OP(VertexAttribDivisorANGLE) /* 430 */ \ - OP(GenMailboxCHROMIUM) /* 431 */ \ - OP(ProduceTextureCHROMIUMImmediate) /* 432 */ \ - OP(ProduceTextureDirectCHROMIUMImmediate) /* 433 */ \ - OP(ConsumeTextureCHROMIUMImmediate) /* 434 */ \ - OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 435 */ \ - OP(BindUniformLocationCHROMIUMBucket) /* 436 */ \ - OP(GenValuebuffersCHROMIUMImmediate) /* 437 */ \ - OP(DeleteValuebuffersCHROMIUMImmediate) /* 438 */ \ - OP(IsValuebufferCHROMIUM) /* 439 */ \ - OP(BindValuebufferCHROMIUM) /* 440 */ \ - OP(SubscribeValueCHROMIUM) /* 441 */ \ - OP(PopulateSubscribedValuesCHROMIUM) /* 442 */ \ - OP(UniformValuebufferCHROMIUM) /* 443 */ \ - OP(BindTexImage2DCHROMIUM) /* 444 */ \ - OP(ReleaseTexImage2DCHROMIUM) /* 445 */ \ - OP(TraceBeginCHROMIUM) /* 446 */ \ - OP(TraceEndCHROMIUM) /* 447 */ \ - OP(AsyncTexSubImage2DCHROMIUM) /* 448 */ \ - OP(AsyncTexImage2DCHROMIUM) /* 449 */ \ - OP(WaitAsyncTexImage2DCHROMIUM) /* 450 */ \ - OP(WaitAllAsyncTexImage2DCHROMIUM) /* 451 */ \ - OP(DiscardFramebufferEXTImmediate) /* 452 */ \ - OP(LoseContextCHROMIUM) /* 453 */ \ - OP(InsertSyncPointCHROMIUM) /* 454 */ \ - OP(WaitSyncPointCHROMIUM) /* 455 */ \ - OP(DrawBuffersEXTImmediate) /* 456 */ \ - OP(DiscardBackbufferCHROMIUM) /* 457 */ \ - OP(ScheduleOverlayPlaneCHROMIUM) /* 458 */ \ - OP(MatrixLoadfCHROMIUMImmediate) /* 459 */ \ - OP(MatrixLoadIdentityCHROMIUM) /* 460 */ \ - OP(BlendBarrierKHR) /* 461 */ + OP(BindBufferBase) /* 260 */ \ + OP(BindBufferRange) /* 261 */ \ + OP(BindFramebuffer) /* 262 */ \ + OP(BindRenderbuffer) /* 263 */ \ + OP(BindSampler) /* 264 */ \ + OP(BindTexture) /* 265 */ \ + OP(BindTransformFeedback) /* 266 */ \ + OP(BlendColor) /* 267 */ \ + OP(BlendEquation) /* 268 */ \ + OP(BlendEquationSeparate) /* 269 */ \ + OP(BlendFunc) /* 270 */ \ + OP(BlendFuncSeparate) /* 271 */ \ + OP(BufferData) /* 272 */ \ + OP(BufferSubData) /* 273 */ \ + OP(CheckFramebufferStatus) /* 274 */ \ + OP(Clear) /* 275 */ \ + OP(ClearBufferfi) /* 276 */ \ + OP(ClearBufferfvImmediate) /* 277 */ \ + OP(ClearBufferivImmediate) /* 278 */ \ + OP(ClearBufferuivImmediate) /* 279 */ \ + OP(ClearColor) /* 280 */ \ + OP(ClearDepthf) /* 281 */ \ + OP(ClearStencil) /* 282 */ \ + OP(ClientWaitSync) /* 283 */ \ + OP(ColorMask) /* 284 */ \ + OP(CompileShader) /* 285 */ \ + OP(CompressedTexImage2DBucket) /* 286 */ \ + OP(CompressedTexImage2D) /* 287 */ \ + OP(CompressedTexSubImage2DBucket) /* 288 */ \ + OP(CompressedTexSubImage2D) /* 289 */ \ + OP(CompressedTexImage3DBucket) /* 290 */ \ + OP(CompressedTexImage3D) /* 291 */ \ + OP(CompressedTexSubImage3DBucket) /* 292 */ \ + OP(CompressedTexSubImage3D) /* 293 */ \ + OP(CopyBufferSubData) /* 294 */ \ + OP(CopyTexImage2D) /* 295 */ \ + OP(CopyTexSubImage2D) /* 296 */ \ + OP(CopyTexSubImage3D) /* 297 */ \ + OP(CreateProgram) /* 298 */ \ + OP(CreateShader) /* 299 */ \ + OP(CullFace) /* 300 */ \ + OP(DeleteBuffersImmediate) /* 301 */ \ + OP(DeleteFramebuffersImmediate) /* 302 */ \ + OP(DeleteProgram) /* 303 */ \ + OP(DeleteRenderbuffersImmediate) /* 304 */ \ + OP(DeleteSamplersImmediate) /* 305 */ \ + OP(DeleteSync) /* 306 */ \ + OP(DeleteShader) /* 307 */ \ + OP(DeleteTexturesImmediate) /* 308 */ \ + OP(DeleteTransformFeedbacksImmediate) /* 309 */ \ + OP(DepthFunc) /* 310 */ \ + OP(DepthMask) /* 311 */ \ + OP(DepthRangef) /* 312 */ \ + OP(DetachShader) /* 313 */ \ + OP(Disable) /* 314 */ \ + OP(DisableVertexAttribArray) /* 315 */ \ + OP(DrawArrays) /* 316 */ \ + OP(DrawElements) /* 317 */ \ + OP(Enable) /* 318 */ \ + OP(EnableVertexAttribArray) /* 319 */ \ + OP(FenceSync) /* 320 */ \ + OP(Finish) /* 321 */ \ + OP(Flush) /* 322 */ \ + OP(FramebufferRenderbuffer) /* 323 */ \ + OP(FramebufferTexture2D) /* 324 */ \ + OP(FramebufferTextureLayer) /* 325 */ \ + OP(FrontFace) /* 326 */ \ + OP(GenBuffersImmediate) /* 327 */ \ + OP(GenerateMipmap) /* 328 */ \ + OP(GenFramebuffersImmediate) /* 329 */ \ + OP(GenRenderbuffersImmediate) /* 330 */ \ + OP(GenSamplersImmediate) /* 331 */ \ + OP(GenTexturesImmediate) /* 332 */ \ + OP(GenTransformFeedbacksImmediate) /* 333 */ \ + OP(GetActiveAttrib) /* 334 */ \ + OP(GetActiveUniform) /* 335 */ \ + OP(GetActiveUniformBlockiv) /* 336 */ \ + OP(GetActiveUniformBlockName) /* 337 */ \ + OP(GetActiveUniformsiv) /* 338 */ \ + OP(GetAttachedShaders) /* 339 */ \ + OP(GetAttribLocation) /* 340 */ \ + OP(GetBooleanv) /* 341 */ \ + OP(GetBufferParameteriv) /* 342 */ \ + OP(GetError) /* 343 */ \ + OP(GetFloatv) /* 344 */ \ + OP(GetFragDataLocation) /* 345 */ \ + OP(GetFramebufferAttachmentParameteriv) /* 346 */ \ + OP(GetInteger64v) /* 347 */ \ + OP(GetIntegeri_v) /* 348 */ \ + OP(GetInteger64i_v) /* 349 */ \ + OP(GetIntegerv) /* 350 */ \ + OP(GetInternalformativ) /* 351 */ \ + OP(GetProgramiv) /* 352 */ \ + OP(GetProgramInfoLog) /* 353 */ \ + OP(GetRenderbufferParameteriv) /* 354 */ \ + OP(GetSamplerParameterfv) /* 355 */ \ + OP(GetSamplerParameteriv) /* 356 */ \ + OP(GetShaderiv) /* 357 */ \ + OP(GetShaderInfoLog) /* 358 */ \ + OP(GetShaderPrecisionFormat) /* 359 */ \ + OP(GetShaderSource) /* 360 */ \ + OP(GetString) /* 361 */ \ + OP(GetSynciv) /* 362 */ \ + OP(GetTexParameterfv) /* 363 */ \ + OP(GetTexParameteriv) /* 364 */ \ + OP(GetTransformFeedbackVarying) /* 365 */ \ + OP(GetUniformBlockIndex) /* 366 */ \ + OP(GetUniformfv) /* 367 */ \ + OP(GetUniformiv) /* 368 */ \ + OP(GetUniformuiv) /* 369 */ \ + OP(GetUniformIndices) /* 370 */ \ + OP(GetUniformLocation) /* 371 */ \ + OP(GetVertexAttribfv) /* 372 */ \ + OP(GetVertexAttribiv) /* 373 */ \ + OP(GetVertexAttribIiv) /* 374 */ \ + OP(GetVertexAttribIuiv) /* 375 */ \ + OP(GetVertexAttribPointerv) /* 376 */ \ + OP(Hint) /* 377 */ \ + OP(InvalidateFramebufferImmediate) /* 378 */ \ + OP(InvalidateSubFramebufferImmediate) /* 379 */ \ + OP(IsBuffer) /* 380 */ \ + OP(IsEnabled) /* 381 */ \ + OP(IsFramebuffer) /* 382 */ \ + OP(IsProgram) /* 383 */ \ + OP(IsRenderbuffer) /* 384 */ \ + OP(IsSampler) /* 385 */ \ + OP(IsShader) /* 386 */ \ + OP(IsSync) /* 387 */ \ + OP(IsTexture) /* 388 */ \ + OP(IsTransformFeedback) /* 389 */ \ + OP(LineWidth) /* 390 */ \ + OP(LinkProgram) /* 391 */ \ + OP(PauseTransformFeedback) /* 392 */ \ + OP(PixelStorei) /* 393 */ \ + OP(PolygonOffset) /* 394 */ \ + OP(ReadBuffer) /* 395 */ \ + OP(ReadPixels) /* 396 */ \ + OP(ReleaseShaderCompiler) /* 397 */ \ + OP(RenderbufferStorage) /* 398 */ \ + OP(ResumeTransformFeedback) /* 399 */ \ + OP(SampleCoverage) /* 400 */ \ + OP(SamplerParameterf) /* 401 */ \ + OP(SamplerParameterfvImmediate) /* 402 */ \ + OP(SamplerParameteri) /* 403 */ \ + OP(SamplerParameterivImmediate) /* 404 */ \ + OP(Scissor) /* 405 */ \ + OP(ShaderBinary) /* 406 */ \ + OP(ShaderSourceBucket) /* 407 */ \ + OP(StencilFunc) /* 408 */ \ + OP(StencilFuncSeparate) /* 409 */ \ + OP(StencilMask) /* 410 */ \ + OP(StencilMaskSeparate) /* 411 */ \ + OP(StencilOp) /* 412 */ \ + OP(StencilOpSeparate) /* 413 */ \ + OP(TexImage2D) /* 414 */ \ + OP(TexImage3D) /* 415 */ \ + OP(TexParameterf) /* 416 */ \ + OP(TexParameterfvImmediate) /* 417 */ \ + OP(TexParameteri) /* 418 */ \ + OP(TexParameterivImmediate) /* 419 */ \ + OP(TexStorage3D) /* 420 */ \ + OP(TexSubImage2D) /* 421 */ \ + OP(TexSubImage3D) /* 422 */ \ + OP(TransformFeedbackVaryingsBucket) /* 423 */ \ + OP(Uniform1f) /* 424 */ \ + OP(Uniform1fvImmediate) /* 425 */ \ + OP(Uniform1i) /* 426 */ \ + OP(Uniform1ivImmediate) /* 427 */ \ + OP(Uniform1ui) /* 428 */ \ + OP(Uniform1uivImmediate) /* 429 */ \ + OP(Uniform2f) /* 430 */ \ + OP(Uniform2fvImmediate) /* 431 */ \ + OP(Uniform2i) /* 432 */ \ + OP(Uniform2ivImmediate) /* 433 */ \ + OP(Uniform2ui) /* 434 */ \ + OP(Uniform2uivImmediate) /* 435 */ \ + OP(Uniform3f) /* 436 */ \ + OP(Uniform3fvImmediate) /* 437 */ \ + OP(Uniform3i) /* 438 */ \ + OP(Uniform3ivImmediate) /* 439 */ \ + OP(Uniform3ui) /* 440 */ \ + OP(Uniform3uivImmediate) /* 441 */ \ + OP(Uniform4f) /* 442 */ \ + OP(Uniform4fvImmediate) /* 443 */ \ + OP(Uniform4i) /* 444 */ \ + OP(Uniform4ivImmediate) /* 445 */ \ + OP(Uniform4ui) /* 446 */ \ + OP(Uniform4uivImmediate) /* 447 */ \ + OP(UniformBlockBinding) /* 448 */ \ + OP(UniformMatrix2fvImmediate) /* 449 */ \ + OP(UniformMatrix2x3fvImmediate) /* 450 */ \ + OP(UniformMatrix2x4fvImmediate) /* 451 */ \ + OP(UniformMatrix3fvImmediate) /* 452 */ \ + OP(UniformMatrix3x2fvImmediate) /* 453 */ \ + OP(UniformMatrix3x4fvImmediate) /* 454 */ \ + OP(UniformMatrix4fvImmediate) /* 455 */ \ + OP(UniformMatrix4x2fvImmediate) /* 456 */ \ + OP(UniformMatrix4x3fvImmediate) /* 457 */ \ + OP(UseProgram) /* 458 */ \ + OP(ValidateProgram) /* 459 */ \ + OP(VertexAttrib1f) /* 460 */ \ + OP(VertexAttrib1fvImmediate) /* 461 */ \ + OP(VertexAttrib2f) /* 462 */ \ + OP(VertexAttrib2fvImmediate) /* 463 */ \ + OP(VertexAttrib3f) /* 464 */ \ + OP(VertexAttrib3fvImmediate) /* 465 */ \ + OP(VertexAttrib4f) /* 466 */ \ + OP(VertexAttrib4fvImmediate) /* 467 */ \ + OP(VertexAttribI4i) /* 468 */ \ + OP(VertexAttribI4ivImmediate) /* 469 */ \ + OP(VertexAttribI4ui) /* 470 */ \ + OP(VertexAttribI4uivImmediate) /* 471 */ \ + OP(VertexAttribIPointer) /* 472 */ \ + OP(VertexAttribPointer) /* 473 */ \ + OP(Viewport) /* 474 */ \ + OP(WaitSync) /* 475 */ \ + OP(BlitFramebufferCHROMIUM) /* 476 */ \ + OP(RenderbufferStorageMultisampleCHROMIUM) /* 477 */ \ + OP(RenderbufferStorageMultisampleEXT) /* 478 */ \ + OP(FramebufferTexture2DMultisampleEXT) /* 479 */ \ + OP(TexStorage2DEXT) /* 480 */ \ + OP(GenQueriesEXTImmediate) /* 481 */ \ + OP(DeleteQueriesEXTImmediate) /* 482 */ \ + OP(BeginQueryEXT) /* 483 */ \ + OP(BeginTransformFeedback) /* 484 */ \ + OP(EndQueryEXT) /* 485 */ \ + OP(EndTransformFeedback) /* 486 */ \ + OP(InsertEventMarkerEXT) /* 487 */ \ + OP(PushGroupMarkerEXT) /* 488 */ \ + OP(PopGroupMarkerEXT) /* 489 */ \ + OP(GenVertexArraysOESImmediate) /* 490 */ \ + OP(DeleteVertexArraysOESImmediate) /* 491 */ \ + OP(IsVertexArrayOES) /* 492 */ \ + OP(BindVertexArrayOES) /* 493 */ \ + OP(SwapBuffers) /* 494 */ \ + OP(GetMaxValueInBufferCHROMIUM) /* 495 */ \ + OP(EnableFeatureCHROMIUM) /* 496 */ \ + OP(MapBufferRange) /* 497 */ \ + OP(UnmapBuffer) /* 498 */ \ + OP(ResizeCHROMIUM) /* 499 */ \ + OP(GetRequestableExtensionsCHROMIUM) /* 500 */ \ + OP(RequestExtensionCHROMIUM) /* 501 */ \ + OP(GetProgramInfoCHROMIUM) /* 502 */ \ + OP(GetUniformBlocksCHROMIUM) /* 503 */ \ + OP(GetTransformFeedbackVaryingsCHROMIUM) /* 504 */ \ + OP(GetUniformsES3CHROMIUM) /* 505 */ \ + OP(GetTranslatedShaderSourceANGLE) /* 506 */ \ + OP(PostSubBufferCHROMIUM) /* 507 */ \ + OP(TexImageIOSurface2DCHROMIUM) /* 508 */ \ + OP(CopyTextureCHROMIUM) /* 509 */ \ + OP(CopySubTextureCHROMIUM) /* 510 */ \ + OP(DrawArraysInstancedANGLE) /* 511 */ \ + OP(DrawElementsInstancedANGLE) /* 512 */ \ + OP(VertexAttribDivisorANGLE) /* 513 */ \ + OP(GenMailboxCHROMIUM) /* 514 */ \ + OP(ProduceTextureCHROMIUMImmediate) /* 515 */ \ + OP(ProduceTextureDirectCHROMIUMImmediate) /* 516 */ \ + OP(ConsumeTextureCHROMIUMImmediate) /* 517 */ \ + OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 518 */ \ + OP(BindUniformLocationCHROMIUMBucket) /* 519 */ \ + OP(GenValuebuffersCHROMIUMImmediate) /* 520 */ \ + OP(DeleteValuebuffersCHROMIUMImmediate) /* 521 */ \ + OP(IsValuebufferCHROMIUM) /* 522 */ \ + OP(BindValuebufferCHROMIUM) /* 523 */ \ + OP(SubscribeValueCHROMIUM) /* 524 */ \ + OP(PopulateSubscribedValuesCHROMIUM) /* 525 */ \ + OP(UniformValuebufferCHROMIUM) /* 526 */ \ + OP(BindTexImage2DCHROMIUM) /* 527 */ \ + OP(ReleaseTexImage2DCHROMIUM) /* 528 */ \ + OP(TraceBeginCHROMIUM) /* 529 */ \ + OP(TraceEndCHROMIUM) /* 530 */ \ + OP(AsyncTexSubImage2DCHROMIUM) /* 531 */ \ + OP(AsyncTexImage2DCHROMIUM) /* 532 */ \ + OP(WaitAsyncTexImage2DCHROMIUM) /* 533 */ \ + OP(WaitAllAsyncTexImage2DCHROMIUM) /* 534 */ \ + OP(DiscardFramebufferEXTImmediate) /* 535 */ \ + OP(LoseContextCHROMIUM) /* 536 */ \ + OP(InsertSyncPointCHROMIUM) /* 537 */ \ + OP(WaitSyncPointCHROMIUM) /* 538 */ \ + OP(DrawBuffersEXTImmediate) /* 539 */ \ + OP(DiscardBackbufferCHROMIUM) /* 540 */ \ + OP(ScheduleOverlayPlaneCHROMIUM) /* 541 */ \ + OP(SwapInterval) /* 542 */ \ + OP(MatrixLoadfCHROMIUMImmediate) /* 543 */ \ + OP(MatrixLoadIdentityCHROMIUM) /* 544 */ \ + OP(BlendBarrierKHR) /* 545 */ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc b/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc index 6b34f392616..d58156f37e6 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc +++ b/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc @@ -9,7 +9,9 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> #include <GLES2/gl2extchromium.h> +#include <GLES3/gl3.h> +#include "base/numerics/safe_math.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" @@ -201,8 +203,6 @@ int GLES2Util::GLGetNumValuesReturned(int id) const { return 1; case GL_TEXTURE_BINDING_RECTANGLE_ARB: return 1; - case GL_TEXTURE_IMMUTABLE_FORMAT_EXT: - return 1; case GL_UNPACK_ALIGNMENT: return 1; case GL_VIEWPORT: @@ -304,14 +304,32 @@ int GLES2Util::GLGetNumValuesReturned(int id) const { 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; - // -- glGetVertexAttribfv, glGetVertexAttribiv + // -- glGetVertexAttrib case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: return 1; case GL_VERTEX_ATTRIB_ARRAY_ENABLED: @@ -326,6 +344,20 @@ int GLES2Util::GLGetNumValuesReturned(int id) const { 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: @@ -350,6 +382,10 @@ int ElementsPerGroup(int format, int type) { 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; @@ -357,11 +393,15 @@ int ElementsPerGroup(int format, int type) { 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; @@ -373,6 +413,8 @@ int ElementsPerGroup(int format, int type) { 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; @@ -382,9 +424,14 @@ int ElementsPerGroup(int format, int type) { // 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_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_OES: case GL_UNSIGNED_SHORT: @@ -404,12 +451,18 @@ int BytesPerElement(int type) { } // anonymous namespace uint32 GLES2Util::ComputeImageGroupSize(int format, int type) { - return BytesPerElement(type) * ElementsPerGroup(format, 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::ComputeImagePaddedRowSize( int width, int format, int type, int unpack_alignment, uint32* padded_row_size) { + DCHECK(unpack_alignment == 1 || unpack_alignment == 2 || + unpack_alignment == 4 || unpack_alignment == 8); uint32 bytes_per_group = ComputeImageGroupSize(format, type); uint32 unpadded_row_size; if (!SafeMultiplyUint32(width, bytes_per_group, &unpadded_row_size)) { @@ -423,23 +476,30 @@ bool GLES2Util::ComputeImagePaddedRowSize( return true; } -// Returns the amount of data glTexImage2D or glTexSubImage2D will access. +// Returns the amount of data glTexImage*D or glTexSubImage*D will access. bool GLES2Util::ComputeImageDataSizes( - int width, int height, int format, int type, int unpack_alignment, - uint32* size, uint32* ret_unpadded_row_size, uint32* ret_padded_row_size) { + int width, int height, int depth, int format, int type, + int unpack_alignment, uint32* size, uint32* ret_unpadded_row_size, + uint32* ret_padded_row_size) { + DCHECK(unpack_alignment == 1 || unpack_alignment == 2 || + unpack_alignment == 4 || unpack_alignment == 8); uint32 bytes_per_group = ComputeImageGroupSize(format, type); uint32 row_size; if (!SafeMultiplyUint32(width, bytes_per_group, &row_size)) { return false; } - if (height > 1) { + uint32 num_of_rows; + if (!SafeMultiplyUint32(height, depth, &num_of_rows)) { + return false; + } + if (num_of_rows > 1) { uint32 temp; if (!SafeAddUint32(row_size, unpack_alignment - 1, &temp)) { return false; } uint32 padded_row_size = (temp / unpack_alignment) * unpack_alignment; uint32 size_of_all_but_last_row; - if (!SafeMultiplyUint32((height - 1), padded_row_size, + if (!SafeMultiplyUint32((num_of_rows - 1), padded_row_size, &size_of_all_but_last_row)) { return false; } @@ -450,9 +510,7 @@ bool GLES2Util::ComputeImageDataSizes( *ret_padded_row_size = padded_row_size; } } else { - if (!SafeMultiplyUint32(height, row_size, size)) { - return false; - } + *size = row_size; if (ret_padded_row_size) { *ret_padded_row_size = row_size; } @@ -485,46 +543,123 @@ size_t GLES2Util::RenderbufferBytesPerPixel(int format) { } } -uint32 GLES2Util::GetGLDataTypeSizeForUniforms(int type) { +uint32 GLES2Util::GetElementSizeForUniformType(int type) { switch (type) { case GL_FLOAT: - return sizeof(GLfloat); // NOLINT case GL_FLOAT_VEC2: - return sizeof(GLfloat) * 2; // NOLINT case GL_FLOAT_VEC3: - return sizeof(GLfloat) * 3; // NOLINT case GL_FLOAT_VEC4: - return sizeof(GLfloat) * 4; // NOLINT + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT4: + return sizeof(GLfloat); case GL_INT: - return sizeof(GLint); // NOLINT case GL_INT_VEC2: - return sizeof(GLint) * 2; // NOLINT case GL_INT_VEC3: - return sizeof(GLint) * 3; // NOLINT case GL_INT_VEC4: - return sizeof(GLint) * 4; // NOLINT case GL_BOOL: - return sizeof(GLint); // NOLINT case GL_BOOL_VEC2: - return sizeof(GLint) * 2; // NOLINT case GL_BOOL_VEC3: - return sizeof(GLint) * 3; // NOLINT case GL_BOOL_VEC4: - return sizeof(GLint) * 4; // NOLINT + 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 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 sizeof(GLfloat) * 2 * 2; // NOLINT + return 4; case GL_FLOAT_MAT3: - return sizeof(GLfloat) * 3 * 3; // NOLINT + return 9; case GL_FLOAT_MAT4: - return sizeof(GLfloat) * 4 * 4; // NOLINT - case GL_SAMPLER_2D: - return sizeof(GLint); // NOLINT - case GL_SAMPLER_2D_RECT_ARB: - return sizeof(GLint); // NOLINT - case GL_SAMPLER_CUBE: - return sizeof(GLint); // NOLINT - case GL_SAMPLER_EXTERNAL_OES: - return sizeof(GLint); // NOLINT + 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; } @@ -610,6 +745,8 @@ size_t GLES2Util::GLTargetToFaceIndex(uint32 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; @@ -682,6 +819,16 @@ uint32 GLES2Util::GetChannelsForFormat(int format) { 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: @@ -693,17 +840,52 @@ uint32 GLES2Util::GetChannelsForFormat(int format) { 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; } @@ -768,9 +950,11 @@ bool GLES2Util::ParseUniformName( size_t* array_pos, int* element_index, bool* getting_array) { + if (name.empty()) + return false; bool getting_array_location = false; size_t open_pos = std::string::npos; - int index = 0; + base::CheckedNumeric<int> index = 0; if (name[name.size() - 1] == ']') { if (name.size() < 3) { return false; @@ -788,14 +972,78 @@ bool GLES2Util::ParseUniformName( } index = index * 10 + digit; } + if (!index.IsValid()) { + return false; + } getting_array_location = true; } *getting_array = getting_array_location; - *element_index = index; + *element_index = index.ValueOrDie(); *array_pos = open_pos; return true; } +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; + } +} + + namespace { // WebGraphicsContext3DCommandBufferImpl configuration attributes. Those in @@ -820,6 +1068,7 @@ const int32 kBufferDestroyed = 0x3095; // EGL_BUFFER_DESTROYED const int32 kBindGeneratesResource = 0x10000; const int32 kFailIfMajorPerfCaveat = 0x10001; const int32 kLoseContextWhenOutOfMemory = 0x10002; +const int32 kES3ContextRequired = 0x10003; } // namespace @@ -835,7 +1084,8 @@ ContextCreationAttribHelper::ContextCreationAttribHelper() buffer_preserved(true), bind_generates_resource(true), fail_if_major_perf_caveat(false), - lose_context_when_out_of_memory(false) {} + lose_context_when_out_of_memory(false), + es3_context_required(false) {} void ContextCreationAttribHelper::Serialize(std::vector<int32>* attribs) const { if (alpha_size != -1) { @@ -878,6 +1128,8 @@ void ContextCreationAttribHelper::Serialize(std::vector<int32>* attribs) const { attribs->push_back(fail_if_major_perf_caveat ? 1 : 0); attribs->push_back(kLoseContextWhenOutOfMemory); attribs->push_back(lose_context_when_out_of_memory ? 1 : 0); + attribs->push_back(kES3ContextRequired); + attribs->push_back(es3_context_required ? 1 : 0); attribs->push_back(kNone); } @@ -932,6 +1184,9 @@ bool ContextCreationAttribHelper::Parse(const std::vector<int32>& attribs) { case kLoseContextWhenOutOfMemory: lose_context_when_out_of_memory = value != 0; break; + case kES3ContextRequired: + es3_context_required = value != 0; + break; case kNone: // Terminate list, even if more attributes. return true; diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_utils.h b/chromium/gpu/command_buffer/common/gles2_cmd_utils.h index 163ffc008c2..aac9d6036ed 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_utils.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_utils.h @@ -14,6 +14,7 @@ #include <string> #include <vector> +#include "base/numerics/safe_math.h" #include "gpu/command_buffer/common/gles2_utils_export.h" namespace gpu { @@ -25,44 +26,29 @@ namespace gles2 { // Multiplies 2 32 bit unsigned numbers checking for overflow. // If there was no overflow returns true. inline bool SafeMultiplyUint32(uint32_t a, uint32_t b, uint32_t* dst) { - if (b == 0) { - *dst = 0; - return true; - } - uint32_t v = a * b; - if (v / b != a) { - *dst = 0; - return false; - } - *dst = v; - return true; + DCHECK(dst); + base::CheckedNumeric<uint32_t> checked = a; + checked *= b; + *dst = checked.ValueOrDefault(0); + return checked.IsValid(); } // Does an add checking for overflow. If there was no overflow returns true. inline bool SafeAddUint32(uint32_t a, uint32_t b, uint32_t* dst) { - if (a + b < a) { - *dst = 0; - return false; - } - *dst = a + b; - return true; + DCHECK(dst); + base::CheckedNumeric<uint32_t> checked = a; + checked += b; + *dst = checked.ValueOrDefault(0); + return checked.IsValid(); } // Does an add checking for overflow. If there was no overflow returns true. inline bool SafeAddInt32(int32_t a, int32_t b, int32_t* dst) { - int64_t sum64 = static_cast<int64_t>(a) + b; - int32_t sum32 = static_cast<int32_t>(sum64); - bool safe = sum64 == static_cast<int64_t>(sum32); - *dst = safe ? sum32 : 0; - return safe; -} - -// Return false if |value| is more than a 32 bit integer can represent. -template<typename T> -inline bool FitInt32NonNegative(T value) { - const int32_t max = std::numeric_limits<int32_t>::max(); - return (std::numeric_limits<T>::max() <= max || - value <= static_cast<T>(max)); + DCHECK(dst); + base::CheckedNumeric<int32_t> checked = a; + checked += b; + *dst = checked.ValueOrDefault(0); + return checked.IsValid(); } // Utilties for GLES2 support. @@ -126,12 +112,18 @@ class GLES2_UTILS_EXPORT GLES2Util { // then the padded_row_size will be the same as the unpadded_row_size since // padding is not necessary. static bool ComputeImageDataSizes( - int width, int height, int format, int type, int unpack_alignment, - uint32_t* size, uint32_t* unpadded_row_size, uint32_t* padded_row_size); + int width, int height, int depth, int format, int type, + int unpack_alignment, uint32_t* size, uint32_t* unpadded_row_size, + uint32_t* padded_row_size); static size_t RenderbufferBytesPerPixel(int format); - static uint32_t GetGLDataTypeSizeForUniforms(int type); + // Return the element's number of bytes. + // For example, GL_FLOAT_MAT3 returns sizeof(GLfloat). + static uint32_t GetElementSizeForUniformType(int type); + // Return the number of elements. + // For example, GL_FLOAT_MAT3 returns 9. + static uint32_t GetElementCountForUniformType(int type); static size_t GetGLTypeSizeForTexturesAndBuffers(uint32_t type); @@ -183,6 +175,15 @@ class GLES2_UTILS_EXPORT GLES2Util { int* element_index, bool* getting_array); + static size_t CalcClearBufferivDataCount(int buffer); + static size_t CalcClearBufferfvDataCount(int buffer); + + static void MapUint64ToTwoUint32( + uint64_t v64, uint32_t* v32_0, uint32_t* v32_1); + static uint64_t MapTwoUint32ToUint64(uint32_t v32_0, uint32_t v32_1); + + static uint32_t MapBufferTargetToBindingEnum(uint32_t target); + #include "../common/gles2_cmd_utils_autogen.h" private: @@ -215,6 +216,7 @@ struct GLES2_UTILS_EXPORT ContextCreationAttribHelper { bool bind_generates_resource; bool fail_if_major_perf_caveat; bool lose_context_when_out_of_memory; + bool es3_context_required; }; } // namespace gles2 diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_utils_autogen.h index e8631e675a1..6e3d161ffe5 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_utils_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_utils_autogen.h @@ -14,9 +14,14 @@ static std::string GetStringAttachment(uint32_t value); static std::string GetStringBackbufferAttachment(uint32_t value); static std::string GetStringBlitFilter(uint32_t value); +static std::string GetStringBufferMode(uint32_t value); static std::string GetStringBufferParameter(uint32_t value); static std::string GetStringBufferTarget(uint32_t value); static std::string GetStringBufferUsage(uint32_t value); +static std::string GetStringBufferfi(uint32_t value); +static std::string GetStringBufferfv(uint32_t value); +static std::string GetStringBufferiv(uint32_t value); +static std::string GetStringBufferuiv(uint32_t value); static std::string GetStringCapability(uint32_t value); static std::string GetStringCmpFunction(uint32_t value); static std::string GetStringCompressedTextureFormat(uint32_t value); @@ -35,6 +40,11 @@ static std::string GetStringHintTarget(uint32_t value); static std::string GetStringImageInternalFormat(uint32_t value); static std::string GetStringImageUsage(uint32_t value); static std::string GetStringIndexType(uint32_t value); +static std::string GetStringIndexedBufferTarget(uint32_t value); +static std::string GetStringIndexedGLState(uint32_t value); +static std::string GetStringInternalFormatParameter(uint32_t value); +static std::string GetStringInvalidateFrameBufferTarget(uint32_t value); +static std::string GetStringMapBufferAccess(uint32_t value); static std::string GetStringMatrixMode(uint32_t value); static std::string GetStringPixelStore(uint32_t value); static std::string GetStringPixelType(uint32_t value); @@ -48,6 +58,7 @@ static std::string GetStringRenderBufferFormat(uint32_t value); static std::string GetStringRenderBufferParameter(uint32_t value); static std::string GetStringRenderBufferTarget(uint32_t value); static std::string GetStringResetStatus(uint32_t value); +static std::string GetStringSamplerParameter(uint32_t value); static std::string GetStringShaderBinaryFormat(uint32_t value); static std::string GetStringShaderParameter(uint32_t value); static std::string GetStringShaderPrecision(uint32_t value); @@ -56,7 +67,12 @@ static std::string GetStringSrcBlendFactor(uint32_t value); static std::string GetStringStencilOp(uint32_t value); static std::string GetStringStringType(uint32_t value); static std::string GetStringSubscriptionTarget(uint32_t value); +static std::string GetStringSyncCondition(uint32_t value); +static std::string GetStringSyncParameter(uint32_t value); +static std::string GetStringTexture3DTarget(uint32_t value); static std::string GetStringTextureBindTarget(uint32_t value); +static std::string GetStringTextureCompareFunc(uint32_t value); +static std::string GetStringTextureCompareMode(uint32_t value); static std::string GetStringTextureFormat(uint32_t value); static std::string GetStringTextureInternalFormat(uint32_t value); static std::string GetStringTextureInternalFormatStorage(uint32_t value); @@ -67,7 +83,12 @@ static std::string GetStringTexturePool(uint32_t value); static std::string GetStringTextureTarget(uint32_t value); static std::string GetStringTextureUsage(uint32_t value); static std::string GetStringTextureWrapMode(uint32_t value); +static std::string GetStringTransformFeedbackBindTarget(uint32_t value); +static std::string GetStringTransformFeedbackPrimitiveMode(uint32_t value); +static std::string GetStringUniformBlockParameter(uint32_t value); +static std::string GetStringUniformParameter(uint32_t value); static std::string GetStringValueBufferTarget(uint32_t value); +static std::string GetStringVertexAttribIType(uint32_t value); static std::string GetStringVertexAttribType(uint32_t value); static std::string GetStringVertexAttribute(uint32_t value); static std::string GetStringVertexPointer(uint32_t value); diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index 1a0945a857b..7cba5373ee6 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -13,6 +13,14 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { { + 0x8D77, + "GL_RGB16UI", + }, + { + 0x8D76, + "GL_RGBA16UI", + }, + { 0x9260, "GL_GCCSO_SHADER_BINARY_FJ", }, @@ -21,10 +29,26 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE_CUBE_MAP_ARRAY_EXT", }, { + 0x8D71, + "GL_RGB32UI", + }, + { + 0x8D70, + "GL_RGBA32UI", + }, + { + 0x8C76, + "GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH", + }, + { 0x8825, "GL_DRAW_BUFFER0_EXT", }, { + 0x8D94, + "GL_RED_INTEGER", + }, + { 0x0BC1, "GL_ALPHA_TEST_FUNC_QCOM", }, @@ -85,6 +109,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_BGRA8_EXT", }, { + 0x813C, + "GL_TEXTURE_BASE_LEVEL", + }, + { 0, "GL_FALSE", }, @@ -93,6 +121,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_STENCIL_BUFFER_BIT6_QCOM", }, { + 64, + "GL_MAILBOX_SIZE_CHROMIUM", + }, + { 0x9500, "GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL", }, @@ -137,6 +169,14 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE_SAMPLES_IMG", }, { + 0x8D88, + "GL_RGBA16I", + }, + { + 0x8D89, + "GL_RGB16I", + }, + { 0x00000020, "GL_COLOR_BUFFER_BIT5_QCOM", }, @@ -181,6 +221,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_LINES", }, { + 0x8D7D, + "GL_RGB8UI", + }, + { 0x93F0, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG", }, @@ -189,6 +233,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG", }, { + 0x0D04, + "GL_PACK_SKIP_PIXELS", + }, + { 0x900E, "GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT", }, @@ -197,6 +245,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT", }, { + 0x8C7F, + "GL_TRANSFORM_FEEDBACK_BUFFER_MODE", + }, + { 0x900F, "GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT", }, @@ -209,8 +261,8 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_SAMPLER_CUBE_MAP_ARRAY_EXT", }, { - 0x88B8, - "GL_READ_ONLY", + 0x8213, + "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE", }, { 0x88B9, @@ -233,6 +285,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_Z400_BINARY_AMD", }, { + 0x8215, + "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE", + }, + { 0x8C4D, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV", }, @@ -337,6 +393,14 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_FLOAT_VEC2", }, { + 0x806D, + "GL_UNPACK_SKIP_IMAGES", + }, + { + 0x806E, + "GL_UNPACK_IMAGE_HEIGHT", + }, + { 0x806F, "GL_TEXTURE_3D_OES", }, @@ -353,10 +417,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE_BINDING_3D_OES", }, { + 0x8D8E, + "GL_RGBA8I", + }, + { 0x8CE3, "GL_COLOR_ATTACHMENT3_EXT", }, { + 0x9274, + "GL_COMPRESSED_RGB8_ETC2", + }, + { 0x1904, "GL_GREEN_NV", }, @@ -369,6 +441,14 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE_BINDING_2D", }, { + 0x8A2E, + "GL_MAX_COMBINED_UNIFORM_BLOCKS", + }, + { + 0x8F96, + "GL_RGB8_SNORM", + }, + { 0x8260, "GL_UNDEFINED_VERTEX_EXT", }, @@ -377,6 +457,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_NO_RESET_NOTIFICATION_KHR", }, { + 0x0D02, + "GL_PACK_ROW_LENGTH", + }, + { 0x8DFA, "GL_SHADER_COMPILER", }, @@ -417,6 +501,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_NUM_PROGRAM_BINARY_FORMATS_OES", }, { + 0x8A41, + "GL_UNIFORM_BLOCK_NAME_LENGTH", + }, + { 0x2600, "GL_NEAREST", }, @@ -429,10 +517,26 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG", }, { + 0x821B, + "GL_MAJOR_VERSION", + }, + { + 0x821A, + "GL_DEPTH_STENCIL_ATTACHMENT", + }, + { + 0x8A40, + "GL_UNIFORM_BLOCK_DATA_SIZE", + }, + { 0x9242, "GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM", }, { + 0x821D, + "GL_NUM_EXTENSIONS", + }, + { 0x88BB, "GL_BUFFER_ACCESS_OES", }, @@ -449,6 +553,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TIME_ELAPSED_EXT", }, { + 0x8A46, + "GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER", + }, + { + 0x6003, + "GL_GET_ERROR_QUERY_CHROMIUM", + }, + { + 0x8F94, + "GL_R8_SNORM", + }, + { 0x0C10, "GL_SCISSOR_BOX", }, @@ -521,6 +637,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_STENCIL_BUFFER_BIT5_QCOM", }, { + 0x8D9F, + "GL_INT_2_10_10_10_REV", + }, + { 0x8B8A, "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH", }, @@ -593,6 +713,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_VALIDATE_STATUS", }, { + 0x9380, + "GL_NUM_SAMPLE_COUNTS", + }, + { 0x8D48, "GL_STENCIL_INDEX8", }, @@ -629,6 +753,14 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_RENDERBUFFER", }, { + 0x8A3A, + "GL_UNIFORM_BLOCK_INDEX", + }, + { + 0x88B8, + "GL_READ_ONLY", + }, + { 0x0BD0, "GL_DITHER", }, @@ -657,6 +789,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_SRC_OVER_NV", }, { + 0x9120, + "GL_BUFFER_MAP_LENGTH", + }, + { 0x0B21, "GL_LINE_WIDTH", }, @@ -677,10 +813,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_DEPTH_COMPONENT32_OES", }, { + 0x88FD, + "GL_VERTEX_ATTRIB_ARRAY_INTEGER", + }, + { 0x88FE, "GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE", }, { + 0x88FF, + "GL_MAX_ARRAY_TEXTURE_LAYERS", + }, + { 0x8B6A, "GL_FLOAT_MAT4x3_NV", }, @@ -825,6 +969,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_COMMANDS_COMPLETED_CHROMIUM", }, { + 0x8F9C, + "GL_SIGNED_NORMALIZED", + }, + { 0x92D5, "GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT", }, @@ -1037,6 +1185,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_SRC_ALPHA", }, { + 0x8212, + "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE", + }, + { 0x0308, "GL_SRC_ALPHA_SATURATE", }, @@ -1085,10 +1237,26 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_RGB32F_EXT", }, { + 0x8A35, + "GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH", + }, + { 0x8814, "GL_RGBA32F_EXT", }, { + 0x6006, + "GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM", + }, + { + 0x9277, + "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2", + }, + { + 0x6004, + "GL_COMMANDS_ISSUED_CHROMIUM", + }, + { 0x813D, "GL_TEXTURE_MAX_LEVEL_APPLE", }, @@ -1097,6 +1265,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_ALPHA32F_EXT", }, { + 0x813B, + "GL_TEXTURE_MAX_LOD", + }, + { 0x8CDD, "GL_FRAMEBUFFER_UNSUPPORTED", }, @@ -1125,8 +1297,12 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_ALPHA8_OES", }, { + 0x8904, + "GL_MIN_PROGRAM_TEXEL_OFFSET", + }, + { 0x84F5, - "GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM", + "GL_TEXTURE_RECTANGLE_ARB", }, { 0x882A, @@ -1142,7 +1318,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { }, { 0x84F6, - "GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM", + "GL_TEXTURE_BINDING_RECTANGLE_ARB", }, { 0x80AB, @@ -1153,6 +1329,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_MAX_PATCH_VERTICES_EXT", }, { + 0x6005, + "GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM", + }, + { 0x9105, "GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES", }, @@ -1185,14 +1365,54 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_FRACTIONAL_EVEN_EXT", }, { + 0x8C8E, + "GL_TRANSFORM_FEEDBACK_BUFFER", + }, + { + 0x8C8D, + "GL_SEPARATE_ATTRIBS", + }, + { + 0x8C8F, + "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING", + }, + { + 0x8C8A, + "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", + }, + { + 0x8C8C, + "GL_INTERLEAVED_ATTRIBS", + }, + { + 0x8C8B, + "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", + }, + { 0x8C17, "GL_UNSIGNED_NORMALIZED_EXT", }, { + 0x8A3E, + "GL_UNIFORM_IS_ROW_MAJOR", + }, + { 0x8E7A, "GL_ISOLINES_EXT", }, { + 0x8F95, + "GL_RG8_SNORM", + }, + { + 0x8D99, + "GL_RGBA_INTEGER", + }, + { + 0x8D98, + "GL_RGB_INTEGER", + }, + { 0x8A4A, "GL_SKIP_DECODE_EXT", }, @@ -1213,6 +1433,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT", }, { + 0x8919, + "GL_SAMPLER_BINDING", + }, + { 0x92CD, "GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT", }, @@ -1221,6 +1445,22 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT", }, { + 0x8C85, + "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE", + }, + { + 0x8D7C, + "GL_RGBA8UI", + }, + { + 0x6007, + "GL_LATENCY_QUERY_CHROMIUM", + }, + { + 0x8D83, + "GL_RGB32I", + }, + { 0x8916, "GL_GEOMETRY_LINKED_VERTICES_OUT_EXT", }, @@ -1233,12 +1473,20 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_LUMINANCE_ALPHA16F_EXT", }, { + 0x84FD, + "GL_MAX_TEXTURE_LOD_BIAS", + }, + { 0x882D, "GL_DRAW_BUFFER8_EXT", }, { - 0x0BA6, - "GL_PATH_MODELVIEW_MATRIX_CHROMIUM", + 0x8A43, + "GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES", + }, + { + 0x8A42, + "GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS", }, { 0x8F37, @@ -1253,6 +1501,14 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT", }, { + 0x8A3C, + "GL_UNIFORM_ARRAY_STRIDE", + }, + { + 0x8A44, + "GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER", + }, + { 0x6000, "GL_TEXTURE_POOL_CHROMIUM", }, @@ -1297,6 +1553,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_PRIMITIVES_GENERATED_EXT", }, { + 0x8C80, + "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS", + }, + { + 0x8C83, + "GL_TRANSFORM_FEEDBACK_VARYINGS", + }, + { + 0x8D69, + "GL_PRIMITIVE_RESTART_FIXED_INDEX", + }, + { 0x882E, "GL_DRAW_BUFFER9_EXT", }, @@ -1305,6 +1573,22 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT", }, { + 0x8A31, + "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS", + }, + { + 0x8C89, + "GL_RASTERIZER_DISCARD", + }, + { + 0x8C88, + "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN", + }, + { + 0x8C1A, + "GL_TEXTURE_2D_ARRAY", + }, + { 0x910D, "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES", }, @@ -1381,10 +1665,30 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_COVERAGE_COMPONENT_NV", }, { + 0x8217, + "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE", + }, + { 0x8E89, "GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT", }, { + 0x8216, + "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE", + }, + { + 0x8A36, + "GL_ACTIVE_UNIFORM_BLOCKS", + }, + { + 0x8A37, + "GL_UNIFORM_TYPE", + }, + { + 0x8A34, + "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT", + }, + { 0x3006, "GL_CLIP_DISTANCE6_APPLE", }, @@ -1393,6 +1697,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_FUNC_REVERSE_SUBTRACT", }, { + 0x8A33, + "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", + }, + { 0x00000400, "GL_STENCIL_BUFFER_BIT", }, @@ -1401,6 +1709,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_FUNC_SUBTRACT", }, { + 0x8214, + "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE", + }, + { + 0x8A38, + "GL_UNIFORM_SIZE", + }, + { + 0x8A39, + "GL_UNIFORM_NAME_LENGTH", + }, + { 0x8E2C, "GL_DEPTH_COMPONENT16_NONLINEAR_NV", }, @@ -1413,10 +1733,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_FRAMEBUFFER_UNDEFINED_OES", }, { + 0x8E23, + "GL_TRANSFORM_FEEDBACK_PAUSED", + }, + { 0x8E22, "GL_TRANSFORM_FEEDBACK", }, { + 0x8E25, + "GL_TRANSFORM_FEEDBACK_BINDING", + }, + { 0x9054, "GL_IMAGE_CUBE_MAP_ARRAY_EXT", }, @@ -1489,6 +1817,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE_FORMAT_QCOM", }, { + 0x8228, + "GL_RG_INTEGER", + }, + { 0x2901, "GL_REPEAT", }, @@ -1605,8 +1937,12 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_VIVIDLIGHT_NV", }, { - 0x78F1, - "GL_MAP_CHROMIUM", + 0x8DCC, + "GL_INT_SAMPLER_CUBE", + }, + { + 0x8905, + "GL_MAX_PROGRAM_TEXEL_OFFSET", }, { 0x00080000, @@ -1617,6 +1953,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_LINEARLIGHT_NV", }, { + 0x8DCF, + "GL_INT_SAMPLER_2D_ARRAY", + }, + { 0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED", }, @@ -1637,6 +1977,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT", }, { + 0x8DCA, + "GL_INT_SAMPLER_2D", + }, + { 0x93C7, "GL_COMPRESSED_RGBA_ASTC_6x5x5_OES", }, @@ -1665,6 +2009,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_DMP_PROGRAM_BINARY_DMP", }, { + 0x8DC8, + "GL_UNSIGNED_INT_VEC4", + }, + { 0x3000, "GL_CLIP_DISTANCE0_APPLE", }, @@ -1673,6 +2021,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_ATC_RGB_AMD", }, { + 0x8DC1, + "GL_SAMPLER_2D_ARRAY", + }, + { 0x9154, "GL_VERTEX_ARRAY_OBJECT_EXT", }, @@ -1697,6 +2049,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_CONTEXT_FLAG_DEBUG_BIT_KHR", }, { + 0x8A3F, + "GL_UNIFORM_BLOCK_BINDING", + }, + { 0x00000000, "GL_PERFQUERY_SINGLE_CONTEXT_INTEL", }, @@ -1729,6 +2085,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_BOOL_VEC3", }, { + 0x8A3D, + "GL_UNIFORM_MATRIX_STRIDE", + }, + { 0x8828, "GL_DRAW_BUFFER3_EXT", }, @@ -1829,6 +2189,14 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_FLOAT_VEC4", }, { + 0x8239, + "GL_RG16I", + }, + { + 0x8238, + "GL_RG8UI", + }, + { 0x9240, "GL_UNPACK_FLIP_Y_CHROMIUM", }, @@ -1837,16 +2205,44 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_UNSIGNED_INT_10_10_10_2_OES", }, { + 0x8A30, + "GL_MAX_UNIFORM_BLOCK_SIZE", + }, + { + 0x9273, + "GL_COMPRESSED_SIGNED_RG11_EAC", + }, + { + 0x8231, + "GL_R8I", + }, + { 0x8866, "GL_QUERY_RESULT_EXT", }, { + 0x8233, + "GL_R16I", + }, + { 0x8DF7, "GL_INT_10_10_10_2_OES", }, { - 0x9246, - "GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM", + 0x8235, + "GL_R32I", + }, + { + 0x8234, + "GL_R16UI", + }, + { + 0x8237, + "GL_RG8I", + }, + { + 0x8236, + "GL_R32UI", }, { 0x8B69, @@ -1877,10 +2273,22 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_COMPRESSED_TEXTURE_FORMATS", }, { + 0x8DD4, + "GL_UNSIGNED_INT_SAMPLER_CUBE", + }, + { 0x9244, "GL_BIND_GENERATES_RESOURCE_CHROMIUM", }, { + 0x8DD2, + "GL_UNSIGNED_INT_SAMPLER_2D", + }, + { + 0x8DD3, + "GL_UNSIGNED_INT_SAMPLER_3D", + }, + { 0x8DD0, "GL_INT_SAMPLER_BUFFER_EXT", }, @@ -1901,6 +2309,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_FIXED", }, { + 0x140B, + "GL_HALF_FLOAT", + }, + { 0x8008, "GL_MAX_EXT", }, @@ -1913,10 +2325,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_QUERY_RESULT_AVAILABLE_EXT", }, { + 0x8D82, + "GL_RGBA32I", + }, + { 0x8009, "GL_BLEND_EQUATION", }, { + 0x911F, + "GL_BUFFER_ACCESS_FLAGS", + }, + { 0x1401, "GL_UNSIGNED_BYTE", }, @@ -1945,6 +2365,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_FLOAT", }, { + 0x8C1D, + "GL_TEXTURE_BINDING_2D_ARRAY", + }, + { 0x8DDF, "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT", }, @@ -1973,10 +2397,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE", }, { + 0x823A, + "GL_RG16UI", + }, + { 0x8CE4, "GL_COLOR_ATTACHMENT4_EXT", }, { + 0x823B, + "GL_RG32I", + }, + { 0x8CD3, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE", }, @@ -2313,6 +2745,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE_CUBE_MAP_POSITIVE_Y", }, { + 0x8218, + "GL_FRAMEBUFFER_DEFAULT", + }, + { 0x8513, "GL_TEXTURE_CUBE_MAP", }, @@ -2425,6 +2861,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_DEBUG_TYPE_PORTABILITY_KHR", }, { + 0x8DD7, + "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY", + }, + { 0x8B31, "GL_VERTEX_SHADER", }, @@ -2565,6 +3005,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_PERFQUERY_COUNTER_RAW_INTEL", }, { + 0x823C, + "GL_RG32UI", + }, + { + 0x8A29, + "GL_UNIFORM_BUFFER_START", + }, + { + 0x8A28, + "GL_UNIFORM_BUFFER_BINDING", + }, + { 0x92BE, "GL_PRIMITIVE_BOUNDING_BOX_EXT", }, @@ -2593,6 +3045,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT", }, { + 0x906F, + "GL_RGB10_A2UI", + }, + { 0x8E72, "GL_PATCH_VERTICES_EXT", }, @@ -2609,6 +3065,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE4", }, { + 0x821C, + "GL_MINOR_VERSION", + }, + { 0x8E8A, "GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT", }, @@ -2621,6 +3081,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_GUILTY_CONTEXT_RESET_KHR", }, { + 0x8D6B, + "GL_MAX_ELEMENT_INDEX", + }, + { 0x8D6C, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT", }, @@ -2801,6 +3265,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_COLOR_ATTACHMENT14_EXT", }, { + 0x8DC7, + "GL_UNSIGNED_INT_VEC3", + }, + { 0x1701, "GL_PATH_PROJECTION_CHROMIUM", }, @@ -2821,6 +3289,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE_WRAP_T", }, { + 0x8DCB, + "GL_INT_SAMPLER_3D", + }, + { 0x3007, "GL_CLIP_DISTANCE7_APPLE", }, @@ -2893,6 +3365,14 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_STENCIL_FAIL", }, { + 0x8B4A, + "GL_MAX_VERTEX_UNIFORM_COMPONENTS", + }, + { + 0x8B4B, + "GL_MAX_VARYING_COMPONENTS", + }, + { 0x8B4C, "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS", }, @@ -2905,6 +3385,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_SHADER_TYPE", }, { + 0x9122, + "GL_MAX_VERTEX_OUTPUT_COMPONENTS", + }, + { 0x9123, "GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT", }, @@ -2913,10 +3397,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_PERFQUERY_WAIT_INTEL", }, { + 0x9121, + "GL_BUFFER_MAP_OFFSET", + }, + { 0x00004000, "GL_COLOR_BUFFER_BIT", }, { + 0x9125, + "GL_MAX_FRAGMENT_INPUT_COMPONENTS", + }, + { 0x00000010, "GL_TESS_EVALUATION_SHADER_BIT_EXT", }, @@ -2985,10 +3477,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_PERFQUERY_FLUSH_INTEL", }, { + 0x0D03, + "GL_PACK_SKIP_ROWS", + }, + { 0x84F3, "GL_FENCE_STATUS_NV", }, { + 0x88E6, + "GL_STATIC_COPY", + }, + { 0x0B93, "GL_STENCIL_VALUE_MASK", }, @@ -3053,10 +3553,22 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE_BORDER_COLOR_EXT", }, { + 0x8A2D, + "GL_MAX_FRAGMENT_UNIFORM_BLOCKS", + }, + { 0x8B48, "GL_SHADER_OBJECT_EXT", }, { + 0x8B49, + "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS", + }, + { + 0x813A, + "GL_TEXTURE_MIN_LOD", + }, + { 0x8DE1, "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT", }, @@ -3077,12 +3589,16 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM", }, { + 0x8A2F, + "GL_MAX_UNIFORM_BUFFER_BINDINGS", + }, + { 0x20000000, "GL_MULTISAMPLE_BUFFER_BIT5_QCOM", }, { - 64, - "GL_MAILBOX_SIZE_CHROMIUM", + 0x8A2A, + "GL_UNIFORM_BUFFER_SIZE", }, { 0x0DE1, @@ -3105,6 +3621,22 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE_IMMUTABLE_FORMAT_EXT", }, { + 0x8A2B, + "GL_MAX_VERTEX_UNIFORM_BLOCKS", + }, + { + 0x9246, + "GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM", + }, + { + 0x88EC, + "GL_PIXEL_UNPACK_BUFFER", + }, + { + 0x8D8F, + "GL_RGB8I", + }, + { 0x8059, "GL_RGB10_A2_EXT", }, @@ -3117,6 +3649,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_PALETTE4_RGBA4_OES", }, { + 0x88EB, + "GL_PIXEL_PACK_BUFFER", + }, + { 0x8E83, "GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT", }, @@ -3125,6 +3661,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_RGB8_OES", }, { + 0x8CAD, + "GL_DEPTH32F_STENCIL8", + }, + { 0x8052, "GL_RGB10_EXT", }, @@ -3133,6 +3673,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_RENDERBUFFER_SAMPLES_ANGLE", }, { + 0x8CAC, + "GL_DEPTH_COMPONENT32F", + }, + { 0x8057, "GL_RGB5_A1", }, @@ -3141,6 +3685,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_RGBA4", }, { + 0x8232, + "GL_R8UI", + }, + { 0x150A, "GL_INVERT", }, @@ -3181,6 +3729,26 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_FIRST_VERTEX_CONVENTION_EXT", }, { + 0x8E24, + "GL_TRANSFORM_FEEDBACK_ACTIVE", + }, + { + 0x8E45, + "GL_TEXTURE_SWIZZLE_A", + }, + { + 0x8E44, + "GL_TEXTURE_SWIZZLE_B", + }, + { + 0x8E43, + "GL_TEXTURE_SWIZZLE_G", + }, + { + 0x8E42, + "GL_TEXTURE_SWIZZLE_R", + }, + { 0x8D20, "GL_STENCIL_ATTACHMENT", }, @@ -3193,6 +3761,14 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_DEPTH_BUFFER_BIT1_QCOM", }, { + 0x78EC, + "GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM", + }, + { + 0x78FA, + "GL_RGB_YUV_420_CHROMIUM", + }, + { 0x00008000, "GL_COVERAGE_BUFFER_BIT_NV", }, @@ -3233,6 +3809,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_STENCIL_BACK_REF", }, { + 0x80E8, + "GL_MAX_ELEMENTS_VERTICES", + }, + { 0x80CB, "GL_BLEND_SRC_ALPHA", }, @@ -3285,10 +3865,22 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_COMPRESSED_RGBA_ASTC_10x6_KHR", }, { + 0x80E9, + "GL_MAX_ELEMENTS_INDICES", + }, + { 0x8CE5, "GL_COLOR_ATTACHMENT5_EXT", }, { + 0x8C84, + "GL_TRANSFORM_FEEDBACK_BUFFER_START", + }, + { + 0x0BA6, + "GL_PATH_MODELVIEW_MATRIX_CHROMIUM", + }, + { 0x8DC2, "GL_SAMPLER_BUFFER_EXT", }, @@ -3301,10 +3893,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_MIN_SAMPLE_SHADING_VALUE_OES", }, { + 0x8F97, + "GL_RGBA8_SNORM", + }, + { 0x8CE9, "GL_COLOR_ATTACHMENT9_EXT", }, { + 0x8DAD, + "GL_FLOAT_32_UNSIGNED_INT_24_8_REV", + }, + { 0x8B96, "GL_PALETTE8_RGBA8_OES", }, @@ -3313,6 +3913,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_MAX_TEXTURE_IMAGE_UNITS", }, { + 0x8DC6, + "GL_UNSIGNED_INT_VEC2", + }, + { 0x8508, "GL_DECR_WRAP", }, @@ -3409,18 +4013,50 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE_IMAGE_VALID_QCOM", }, { + 0x9278, + "GL_COMPRESSED_RGBA8_ETC2_EAC", + }, + { + 0x9279, + "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC", + }, + { 0x8DA7, "GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT", }, { + 0x9272, + "GL_COMPRESSED_RG11_EAC", + }, + { 0x8DA8, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT", }, { + 0x9270, + "GL_COMPRESSED_R11_EAC", + }, + { + 0x9271, + "GL_COMPRESSED_SIGNED_R11_EAC", + }, + { + 0x9276, + "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2", + }, + { 0x887F, "GL_GEOMETRY_SHADER_INVOCATIONS_EXT", }, { + 0x8A3B, + "GL_UNIFORM_OFFSET", + }, + { + 0x9275, + "GL_COMPRESSED_SRGB8_ETC2", + }, + { 0x84D5, "GL_TEXTURE21", }, @@ -3533,6 +4169,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_PROGRAM_SEPARABLE_EXT", }, { + 0x8257, + "GL_PROGRAM_BINARY_RETRIEVABLE_HINT", + }, + { 0x8256, "GL_RESET_NOTIFICATION_STRATEGY_KHR", }, @@ -3605,6 +4245,14 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_STREAM_DRAW", }, { + 0x88E2, + "GL_STREAM_COPY", + }, + { + 0x88E5, + "GL_STATIC_READ", + }, + { 0x88E4, "GL_STATIC_DRAW", }, @@ -3613,6 +4261,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_COMPRESSED_RGBA_ASTC_5x5x5_OES", }, { + 0x88E9, + "GL_DYNAMIC_READ", + }, + { 0x88E8, "GL_DYNAMIC_DRAW", }, @@ -3633,6 +4285,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_MULTISAMPLE_BUFFER_BIT6_QCOM", }, { + 0x88EA, + "GL_DYNAMIC_COPY", + }, + { 0x9116, "GL_SYNC_FENCE_APPLE", }, @@ -3645,8 +4301,12 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_ETC1_SRGB8_NV", }, { - 0x78EC, - "GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM", + 0x88ED, + "GL_PIXEL_PACK_BUFFER_BINDING", + }, + { + 0x88EF, + "GL_PIXEL_UNPACK_BUFFER_BINDING", }, { 0x93C3, @@ -3717,10 +4377,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_COLOR_CLEAR_VALUE", }, { + 0x8A11, + "GL_UNIFORM_BUFFER", + }, + { 0x8823, "GL_WRITEONLY_RENDERING_QCOM", }, { + 0x78F1, + "GL_MAP_CHROMIUM", + }, + { 0x8824, "GL_MAX_DRAW_BUFFERS_EXT", }, @@ -3788,6 +4456,7 @@ std::string GLES2Util::GetStringAttachment(uint32_t value) { {GL_COLOR_ATTACHMENT0, "GL_COLOR_ATTACHMENT0"}, {GL_DEPTH_ATTACHMENT, "GL_DEPTH_ATTACHMENT"}, {GL_STENCIL_ATTACHMENT, "GL_STENCIL_ATTACHMENT"}, + {GL_DEPTH_STENCIL_ATTACHMENT, "GL_DEPTH_STENCIL_ATTACHMENT"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -3811,9 +4480,23 @@ std::string GLES2Util::GetStringBlitFilter(uint32_t value) { arraysize(string_table), value); } +std::string GLES2Util::GetStringBufferMode(uint32_t value) { + static const EnumToString string_table[] = { + {GL_INTERLEAVED_ATTRIBS, "GL_INTERLEAVED_ATTRIBS"}, + {GL_SEPARATE_ATTRIBS, "GL_SEPARATE_ATTRIBS"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + std::string GLES2Util::GetStringBufferParameter(uint32_t value) { static const EnumToString string_table[] = { - {GL_BUFFER_SIZE, "GL_BUFFER_SIZE"}, {GL_BUFFER_USAGE, "GL_BUFFER_USAGE"}, + {GL_BUFFER_SIZE, "GL_BUFFER_SIZE"}, + {GL_BUFFER_USAGE, "GL_BUFFER_USAGE"}, + {GL_BUFFER_ACCESS_FLAGS, "GL_BUFFER_ACCESS_FLAGS"}, + {GL_BUFFER_MAPPED, "GL_BUFFER_MAPPED"}, + {GL_BUFFER_MAP_LENGTH, "GL_BUFFER_MAP_LENGTH"}, + {GL_BUFFER_MAP_OFFSET, "GL_BUFFER_MAP_OFFSET"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -3823,6 +4506,12 @@ std::string GLES2Util::GetStringBufferTarget(uint32_t value) { static const EnumToString string_table[] = { {GL_ARRAY_BUFFER, "GL_ARRAY_BUFFER"}, {GL_ELEMENT_ARRAY_BUFFER, "GL_ELEMENT_ARRAY_BUFFER"}, + {GL_COPY_READ_BUFFER, "GL_COPY_READ_BUFFER"}, + {GL_COPY_WRITE_BUFFER, "GL_COPY_WRITE_BUFFER"}, + {GL_PIXEL_PACK_BUFFER, "GL_PIXEL_PACK_BUFFER"}, + {GL_PIXEL_UNPACK_BUFFER, "GL_PIXEL_UNPACK_BUFFER"}, + {GL_TRANSFORM_FEEDBACK_BUFFER, "GL_TRANSFORM_FEEDBACK_BUFFER"}, + {GL_UNIFORM_BUFFER, "GL_UNIFORM_BUFFER"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -3833,6 +4522,44 @@ std::string GLES2Util::GetStringBufferUsage(uint32_t value) { {GL_STREAM_DRAW, "GL_STREAM_DRAW"}, {GL_STATIC_DRAW, "GL_STATIC_DRAW"}, {GL_DYNAMIC_DRAW, "GL_DYNAMIC_DRAW"}, + {GL_STREAM_READ, "GL_STREAM_READ"}, + {GL_STREAM_COPY, "GL_STREAM_COPY"}, + {GL_STATIC_READ, "GL_STATIC_READ"}, + {GL_STATIC_COPY, "GL_STATIC_COPY"}, + {GL_DYNAMIC_READ, "GL_DYNAMIC_READ"}, + {GL_DYNAMIC_COPY, "GL_DYNAMIC_COPY"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringBufferfi(uint32_t value) { + static const EnumToString string_table[] = { + {GL_DEPTH_STENCIL, "GL_DEPTH_STENCIL"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringBufferfv(uint32_t value) { + static const EnumToString string_table[] = { + {GL_COLOR, "GL_COLOR"}, {GL_DEPTH, "GL_DEPTH"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringBufferiv(uint32_t value) { + static const EnumToString string_table[] = { + {GL_COLOR, "GL_COLOR"}, {GL_STENCIL, "GL_STENCIL"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringBufferuiv(uint32_t value) { + static const EnumToString string_table[] = { + {GL_COLOR, "GL_COLOR"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -3849,6 +4576,8 @@ std::string GLES2Util::GetStringCapability(uint32_t value) { {GL_SAMPLE_COVERAGE, "GL_SAMPLE_COVERAGE"}, {GL_SCISSOR_TEST, "GL_SCISSOR_TEST"}, {GL_STENCIL_TEST, "GL_STENCIL_TEST"}, + {GL_RASTERIZER_DISCARD, "GL_RASTERIZER_DISCARD"}, + {GL_PRIMITIVE_RESTART_FIXED_INDEX, "GL_PRIMITIVE_RESTART_FIXED_INDEX"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -3870,7 +4599,23 @@ std::string GLES2Util::GetStringCmpFunction(uint32_t value) { } std::string GLES2Util::GetStringCompressedTextureFormat(uint32_t value) { - return GLES2Util::GetQualifiedEnumString(NULL, 0, value); + static const EnumToString string_table[] = { + {GL_COMPRESSED_R11_EAC, "GL_COMPRESSED_R11_EAC"}, + {GL_COMPRESSED_SIGNED_R11_EAC, "GL_COMPRESSED_SIGNED_R11_EAC"}, + {GL_COMPRESSED_RG11_EAC, "GL_COMPRESSED_RG11_EAC"}, + {GL_COMPRESSED_SIGNED_RG11_EAC, "GL_COMPRESSED_SIGNED_RG11_EAC"}, + {GL_COMPRESSED_RGB8_ETC2, "GL_COMPRESSED_RGB8_ETC2"}, + {GL_COMPRESSED_SRGB8_ETC2, "GL_COMPRESSED_SRGB8_ETC2"}, + {GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"}, + {GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"}, + {GL_COMPRESSED_RGBA8_ETC2_EAC, "GL_COMPRESSED_RGBA8_ETC2_EAC"}, + {GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, + "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); } std::string GLES2Util::GetStringDrawMode(uint32_t value) { @@ -3913,6 +4658,8 @@ std::string GLES2Util::GetStringEquation(uint32_t value) { {GL_FUNC_ADD, "GL_FUNC_ADD"}, {GL_FUNC_SUBTRACT, "GL_FUNC_SUBTRACT"}, {GL_FUNC_REVERSE_SUBTRACT, "GL_FUNC_REVERSE_SUBTRACT"}, + {GL_MIN, "GL_MIN"}, + {GL_MAX, "GL_MAX"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -3946,6 +4693,24 @@ std::string GLES2Util::GetStringFrameBufferParameter(uint32_t value) { "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL"}, {GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE"}, + {GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, + "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE"}, + {GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, + "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE"}, + {GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, + "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE"}, + {GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, + "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE"}, + {GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, + "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE"}, + {GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, + "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE"}, + {GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, + "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE"}, + {GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, + "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING"}, + {GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, + "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -3954,6 +4719,8 @@ std::string GLES2Util::GetStringFrameBufferParameter(uint32_t value) { std::string GLES2Util::GetStringFrameBufferTarget(uint32_t value) { static const EnumToString string_table[] = { {GL_FRAMEBUFFER, "GL_FRAMEBUFFER"}, + {GL_DRAW_FRAMEBUFFER, "GL_DRAW_FRAMEBUFFER"}, + {GL_READ_FRAMEBUFFER, "GL_READ_FRAMEBUFFER"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4057,6 +4824,95 @@ std::string GLES2Util::GetStringGLState(uint32_t value) { {GL_SAMPLE_COVERAGE, "GL_SAMPLE_COVERAGE"}, {GL_SCISSOR_TEST, "GL_SCISSOR_TEST"}, {GL_STENCIL_TEST, "GL_STENCIL_TEST"}, + {GL_RASTERIZER_DISCARD, "GL_RASTERIZER_DISCARD"}, + {GL_PRIMITIVE_RESTART_FIXED_INDEX, "GL_PRIMITIVE_RESTART_FIXED_INDEX"}, + {GL_COPY_READ_BUFFER_BINDING, "GL_COPY_READ_BUFFER_BINDING"}, + {GL_COPY_WRITE_BUFFER_BINDING, "GL_COPY_WRITE_BUFFER_BINDING"}, + {GL_DRAW_BUFFER0, "GL_DRAW_BUFFER0"}, + {GL_DRAW_BUFFER1, "GL_DRAW_BUFFER1"}, + {GL_DRAW_BUFFER2, "GL_DRAW_BUFFER2"}, + {GL_DRAW_BUFFER3, "GL_DRAW_BUFFER3"}, + {GL_DRAW_BUFFER4, "GL_DRAW_BUFFER4"}, + {GL_DRAW_BUFFER5, "GL_DRAW_BUFFER5"}, + {GL_DRAW_BUFFER6, "GL_DRAW_BUFFER6"}, + {GL_DRAW_BUFFER7, "GL_DRAW_BUFFER7"}, + {GL_DRAW_BUFFER8, "GL_DRAW_BUFFER8"}, + {GL_DRAW_BUFFER9, "GL_DRAW_BUFFER9"}, + {GL_DRAW_BUFFER10, "GL_DRAW_BUFFER10"}, + {GL_DRAW_BUFFER11, "GL_DRAW_BUFFER11"}, + {GL_DRAW_BUFFER12, "GL_DRAW_BUFFER12"}, + {GL_DRAW_BUFFER13, "GL_DRAW_BUFFER13"}, + {GL_DRAW_BUFFER14, "GL_DRAW_BUFFER14"}, + {GL_DRAW_BUFFER15, "GL_DRAW_BUFFER15"}, + {GL_DRAW_FRAMEBUFFER_BINDING, "GL_DRAW_FRAMEBUFFER_BINDING"}, + {GL_FRAGMENT_SHADER_DERIVATIVE_HINT, + "GL_FRAGMENT_SHADER_DERIVATIVE_HINT"}, + {GL_MAJOR_VERSION, "GL_MAJOR_VERSION"}, + {GL_MAX_3D_TEXTURE_SIZE, "GL_MAX_3D_TEXTURE_SIZE"}, + {GL_MAX_ARRAY_TEXTURE_LAYERS, "GL_MAX_ARRAY_TEXTURE_LAYERS"}, + {GL_MAX_COLOR_ATTACHMENTS, "GL_MAX_COLOR_ATTACHMENTS"}, + {GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, + "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS"}, + {GL_MAX_COMBINED_UNIFORM_BLOCKS, "GL_MAX_COMBINED_UNIFORM_BLOCKS"}, + {GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, + "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS"}, + {GL_MAX_DRAW_BUFFERS, "GL_MAX_DRAW_BUFFERS"}, + {GL_MAX_ELEMENT_INDEX, "GL_MAX_ELEMENT_INDEX"}, + {GL_MAX_ELEMENTS_INDICES, "GL_MAX_ELEMENTS_INDICES"}, + {GL_MAX_ELEMENTS_VERTICES, "GL_MAX_ELEMENTS_VERTICES"}, + {GL_MAX_FRAGMENT_INPUT_COMPONENTS, "GL_MAX_FRAGMENT_INPUT_COMPONENTS"}, + {GL_MAX_FRAGMENT_UNIFORM_BLOCKS, "GL_MAX_FRAGMENT_UNIFORM_BLOCKS"}, + {GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, + "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS"}, + {GL_MAX_PROGRAM_TEXEL_OFFSET, "GL_MAX_PROGRAM_TEXEL_OFFSET"}, + {GL_MAX_SAMPLES, "GL_MAX_SAMPLES"}, + {GL_MAX_SERVER_WAIT_TIMEOUT, "GL_MAX_SERVER_WAIT_TIMEOUT"}, + {GL_MAX_TEXTURE_LOD_BIAS, "GL_MAX_TEXTURE_LOD_BIAS"}, + {GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, + "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS"}, + {GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, + "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS"}, + {GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, + "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS"}, + {GL_MAX_UNIFORM_BLOCK_SIZE, "GL_MAX_UNIFORM_BLOCK_SIZE"}, + {GL_MAX_UNIFORM_BUFFER_BINDINGS, "GL_MAX_UNIFORM_BUFFER_BINDINGS"}, + {GL_MAX_VARYING_COMPONENTS, "GL_MAX_VARYING_COMPONENTS"}, + {GL_MAX_VERTEX_OUTPUT_COMPONENTS, "GL_MAX_VERTEX_OUTPUT_COMPONENTS"}, + {GL_MAX_VERTEX_UNIFORM_BLOCKS, "GL_MAX_VERTEX_UNIFORM_BLOCKS"}, + {GL_MAX_VERTEX_UNIFORM_COMPONENTS, "GL_MAX_VERTEX_UNIFORM_COMPONENTS"}, + {GL_MIN_PROGRAM_TEXEL_OFFSET, "GL_MIN_PROGRAM_TEXEL_OFFSET"}, + {GL_MINOR_VERSION, "GL_MINOR_VERSION"}, + {GL_NUM_EXTENSIONS, "GL_NUM_EXTENSIONS"}, + {GL_NUM_PROGRAM_BINARY_FORMATS, "GL_NUM_PROGRAM_BINARY_FORMATS"}, + {GL_PACK_ROW_LENGTH, "GL_PACK_ROW_LENGTH"}, + {GL_PACK_SKIP_PIXELS, "GL_PACK_SKIP_PIXELS"}, + {GL_PACK_SKIP_ROWS, "GL_PACK_SKIP_ROWS"}, + {GL_PIXEL_PACK_BUFFER_BINDING, "GL_PIXEL_PACK_BUFFER_BINDING"}, + {GL_PIXEL_UNPACK_BUFFER_BINDING, "GL_PIXEL_UNPACK_BUFFER_BINDING"}, + {GL_PROGRAM_BINARY_FORMATS, "GL_PROGRAM_BINARY_FORMATS"}, + {GL_READ_BUFFER, "GL_READ_BUFFER"}, + {GL_READ_FRAMEBUFFER_BINDING, "GL_READ_FRAMEBUFFER_BINDING"}, + {GL_SAMPLER_BINDING, "GL_SAMPLER_BINDING"}, + {GL_TEXTURE_BINDING_2D_ARRAY, "GL_TEXTURE_BINDING_2D_ARRAY"}, + {GL_TEXTURE_BINDING_3D, "GL_TEXTURE_BINDING_3D"}, + {GL_TRANSFORM_FEEDBACK_BINDING, "GL_TRANSFORM_FEEDBACK_BINDING"}, + {GL_TRANSFORM_FEEDBACK_ACTIVE, "GL_TRANSFORM_FEEDBACK_ACTIVE"}, + {GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, + "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING"}, + {GL_TRANSFORM_FEEDBACK_PAUSED, "GL_TRANSFORM_FEEDBACK_PAUSED"}, + {GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE"}, + {GL_TRANSFORM_FEEDBACK_BUFFER_START, + "GL_TRANSFORM_FEEDBACK_BUFFER_START"}, + {GL_UNIFORM_BUFFER_BINDING, "GL_UNIFORM_BUFFER_BINDING"}, + {GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, + "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT"}, + {GL_UNIFORM_BUFFER_SIZE, "GL_UNIFORM_BUFFER_SIZE"}, + {GL_UNIFORM_BUFFER_START, "GL_UNIFORM_BUFFER_START"}, + {GL_UNPACK_IMAGE_HEIGHT, "GL_UNPACK_IMAGE_HEIGHT"}, + {GL_UNPACK_ROW_LENGTH, "GL_UNPACK_ROW_LENGTH"}, + {GL_UNPACK_SKIP_IMAGES, "GL_UNPACK_SKIP_IMAGES"}, + {GL_UNPACK_SKIP_PIXELS, "GL_UNPACK_SKIP_PIXELS"}, + {GL_UNPACK_SKIP_ROWS, "GL_UNPACK_SKIP_ROWS"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4076,6 +4932,8 @@ std::string GLES2Util::GetStringGetTexParamTarget(uint32_t value) { static const EnumToString string_table[] = { {GL_TEXTURE_2D, "GL_TEXTURE_2D"}, {GL_TEXTURE_CUBE_MAP, "GL_TEXTURE_CUBE_MAP"}, + {GL_TEXTURE_2D_ARRAY, "GL_TEXTURE_2D_ARRAY"}, + {GL_TEXTURE_3D, "GL_TEXTURE_3D"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4094,6 +4952,8 @@ std::string GLES2Util::GetStringHintMode(uint32_t value) { std::string GLES2Util::GetStringHintTarget(uint32_t value) { static const EnumToString string_table[] = { {GL_GENERATE_MIPMAP_HINT, "GL_GENERATE_MIPMAP_HINT"}, + {GL_FRAGMENT_SHADER_DERIVATIVE_HINT, + "GL_FRAGMENT_SHADER_DERIVATIVE_HINT"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4101,7 +4961,9 @@ std::string GLES2Util::GetStringHintTarget(uint32_t value) { std::string GLES2Util::GetStringImageInternalFormat(uint32_t value) { static const EnumToString string_table[] = { - {GL_RGB, "GL_RGB"}, {GL_RGBA, "GL_RGBA"}, + {GL_RGB, "GL_RGB"}, + {GL_RGB_YUV_420_CHROMIUM, "GL_RGB_YUV_420_CHROMIUM"}, + {GL_RGBA, "GL_RGBA"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4120,6 +4982,61 @@ std::string GLES2Util::GetStringIndexType(uint32_t value) { static const EnumToString string_table[] = { {GL_UNSIGNED_BYTE, "GL_UNSIGNED_BYTE"}, {GL_UNSIGNED_SHORT, "GL_UNSIGNED_SHORT"}, + {GL_UNSIGNED_INT, "GL_UNSIGNED_INT"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringIndexedBufferTarget(uint32_t value) { + static const EnumToString string_table[] = { + {GL_TRANSFORM_FEEDBACK_BUFFER, "GL_TRANSFORM_FEEDBACK_BUFFER"}, + {GL_UNIFORM_BUFFER, "GL_UNIFORM_BUFFER"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringIndexedGLState(uint32_t value) { + static const EnumToString string_table[] = { + {GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, + "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING"}, + {GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE"}, + {GL_TRANSFORM_FEEDBACK_BUFFER_START, + "GL_TRANSFORM_FEEDBACK_BUFFER_START"}, + {GL_UNIFORM_BUFFER_BINDING, "GL_UNIFORM_BUFFER_BINDING"}, + {GL_UNIFORM_BUFFER_SIZE, "GL_UNIFORM_BUFFER_SIZE"}, + {GL_UNIFORM_BUFFER_START, "GL_UNIFORM_BUFFER_START"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringInternalFormatParameter(uint32_t value) { + static const EnumToString string_table[] = { + {GL_NUM_SAMPLE_COUNTS, "GL_NUM_SAMPLE_COUNTS"}, + {GL_SAMPLES, "GL_SAMPLES"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringInvalidateFrameBufferTarget(uint32_t value) { + static const EnumToString string_table[] = { + {GL_FRAMEBUFFER, "GL_FRAMEBUFFER"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringMapBufferAccess(uint32_t value) { + static const EnumToString string_table[] = { + {GL_MAP_READ_BIT, "GL_MAP_READ_BIT"}, + {GL_MAP_WRITE_BIT, "GL_MAP_WRITE_BIT"}, + {GL_MAP_INVALIDATE_RANGE_BIT, "GL_MAP_INVALIDATE_RANGE_BIT"}, + {GL_MAP_INVALIDATE_BUFFER_BIT, "GL_MAP_INVALIDATE_BUFFER_BIT"}, + {GL_MAP_FLUSH_EXPLICIT_BIT, "GL_MAP_FLUSH_EXPLICIT_BIT"}, + {GL_MAP_UNSYNCHRONIZED_BIT, "GL_MAP_UNSYNCHRONIZED_BIT"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4143,6 +5060,14 @@ std::string GLES2Util::GetStringPixelStore(uint32_t value) { "GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM"}, {GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, "GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM"}, + {GL_PACK_ROW_LENGTH, "GL_PACK_ROW_LENGTH"}, + {GL_PACK_SKIP_PIXELS, "GL_PACK_SKIP_PIXELS"}, + {GL_PACK_SKIP_ROWS, "GL_PACK_SKIP_ROWS"}, + {GL_UNPACK_ROW_LENGTH, "GL_UNPACK_ROW_LENGTH"}, + {GL_UNPACK_IMAGE_HEIGHT, "GL_UNPACK_IMAGE_HEIGHT"}, + {GL_UNPACK_SKIP_PIXELS, "GL_UNPACK_SKIP_PIXELS"}, + {GL_UNPACK_SKIP_ROWS, "GL_UNPACK_SKIP_ROWS"}, + {GL_UNPACK_SKIP_IMAGES, "GL_UNPACK_SKIP_IMAGES"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4154,6 +5079,18 @@ std::string GLES2Util::GetStringPixelType(uint32_t value) { {GL_UNSIGNED_SHORT_5_6_5, "GL_UNSIGNED_SHORT_5_6_5"}, {GL_UNSIGNED_SHORT_4_4_4_4, "GL_UNSIGNED_SHORT_4_4_4_4"}, {GL_UNSIGNED_SHORT_5_5_5_1, "GL_UNSIGNED_SHORT_5_5_5_1"}, + {GL_BYTE, "GL_BYTE"}, + {GL_UNSIGNED_SHORT, "GL_UNSIGNED_SHORT"}, + {GL_SHORT, "GL_SHORT"}, + {GL_UNSIGNED_INT, "GL_UNSIGNED_INT"}, + {GL_INT, "GL_INT"}, + {GL_HALF_FLOAT, "GL_HALF_FLOAT"}, + {GL_FLOAT, "GL_FLOAT"}, + {GL_UNSIGNED_INT_2_10_10_10_REV, "GL_UNSIGNED_INT_2_10_10_10_REV"}, + {GL_UNSIGNED_INT_10F_11F_11F_REV, "GL_UNSIGNED_INT_10F_11F_11F_REV"}, + {GL_UNSIGNED_INT_5_9_9_9_REV, "GL_UNSIGNED_INT_5_9_9_9_REV"}, + {GL_UNSIGNED_INT_24_8, "GL_UNSIGNED_INT_24_8"}, + {GL_FLOAT_32_UNSIGNED_INT_24_8_REV, "GL_FLOAT_32_UNSIGNED_INT_24_8_REV"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4170,6 +5107,13 @@ std::string GLES2Util::GetStringProgramParameter(uint32_t value) { {GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH"}, {GL_ACTIVE_UNIFORMS, "GL_ACTIVE_UNIFORMS"}, {GL_ACTIVE_UNIFORM_MAX_LENGTH, "GL_ACTIVE_UNIFORM_MAX_LENGTH"}, + {GL_ACTIVE_UNIFORM_BLOCKS, "GL_ACTIVE_UNIFORM_BLOCKS"}, + {GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, + "GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH"}, + {GL_TRANSFORM_FEEDBACK_BUFFER_MODE, "GL_TRANSFORM_FEEDBACK_BUFFER_MODE"}, + {GL_TRANSFORM_FEEDBACK_VARYINGS, "GL_TRANSFORM_FEEDBACK_VARYINGS"}, + {GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, + "GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4211,7 +5155,10 @@ std::string GLES2Util::GetStringQueryTarget(uint32_t value) { std::string GLES2Util::GetStringReadPixelFormat(uint32_t value) { static const EnumToString string_table[] = { - {GL_ALPHA, "GL_ALPHA"}, {GL_RGB, "GL_RGB"}, {GL_RGBA, "GL_RGBA"}, + {GL_ALPHA, "GL_ALPHA"}, + {GL_RGB, "GL_RGB"}, + {GL_RGBA, "GL_RGBA"}, + {GL_RGBA_INTEGER, "GL_RGBA_INTEGER"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4223,6 +5170,9 @@ std::string GLES2Util::GetStringReadPixelType(uint32_t value) { {GL_UNSIGNED_SHORT_5_6_5, "GL_UNSIGNED_SHORT_5_6_5"}, {GL_UNSIGNED_SHORT_4_4_4_4, "GL_UNSIGNED_SHORT_4_4_4_4"}, {GL_UNSIGNED_SHORT_5_5_5_1, "GL_UNSIGNED_SHORT_5_5_5_1"}, + {GL_UNSIGNED_INT, "GL_UNSIGNED_INT"}, + {GL_INT, "GL_INT"}, + {GL_FLOAT, "GL_FLOAT"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4235,6 +5185,35 @@ std::string GLES2Util::GetStringRenderBufferFormat(uint32_t value) { {GL_RGB5_A1, "GL_RGB5_A1"}, {GL_DEPTH_COMPONENT16, "GL_DEPTH_COMPONENT16"}, {GL_STENCIL_INDEX8, "GL_STENCIL_INDEX8"}, + {GL_R8, "GL_R8"}, + {GL_R8UI, "GL_R8UI"}, + {GL_R8I, "GL_R8I"}, + {GL_R16UI, "GL_R16UI"}, + {GL_R16I, "GL_R16I"}, + {GL_R32UI, "GL_R32UI"}, + {GL_R32I, "GL_R32I"}, + {GL_RG8, "GL_RG8"}, + {GL_RG8UI, "GL_RG8UI"}, + {GL_RG8I, "GL_RG8I"}, + {GL_RG16UI, "GL_RG16UI"}, + {GL_RG16I, "GL_RG16I"}, + {GL_RG32UI, "GL_RG32UI"}, + {GL_RG32I, "GL_RG32I"}, + {GL_RGB8, "GL_RGB8"}, + {GL_RGBA8, "GL_RGBA8"}, + {GL_SRGB8_ALPHA8, "GL_SRGB8_ALPHA8"}, + {GL_RGB10_A2, "GL_RGB10_A2"}, + {GL_RGBA8UI, "GL_RGBA8UI"}, + {GL_RGBA8I, "GL_RGBA8I"}, + {GL_RGB10_A2UI, "GL_RGB10_A2UI"}, + {GL_RGBA16UI, "GL_RGBA16UI"}, + {GL_RGBA16I, "GL_RGBA16I"}, + {GL_RGBA32UI, "GL_RGBA32UI"}, + {GL_RGBA32I, "GL_RGBA32I"}, + {GL_DEPTH_COMPONENT24, "GL_DEPTH_COMPONENT24"}, + {GL_DEPTH_COMPONENT32F, "GL_DEPTH_COMPONENT32F"}, + {GL_DEPTH24_STENCIL8, "GL_DEPTH24_STENCIL8"}, + {GL_DEPTH32F_STENCIL8, "GL_DEPTH32F_STENCIL8"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4251,6 +5230,7 @@ std::string GLES2Util::GetStringRenderBufferParameter(uint32_t value) { {GL_RENDERBUFFER_WIDTH, "GL_RENDERBUFFER_WIDTH"}, {GL_RENDERBUFFER_HEIGHT, "GL_RENDERBUFFER_HEIGHT"}, {GL_RENDERBUFFER_INTERNAL_FORMAT, "GL_RENDERBUFFER_INTERNAL_FORMAT"}, + {GL_RENDERBUFFER_SAMPLES, "GL_RENDERBUFFER_SAMPLES"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4274,6 +5254,22 @@ std::string GLES2Util::GetStringResetStatus(uint32_t value) { arraysize(string_table), value); } +std::string GLES2Util::GetStringSamplerParameter(uint32_t value) { + static const EnumToString string_table[] = { + {GL_TEXTURE_MAG_FILTER, "GL_TEXTURE_MAG_FILTER"}, + {GL_TEXTURE_MIN_FILTER, "GL_TEXTURE_MIN_FILTER"}, + {GL_TEXTURE_MIN_LOD, "GL_TEXTURE_MIN_LOD"}, + {GL_TEXTURE_MAX_LOD, "GL_TEXTURE_MAX_LOD"}, + {GL_TEXTURE_WRAP_S, "GL_TEXTURE_WRAP_S"}, + {GL_TEXTURE_WRAP_T, "GL_TEXTURE_WRAP_T"}, + {GL_TEXTURE_WRAP_R, "GL_TEXTURE_WRAP_R"}, + {GL_TEXTURE_COMPARE_MODE, "GL_TEXTURE_COMPARE_MODE"}, + {GL_TEXTURE_COMPARE_FUNC, "GL_TEXTURE_COMPARE_FUNC"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + std::string GLES2Util::GetStringShaderBinaryFormat(uint32_t value) { return GLES2Util::GetQualifiedEnumString(NULL, 0, value); } @@ -4371,10 +5367,64 @@ std::string GLES2Util::GetStringSubscriptionTarget(uint32_t value) { arraysize(string_table), value); } +std::string GLES2Util::GetStringSyncCondition(uint32_t value) { + static const EnumToString string_table[] = { + {GL_SYNC_GPU_COMMANDS_COMPLETE, "GL_SYNC_GPU_COMMANDS_COMPLETE"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringSyncParameter(uint32_t value) { + static const EnumToString string_table[] = { + {GL_SYNC_STATUS, "GL_SYNC_STATUS"}, + {GL_OBJECT_TYPE, "GL_OBJECT_TYPE"}, + {GL_SYNC_CONDITION, "GL_SYNC_CONDITION"}, + {GL_SYNC_FLAGS, "GL_SYNC_FLAGS"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringTexture3DTarget(uint32_t value) { + static const EnumToString string_table[] = { + {GL_TEXTURE_3D, "GL_TEXTURE_3D"}, + {GL_TEXTURE_2D_ARRAY, "GL_TEXTURE_2D_ARRAY"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + std::string GLES2Util::GetStringTextureBindTarget(uint32_t value) { static const EnumToString string_table[] = { {GL_TEXTURE_2D, "GL_TEXTURE_2D"}, {GL_TEXTURE_CUBE_MAP, "GL_TEXTURE_CUBE_MAP"}, + {GL_TEXTURE_3D, "GL_TEXTURE_3D"}, + {GL_TEXTURE_2D_ARRAY, "GL_TEXTURE_2D_ARRAY"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringTextureCompareFunc(uint32_t value) { + static const EnumToString string_table[] = { + {GL_LEQUAL, "GL_LEQUAL"}, + {GL_GEQUAL, "GL_GEQUAL"}, + {GL_LESS, "GL_LESS"}, + {GL_GREATER, "GL_GREATER"}, + {GL_EQUAL, "GL_EQUAL"}, + {GL_NOTEQUAL, "GL_NOTEQUAL"}, + {GL_ALWAYS, "GL_ALWAYS"}, + {GL_NEVER, "GL_NEVER"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringTextureCompareMode(uint32_t value) { + static const EnumToString string_table[] = { + {GL_NONE, "GL_NONE"}, + {GL_COMPARE_REF_TO_TEXTURE, "GL_COMPARE_REF_TO_TEXTURE"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4387,6 +5437,14 @@ std::string GLES2Util::GetStringTextureFormat(uint32_t value) { {GL_LUMINANCE_ALPHA, "GL_LUMINANCE_ALPHA"}, {GL_RGB, "GL_RGB"}, {GL_RGBA, "GL_RGBA"}, + {GL_RED, "GL_RED"}, + {GL_RED_INTEGER, "GL_RED_INTEGER"}, + {GL_RG, "GL_RG"}, + {GL_RG_INTEGER, "GL_RG_INTEGER"}, + {GL_RGB_INTEGER, "GL_RGB_INTEGER"}, + {GL_RGBA_INTEGER, "GL_RGBA_INTEGER"}, + {GL_DEPTH_COMPONENT, "GL_DEPTH_COMPONENT"}, + {GL_DEPTH_STENCIL, "GL_DEPTH_STENCIL"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4399,6 +5457,60 @@ std::string GLES2Util::GetStringTextureInternalFormat(uint32_t value) { {GL_LUMINANCE_ALPHA, "GL_LUMINANCE_ALPHA"}, {GL_RGB, "GL_RGB"}, {GL_RGBA, "GL_RGBA"}, + {GL_R8, "GL_R8"}, + {GL_R8_SNORM, "GL_R8_SNORM"}, + {GL_R16F, "GL_R16F"}, + {GL_R32F, "GL_R32F"}, + {GL_R8UI, "GL_R8UI"}, + {GL_R8I, "GL_R8I"}, + {GL_R16UI, "GL_R16UI"}, + {GL_R16I, "GL_R16I"}, + {GL_R32UI, "GL_R32UI"}, + {GL_R32I, "GL_R32I"}, + {GL_RG8, "GL_RG8"}, + {GL_RG8_SNORM, "GL_RG8_SNORM"}, + {GL_RG16F, "GL_RG16F"}, + {GL_RG32F, "GL_RG32F"}, + {GL_RG8UI, "GL_RG8UI"}, + {GL_RG8I, "GL_RG8I"}, + {GL_RG16UI, "GL_RG16UI"}, + {GL_RG16I, "GL_RG16I"}, + {GL_RG32UI, "GL_RG32UI"}, + {GL_RG32I, "GL_RG32I"}, + {GL_RGB8, "GL_RGB8"}, + {GL_SRGB8, "GL_SRGB8"}, + {GL_RGB565, "GL_RGB565"}, + {GL_RGB8_SNORM, "GL_RGB8_SNORM"}, + {GL_R11F_G11F_B10F, "GL_R11F_G11F_B10F"}, + {GL_RGB9_E5, "GL_RGB9_E5"}, + {GL_RGB16F, "GL_RGB16F"}, + {GL_RGB32F, "GL_RGB32F"}, + {GL_RGB8UI, "GL_RGB8UI"}, + {GL_RGB8I, "GL_RGB8I"}, + {GL_RGB16UI, "GL_RGB16UI"}, + {GL_RGB16I, "GL_RGB16I"}, + {GL_RGB32UI, "GL_RGB32UI"}, + {GL_RGB32I, "GL_RGB32I"}, + {GL_RGBA8, "GL_RGBA8"}, + {GL_SRGB8_ALPHA8, "GL_SRGB8_ALPHA8"}, + {GL_RGBA8_SNORM, "GL_RGBA8_SNORM"}, + {GL_RGB5_A1, "GL_RGB5_A1"}, + {GL_RGBA4, "GL_RGBA4"}, + {GL_RGB10_A2, "GL_RGB10_A2"}, + {GL_RGBA16F, "GL_RGBA16F"}, + {GL_RGBA32F, "GL_RGBA32F"}, + {GL_RGBA8UI, "GL_RGBA8UI"}, + {GL_RGBA8I, "GL_RGBA8I"}, + {GL_RGB10_A2UI, "GL_RGB10_A2UI"}, + {GL_RGBA16UI, "GL_RGBA16UI"}, + {GL_RGBA16I, "GL_RGBA16I"}, + {GL_RGBA32UI, "GL_RGBA32UI"}, + {GL_RGBA32I, "GL_RGBA32I"}, + {GL_DEPTH_COMPONENT16, "GL_DEPTH_COMPONENT16"}, + {GL_DEPTH_COMPONENT24, "GL_DEPTH_COMPONENT24"}, + {GL_DEPTH_COMPONENT32F, "GL_DEPTH_COMPONENT32F"}, + {GL_DEPTH24_STENCIL8, "GL_DEPTH24_STENCIL8"}, + {GL_DEPTH32F_STENCIL8, "GL_DEPTH32F_STENCIL8"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4414,6 +5526,68 @@ std::string GLES2Util::GetStringTextureInternalFormatStorage(uint32_t value) { {GL_LUMINANCE8_ALPHA8_EXT, "GL_LUMINANCE8_ALPHA8_EXT"}, {GL_RGB8_OES, "GL_RGB8_OES"}, {GL_RGBA8_OES, "GL_RGBA8_OES"}, + {GL_R8, "GL_R8"}, + {GL_R8_SNORM, "GL_R8_SNORM"}, + {GL_R16F, "GL_R16F"}, + {GL_R32F, "GL_R32F"}, + {GL_R8UI, "GL_R8UI"}, + {GL_R8I, "GL_R8I"}, + {GL_R16UI, "GL_R16UI"}, + {GL_R16I, "GL_R16I"}, + {GL_R32UI, "GL_R32UI"}, + {GL_R32I, "GL_R32I"}, + {GL_RG8, "GL_RG8"}, + {GL_RG8_SNORM, "GL_RG8_SNORM"}, + {GL_RG16F, "GL_RG16F"}, + {GL_RG32F, "GL_RG32F"}, + {GL_RG8UI, "GL_RG8UI"}, + {GL_RG8I, "GL_RG8I"}, + {GL_RG16UI, "GL_RG16UI"}, + {GL_RG16I, "GL_RG16I"}, + {GL_RG32UI, "GL_RG32UI"}, + {GL_RG32I, "GL_RG32I"}, + {GL_SRGB8, "GL_SRGB8"}, + {GL_RGB8_SNORM, "GL_RGB8_SNORM"}, + {GL_R11F_G11F_B10F, "GL_R11F_G11F_B10F"}, + {GL_RGB9_E5, "GL_RGB9_E5"}, + {GL_RGB16F, "GL_RGB16F"}, + {GL_RGB32F, "GL_RGB32F"}, + {GL_RGB8UI, "GL_RGB8UI"}, + {GL_RGB8I, "GL_RGB8I"}, + {GL_RGB16UI, "GL_RGB16UI"}, + {GL_RGB16I, "GL_RGB16I"}, + {GL_RGB32UI, "GL_RGB32UI"}, + {GL_RGB32I, "GL_RGB32I"}, + {GL_SRGB8_ALPHA8, "GL_SRGB8_ALPHA8"}, + {GL_RGBA8_SNORM, "GL_RGBA8_SNORM"}, + {GL_RGB10_A2, "GL_RGB10_A2"}, + {GL_RGBA16F, "GL_RGBA16F"}, + {GL_RGBA32F, "GL_RGBA32F"}, + {GL_RGBA8UI, "GL_RGBA8UI"}, + {GL_RGBA8I, "GL_RGBA8I"}, + {GL_RGB10_A2UI, "GL_RGB10_A2UI"}, + {GL_RGBA16UI, "GL_RGBA16UI"}, + {GL_RGBA16I, "GL_RGBA16I"}, + {GL_RGBA32UI, "GL_RGBA32UI"}, + {GL_RGBA32I, "GL_RGBA32I"}, + {GL_DEPTH_COMPONENT16, "GL_DEPTH_COMPONENT16"}, + {GL_DEPTH_COMPONENT24, "GL_DEPTH_COMPONENT24"}, + {GL_DEPTH_COMPONENT32F, "GL_DEPTH_COMPONENT32F"}, + {GL_DEPTH24_STENCIL8, "GL_DEPTH24_STENCIL8"}, + {GL_DEPTH32F_STENCIL8, "GL_DEPTH32F_STENCIL8"}, + {GL_COMPRESSED_R11_EAC, "GL_COMPRESSED_R11_EAC"}, + {GL_COMPRESSED_SIGNED_R11_EAC, "GL_COMPRESSED_SIGNED_R11_EAC"}, + {GL_COMPRESSED_RG11_EAC, "GL_COMPRESSED_RG11_EAC"}, + {GL_COMPRESSED_SIGNED_RG11_EAC, "GL_COMPRESSED_SIGNED_RG11_EAC"}, + {GL_COMPRESSED_RGB8_ETC2, "GL_COMPRESSED_RGB8_ETC2"}, + {GL_COMPRESSED_SRGB8_ETC2, "GL_COMPRESSED_SRGB8_ETC2"}, + {GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"}, + {GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"}, + {GL_COMPRESSED_RGBA8_ETC2_EAC, "GL_COMPRESSED_RGBA8_ETC2_EAC"}, + {GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, + "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4447,6 +5621,15 @@ std::string GLES2Util::GetStringTextureParameter(uint32_t value) { {GL_TEXTURE_POOL_CHROMIUM, "GL_TEXTURE_POOL_CHROMIUM"}, {GL_TEXTURE_WRAP_S, "GL_TEXTURE_WRAP_S"}, {GL_TEXTURE_WRAP_T, "GL_TEXTURE_WRAP_T"}, + {GL_TEXTURE_BASE_LEVEL, "GL_TEXTURE_BASE_LEVEL"}, + {GL_TEXTURE_COMPARE_FUNC, "GL_TEXTURE_COMPARE_FUNC"}, + {GL_TEXTURE_COMPARE_MODE, "GL_TEXTURE_COMPARE_MODE"}, + {GL_TEXTURE_IMMUTABLE_FORMAT, "GL_TEXTURE_IMMUTABLE_FORMAT"}, + {GL_TEXTURE_IMMUTABLE_LEVELS, "GL_TEXTURE_IMMUTABLE_LEVELS"}, + {GL_TEXTURE_MAX_LEVEL, "GL_TEXTURE_MAX_LEVEL"}, + {GL_TEXTURE_MAX_LOD, "GL_TEXTURE_MAX_LOD"}, + {GL_TEXTURE_MIN_LOD, "GL_TEXTURE_MIN_LOD"}, + {GL_TEXTURE_WRAP_R, "GL_TEXTURE_WRAP_R"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4495,6 +5678,56 @@ std::string GLES2Util::GetStringTextureWrapMode(uint32_t value) { arraysize(string_table), value); } +std::string GLES2Util::GetStringTransformFeedbackBindTarget(uint32_t value) { + static const EnumToString string_table[] = { + {GL_TRANSFORM_FEEDBACK, "GL_TRANSFORM_FEEDBACK"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringTransformFeedbackPrimitiveMode(uint32_t value) { + static const EnumToString string_table[] = { + {GL_POINTS, "GL_POINTS"}, + {GL_LINES, "GL_LINES"}, + {GL_TRIANGLES, "GL_TRIANGLES"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringUniformBlockParameter(uint32_t value) { + static const EnumToString string_table[] = { + {GL_UNIFORM_BLOCK_BINDING, "GL_UNIFORM_BLOCK_BINDING"}, + {GL_UNIFORM_BLOCK_DATA_SIZE, "GL_UNIFORM_BLOCK_DATA_SIZE"}, + {GL_UNIFORM_BLOCK_NAME_LENGTH, "GL_UNIFORM_BLOCK_NAME_LENGTH"}, + {GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS"}, + {GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + "GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES"}, + {GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, + "GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER"}, + {GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, + "GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringUniformParameter(uint32_t value) { + static const EnumToString string_table[] = { + {GL_UNIFORM_SIZE, "GL_UNIFORM_SIZE"}, + {GL_UNIFORM_TYPE, "GL_UNIFORM_TYPE"}, + {GL_UNIFORM_NAME_LENGTH, "GL_UNIFORM_NAME_LENGTH"}, + {GL_UNIFORM_BLOCK_INDEX, "GL_UNIFORM_BLOCK_INDEX"}, + {GL_UNIFORM_OFFSET, "GL_UNIFORM_OFFSET"}, + {GL_UNIFORM_ARRAY_STRIDE, "GL_UNIFORM_ARRAY_STRIDE"}, + {GL_UNIFORM_MATRIX_STRIDE, "GL_UNIFORM_MATRIX_STRIDE"}, + {GL_UNIFORM_IS_ROW_MAJOR, "GL_UNIFORM_IS_ROW_MAJOR"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + std::string GLES2Util::GetStringValueBufferTarget(uint32_t value) { static const EnumToString string_table[] = { {GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, @@ -4504,6 +5737,19 @@ std::string GLES2Util::GetStringValueBufferTarget(uint32_t value) { arraysize(string_table), value); } +std::string GLES2Util::GetStringVertexAttribIType(uint32_t value) { + static const EnumToString string_table[] = { + {GL_BYTE, "GL_BYTE"}, + {GL_UNSIGNED_BYTE, "GL_UNSIGNED_BYTE"}, + {GL_SHORT, "GL_SHORT"}, + {GL_UNSIGNED_SHORT, "GL_UNSIGNED_SHORT"}, + {GL_INT, "GL_INT"}, + {GL_UNSIGNED_INT, "GL_UNSIGNED_INT"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + std::string GLES2Util::GetStringVertexAttribType(uint32_t value) { static const EnumToString string_table[] = { {GL_BYTE, "GL_BYTE"}, @@ -4511,6 +5757,11 @@ std::string GLES2Util::GetStringVertexAttribType(uint32_t value) { {GL_SHORT, "GL_SHORT"}, {GL_UNSIGNED_SHORT, "GL_UNSIGNED_SHORT"}, {GL_FLOAT, "GL_FLOAT"}, + {GL_INT, "GL_INT"}, + {GL_UNSIGNED_INT, "GL_UNSIGNED_INT"}, + {GL_HALF_FLOAT, "GL_HALF_FLOAT"}, + {GL_INT_2_10_10_10_REV, "GL_INT_2_10_10_10_REV"}, + {GL_UNSIGNED_INT_2_10_10_10_REV, "GL_UNSIGNED_INT_2_10_10_10_REV"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); @@ -4526,6 +5777,8 @@ std::string GLES2Util::GetStringVertexAttribute(uint32_t value) { {GL_VERTEX_ATTRIB_ARRAY_STRIDE, "GL_VERTEX_ATTRIB_ARRAY_STRIDE"}, {GL_VERTEX_ATTRIB_ARRAY_TYPE, "GL_VERTEX_ATTRIB_ARRAY_TYPE"}, {GL_CURRENT_VERTEX_ATTRIB, "GL_CURRENT_VERTEX_ATTRIB"}, + {GL_VERTEX_ATTRIB_ARRAY_INTEGER, "GL_VERTEX_ATTRIB_ARRAY_INTEGER"}, + {GL_VERTEX_ATTRIB_ARRAY_DIVISOR, "GL_VERTEX_ATTRIB_ARRAY_DIVISOR"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value); diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc b/chromium/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc index d0e7e037ebc..8f7f94f270d 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc +++ b/chromium/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc @@ -8,6 +8,7 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> #include <GLES2/gl2extchromium.h> +#include <GLES3/gl3.h> #include "testing/gtest/include/gtest/gtest.h" @@ -95,54 +96,83 @@ TEST_F(GLES2UtilTest, ComputeImageDataSizesFormats) { uint32_t unpadded_row_size; uint32_t padded_row_size; EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size, - &padded_row_size)); + kWidth, kHeight, 1, GL_RGB, GL_UNSIGNED_BYTE, 1, + &size, &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 3, size); EXPECT_EQ(kWidth * 3, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size, - &padded_row_size)); + kWidth, kHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, &size, + &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 4, size); EXPECT_EQ(kWidth * 4, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1, &size, + kWidth, kHeight, 1, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 1, size); EXPECT_EQ(kWidth * 1, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1, &size, + kWidth, kHeight, 1, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 2, size); EXPECT_EQ(kWidth * 2, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 1, &size, + kWidth, kHeight, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 4, size); EXPECT_EQ(kWidth * 4, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_ALPHA, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size, - &padded_row_size)); + kWidth, kHeight, 1, GL_ALPHA, GL_UNSIGNED_BYTE, 1, &size, + &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 1, size); EXPECT_EQ(kWidth * 1, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 1, &size, + kWidth, kHeight, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 1, &size, &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 2, size); EXPECT_EQ(kWidth * 2, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, 1, - &size, &unpadded_row_size, - &padded_row_size)); + kWidth, kHeight, 1, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, 1, + &size, &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 4, size); EXPECT_EQ(kWidth * 4, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, 1, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, 1, + &size, &unpadded_row_size, &padded_row_size)); + EXPECT_EQ(kWidth * kHeight * 3, size); + EXPECT_EQ(kWidth * 3, padded_row_size); + EXPECT_EQ(padded_row_size, unpadded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, 1, GL_RG, GL_UNSIGNED_BYTE, 1, + &size, &unpadded_row_size, &padded_row_size)); + EXPECT_EQ(kWidth * kHeight * 2, size); + EXPECT_EQ(kWidth * 2, padded_row_size); + EXPECT_EQ(padded_row_size, unpadded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, 1, GL_RG_INTEGER, GL_UNSIGNED_BYTE, 1, + &size, &unpadded_row_size, &padded_row_size)); + EXPECT_EQ(kWidth * kHeight * 2, size); + EXPECT_EQ(kWidth * 2, padded_row_size); + EXPECT_EQ(padded_row_size, unpadded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, 1, GL_RED, GL_UNSIGNED_BYTE, 1, + &size, &unpadded_row_size, &padded_row_size)); + EXPECT_EQ(kWidth * kHeight * 1, size); + EXPECT_EQ(kWidth * 1, padded_row_size); + EXPECT_EQ(padded_row_size, unpadded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, 1, + &size, &unpadded_row_size, &padded_row_size)); + EXPECT_EQ(kWidth * kHeight * 1, size); + EXPECT_EQ(kWidth * 1, padded_row_size); + EXPECT_EQ(padded_row_size, unpadded_row_size); } TEST_F(GLES2UtilTest, ComputeImageDataSizeTypes) { @@ -152,35 +182,59 @@ TEST_F(GLES2UtilTest, ComputeImageDataSizeTypes) { uint32_t unpadded_row_size; uint32_t padded_row_size; EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size, - &padded_row_size)); + kWidth, kHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, &size, + &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 4, size); EXPECT_EQ(kWidth * 4, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 1, &size, + kWidth, kHeight, 1, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 1, &size, &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 2, size); EXPECT_EQ(kWidth * 2, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 1, &size, + kWidth, kHeight, 1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 1, &size, &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 2, size); EXPECT_EQ(kWidth * 2, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 1, &size, + kWidth, kHeight, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 1, &size, &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 2, size); EXPECT_EQ(kWidth * 2, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 1, &size, + kWidth, kHeight, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 1, &size, + &unpadded_row_size, &padded_row_size)); + EXPECT_EQ(kWidth * kHeight * 4, size); + EXPECT_EQ(kWidth * 4, padded_row_size); + EXPECT_EQ(padded_row_size, unpadded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, 1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 1, &size, + &unpadded_row_size, &padded_row_size)); + EXPECT_EQ(kWidth * kHeight * 4, size); + EXPECT_EQ(kWidth * 4, padded_row_size); + EXPECT_EQ(padded_row_size, unpadded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, 1, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, 1, &size, + &unpadded_row_size, &padded_row_size)); + EXPECT_EQ(kWidth * kHeight * 4, size); + EXPECT_EQ(kWidth * 4, padded_row_size); + EXPECT_EQ(padded_row_size, unpadded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, 1, GL_RGBA, GL_UNSIGNED_INT_5_9_9_9_REV, 1, &size, &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 4, size); EXPECT_EQ(kWidth * 4, padded_row_size); EXPECT_EQ(padded_row_size, unpadded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, 1, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, + 1, &size, &unpadded_row_size, &padded_row_size)); + EXPECT_EQ(kWidth * kHeight * 8, size); + EXPECT_EQ(kWidth * 8, padded_row_size); + EXPECT_EQ(padded_row_size, unpadded_row_size); } TEST_F(GLES2UtilTest, ComputeImageDataSizesUnpackAlignment) { @@ -190,34 +244,70 @@ TEST_F(GLES2UtilTest, ComputeImageDataSizesUnpackAlignment) { uint32_t unpadded_row_size; uint32_t padded_row_size; EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size, - &padded_row_size)); + kWidth, kHeight, 1, GL_RGB, GL_UNSIGNED_BYTE, 1, &size, + &unpadded_row_size, &padded_row_size)); EXPECT_EQ(kWidth * kHeight * 3, size); EXPECT_EQ(kWidth * 3, unpadded_row_size); EXPECT_EQ(kWidth * 3, padded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 2, &size, &unpadded_row_size, - &padded_row_size)); + kWidth, kHeight, 1, GL_RGB, GL_UNSIGNED_BYTE, 2, &size, + &unpadded_row_size, &padded_row_size)); EXPECT_EQ((kWidth * 3 + 1) * (kHeight - 1) + kWidth * 3, size); EXPECT_EQ(kWidth * 3, unpadded_row_size); EXPECT_EQ(kWidth * 3 + 1, padded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 4, &size, &unpadded_row_size, - &padded_row_size)); + kWidth, kHeight, 1, GL_RGB, GL_UNSIGNED_BYTE, 4, &size, + &unpadded_row_size, &padded_row_size)); EXPECT_EQ((kWidth * 3 + 3) * (kHeight - 1) + kWidth * 3, size); EXPECT_EQ(kWidth * 3, unpadded_row_size); EXPECT_EQ(kWidth * 3 + 3, padded_row_size); EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( - kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 8, &size, &unpadded_row_size, - &padded_row_size)); + kWidth, kHeight, 1, GL_RGB, GL_UNSIGNED_BYTE, 8, &size, + &unpadded_row_size, &padded_row_size)); EXPECT_EQ((kWidth * 3 + 7) * (kHeight - 1) + kWidth * 3, size); EXPECT_EQ(kWidth * 3, unpadded_row_size); EXPECT_EQ(kWidth * 3 + 7, padded_row_size); } +TEST_F(GLES2UtilTest, ComputeImageDataSizeDepth) { + const uint32_t kWidth = 19; + const uint32_t kHeight = 12; + const uint32_t kDepth = 3; + uint32_t size; + uint32_t unpadded_row_size; + uint32_t padded_row_size; + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, kDepth, GL_RGB, GL_UNSIGNED_BYTE, 1, &size, + &unpadded_row_size, &padded_row_size)); + EXPECT_EQ(kWidth * kHeight * kDepth * 3, size); + EXPECT_EQ(kWidth * 3, padded_row_size); + EXPECT_EQ(padded_row_size, unpadded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, kDepth, GL_RGB, GL_UNSIGNED_BYTE, 2, &size, + &unpadded_row_size, &padded_row_size)); + EXPECT_EQ((kWidth * 3 + 1) * (kHeight * kDepth - 1) + + kWidth * 3, size); + EXPECT_EQ(kWidth * 3, unpadded_row_size); + EXPECT_EQ(kWidth * 3 + 1, padded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, kDepth, GL_RGB, GL_UNSIGNED_BYTE, 4, &size, + &unpadded_row_size, &padded_row_size)); + EXPECT_EQ((kWidth * 3 + 3) * (kHeight * kDepth - 1) + + kWidth * 3, size); + EXPECT_EQ(kWidth * 3, unpadded_row_size); + EXPECT_EQ(kWidth * 3 + 3, padded_row_size); + EXPECT_TRUE(GLES2Util::ComputeImageDataSizes( + kWidth, kHeight, kDepth, GL_RGB, GL_UNSIGNED_BYTE, 8, &size, + &unpadded_row_size, &padded_row_size)); + EXPECT_EQ((kWidth * 3 + 7) * (kHeight * kDepth - 1) + + kWidth * 3, size); + EXPECT_EQ(kWidth * 3, unpadded_row_size); + EXPECT_EQ(kWidth * 3 + 7, padded_row_size); +} + TEST_F(GLES2UtilTest, RenderbufferBytesPerPixel) { EXPECT_EQ(1u, GLES2Util::RenderbufferBytesPerPixel(GL_STENCIL_INDEX8)); EXPECT_EQ(2u, GLES2Util::RenderbufferBytesPerPixel(GL_RGBA4)); @@ -300,6 +390,7 @@ TEST_F(GLES2UtilTest, ParseUniformName) { CheckParseUniformName("u_name[03][02]", true, 10u, 2, true); CheckParseUniformName("u_name[30][20]", true, 10u, 20, true); CheckParseUniformName("u_name[030][020]", true, 11u, 20, true); + CheckParseUniformName("", false, std::string::npos, 0, false); } } // namespace gles2 diff --git a/chromium/gpu/command_buffer/common/id_allocator.cc b/chromium/gpu/command_buffer/common/id_allocator.cc index 507b14e9af1..eccb4681df7 100644 --- a/chromium/gpu/command_buffer/common/id_allocator.cc +++ b/chromium/gpu/command_buffer/common/id_allocator.cc @@ -6,84 +6,200 @@ #include "gpu/command_buffer/common/id_allocator.h" +#include <limits> #include "base/logging.h" namespace gpu { -IdAllocator::IdAllocator() {} +IdAllocator::IdAllocator() { + COMPILE_ASSERT(kInvalidResource == 0u, invalid_resource_is_not_zero); + // Simplify the code by making sure that lower_bound(id) never + // returns the beginning of the map, if id is valid (eg != + // kInvalidResource). + used_ids_.insert(std::make_pair(0u, 0u)); +} IdAllocator::~IdAllocator() {} ResourceId IdAllocator::AllocateID() { - ResourceId id; - ResourceIdSet::iterator iter = free_ids_.begin(); - if (iter != free_ids_.end()) { - id = *iter; + return AllocateIDRange(1u); +} + +ResourceId IdAllocator::AllocateIDAtOrAbove(ResourceId desired_id) { + if (desired_id == 0u || desired_id == 1u) { + return AllocateIDRange(1u); + } + + ResourceIdRangeMap::iterator current = used_ids_.lower_bound(desired_id); + ResourceIdRangeMap::iterator next = current; + if (current == used_ids_.end() || current->first > desired_id) { + current--; } else { - id = LastUsedId() + 1; - if (!id) { - // We wrapped around to 0. - id = FindFirstUnusedId(); + next++; + } + + ResourceId first_id = current->first; + ResourceId last_id = current->second; + + DCHECK(desired_id >= first_id); + + if (desired_id - 1u <= last_id) { + // Append to current range. + last_id++; + if (last_id == 0) { + // The increment overflowed. + return AllocateIDRange(1u); + } + + current->second = last_id; + + if (next != used_ids_.end() && next->first - 1u == last_id) { + // Merge with next range. + current->second = next->second; + used_ids_.erase(next); } + return last_id; + } else if (next != used_ids_.end() && next->first - 1u == desired_id) { + // Prepend to next range. + ResourceId last_existing_id = next->second; + used_ids_.erase(next); + used_ids_.insert(std::make_pair(desired_id, last_existing_id)); + return desired_id; } - MarkAsUsed(id); - return id; + used_ids_.insert(std::make_pair(desired_id, desired_id)); + return desired_id; } -ResourceId IdAllocator::AllocateIDAtOrAbove(ResourceId desired_id) { - ResourceId id; - ResourceIdSet::iterator iter = free_ids_.lower_bound(desired_id); - if (iter != free_ids_.end()) { - id = *iter; - } else if (LastUsedId() < desired_id) { - id = desired_id; - } else { - id = LastUsedId() + 1; - if (!id) { - // We wrapped around to 0. - id = FindFirstUnusedId(); +ResourceId IdAllocator::AllocateIDRange(uint32_t range) { + DCHECK(range > 0u); + + ResourceIdRangeMap::iterator current = used_ids_.begin(); + ResourceIdRangeMap::iterator next = current; + + while (++next != used_ids_.end()) { + if (next->first - current->second > range) { + break; } + current = next; + } + + ResourceId first_id = current->second + 1u; + ResourceId last_id = first_id + range - 1u; + + if (first_id == 0u || last_id < first_id) { + return kInvalidResource; } - MarkAsUsed(id); - return id; + + current->second = last_id; + + if (next != used_ids_.end() && next->first - 1u == last_id) { + // Merge with next range. + current->second = next->second; + used_ids_.erase(next); + } + + return first_id; } bool IdAllocator::MarkAsUsed(ResourceId id) { DCHECK(id); - free_ids_.erase(id); - std::pair<ResourceIdSet::iterator, bool> result = used_ids_.insert(id); - return result.second; -} + ResourceIdRangeMap::iterator current = used_ids_.lower_bound(id); + if (current != used_ids_.end() && current->first == id) { + return false; + } -void IdAllocator::FreeID(ResourceId id) { - if (id) { - used_ids_.erase(id); - free_ids_.insert(id); + ResourceIdRangeMap::iterator next = current; + --current; + + if (current->second >= id) { + return false; } + + DCHECK(current->first < id && current->second < id); + + if (current->second + 1u == id) { + // Append to current range. + current->second = id; + if (next != used_ids_.end() && next->first - 1u == id) { + // Merge with next range. + current->second = next->second; + used_ids_.erase(next); + } + return true; + } else if (next != used_ids_.end() && next->first - 1u == id) { + // Prepend to next range. + ResourceId last_existing_id = next->second; + used_ids_.erase(next); + used_ids_.insert(std::make_pair(id, last_existing_id)); + return true; + } + + used_ids_.insert(std::make_pair(id, id)); + return true; } -bool IdAllocator::InUse(ResourceId id) const { - return id == kInvalidResource || used_ids_.find(id) != used_ids_.end(); +void IdAllocator::FreeID(ResourceId id) { + FreeIDRange(id, 1u); } -ResourceId IdAllocator::LastUsedId() const { - if (used_ids_.empty()) { - return 0u; - } else { - return *used_ids_.rbegin(); +void IdAllocator::FreeIDRange(ResourceId first_id, uint32 range) { + COMPILE_ASSERT(kInvalidResource == 0u, invalid_resource_is_not_zero); + + if (range == 0u || (first_id == 0u && range == 1u)) { + return; + } + + if (first_id == 0u) { + first_id++; + range--; + } + + ResourceId last_id = first_id + range - 1u; + if (last_id < first_id) { + last_id = std::numeric_limits<ResourceId>::max(); + } + + while (true) { + ResourceIdRangeMap::iterator current = used_ids_.lower_bound(last_id); + if (current == used_ids_.end() || current->first > last_id) { + --current; + } + + if (current->second < first_id) { + return; + } + + if (current->first >= first_id) { + ResourceId last_existing_id = current->second; + used_ids_.erase(current); + if (last_id < last_existing_id) { + used_ids_.insert(std::make_pair(last_id + 1u, last_existing_id)); + } + } else if (current->second <= last_id) { + current->second = first_id - 1u; + } else { + DCHECK(current->first < first_id && current->second > last_id); + ResourceId last_existing_id = current->second; + current->second = first_id - 1u; + used_ids_.insert(std::make_pair(last_id + 1u, last_existing_id)); + } } } -ResourceId IdAllocator::FindFirstUnusedId() const { - ResourceId id = 1; - for (ResourceIdSet::const_iterator it = used_ids_.begin(); - it != used_ids_.end(); ++it) { - if ((*it) != id) { - return id; +bool IdAllocator::InUse(ResourceId id) const { + if (id == kInvalidResource) { + return false; + } + + ResourceIdRangeMap::const_iterator current = used_ids_.lower_bound(id); + if (current != used_ids_.end()) { + if (current->first == id) { + return true; } - ++id; } - return id; + + --current; + return current->second >= id; } } // namespace gpu diff --git a/chromium/gpu/command_buffer/common/id_allocator.h b/chromium/gpu/command_buffer/common/id_allocator.h index b877083008a..118424f3c9d 100644 --- a/chromium/gpu/command_buffer/common/id_allocator.h +++ b/chromium/gpu/command_buffer/common/id_allocator.h @@ -9,7 +9,7 @@ #include <stdint.h> -#include <set> +#include <map> #include <utility> #include "base/compiler_specific.h" @@ -36,27 +36,28 @@ class GPU_EXPORT IdAllocator { // Note: may wrap if it starts near limit. ResourceId AllocateIDAtOrAbove(ResourceId desired_id); + // Allocates |range| amount of contiguous ids. + // Returns the first id to |first_id| or |kInvalidResource| if + // allocation failed. + ResourceId AllocateIDRange(uint32_t range); + // Marks an id as used. Returns false if id was already used. bool MarkAsUsed(ResourceId id); // Frees a resource ID. void FreeID(ResourceId id); + // Frees a |range| amount of contiguous ids, starting from |first_id|. + void FreeIDRange(ResourceId first_id, uint32_t range); + // Checks whether or not a resource ID is in use. bool InUse(ResourceId id) const; private: - // TODO(gman): This would work much better with ranges or a hash table. - typedef std::set<ResourceId> ResourceIdSet; - - // The highest ID on the used list. - ResourceId LastUsedId() const; - - // Lowest ID that isn't on the used list. This is slow, use as a last resort. - ResourceId FindFirstUnusedId() const; + // first_id -> last_id mapping. + typedef std::map<ResourceId, ResourceId> ResourceIdRangeMap; - ResourceIdSet used_ids_; - ResourceIdSet free_ids_; + ResourceIdRangeMap used_ids_; DISALLOW_COPY_AND_ASSIGN(IdAllocator); }; diff --git a/chromium/gpu/command_buffer/common/id_allocator_test.cc b/chromium/gpu/command_buffer/common/id_allocator_test.cc index adeed5b0969..7d939061988 100644 --- a/chromium/gpu/command_buffer/common/id_allocator_test.cc +++ b/chromium/gpu/command_buffer/common/id_allocator_test.cc @@ -125,4 +125,123 @@ TEST_F(IdAllocatorTest, RedundantFreeIsIgnored) { EXPECT_NE(kInvalidResource, id3); } +TEST_F(IdAllocatorTest, AllocateIDRange) { + const ResourceId kMaxPossibleOffset = std::numeric_limits<ResourceId>::max(); + + IdAllocator* allocator = id_allocator(); + + ResourceId id1 = allocator->AllocateIDRange(1); + EXPECT_EQ(1u, id1); + ResourceId id2 = allocator->AllocateIDRange(2); + EXPECT_EQ(2u, id2); + ResourceId id3 = allocator->AllocateIDRange(3); + EXPECT_EQ(4u, id3); + ResourceId id4 = allocator->AllocateID(); + EXPECT_EQ(7u, id4); + allocator->FreeID(3); + ResourceId id5 = allocator->AllocateIDRange(1); + EXPECT_EQ(3u, id5); + allocator->FreeID(5); + allocator->FreeID(2); + allocator->FreeID(4); + ResourceId id6 = allocator->AllocateIDRange(2); + EXPECT_EQ(4u, id6); + ResourceId id7 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset); + EXPECT_EQ(kMaxPossibleOffset, id7); + ResourceId id8 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset); + EXPECT_EQ(2u, id8); + ResourceId id9 = allocator->AllocateIDRange(50); + EXPECT_EQ(8u, id9); + ResourceId id10 = allocator->AllocateIDRange(50); + EXPECT_EQ(58u, id10); + // Remove all the low-numbered ids. + allocator->FreeID(1); + allocator->FreeID(15); + allocator->FreeIDRange(2, 107); + ResourceId id11 = allocator->AllocateIDRange(100); + EXPECT_EQ(1u, id11); + allocator->FreeID(kMaxPossibleOffset); + ResourceId id12 = allocator->AllocateIDRange(100); + EXPECT_EQ(101u, id12); + + ResourceId id13 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset - 2u); + EXPECT_EQ(kMaxPossibleOffset - 2u, id13); + ResourceId id14 = allocator->AllocateIDRange(3); + EXPECT_EQ(201u, id14); +} + +TEST_F(IdAllocatorTest, AllocateIDRangeEndNoEffect) { + const ResourceId kMaxPossibleOffset = std::numeric_limits<ResourceId>::max(); + + IdAllocator* allocator = id_allocator(); + ResourceId id1 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset - 2u); + EXPECT_EQ(kMaxPossibleOffset - 2u, id1); + ResourceId id3 = allocator->AllocateIDRange(3); + EXPECT_EQ(1u, id3); + ResourceId id2 = allocator->AllocateIDRange(2); + EXPECT_EQ(4u, id2); +} + +TEST_F(IdAllocatorTest, AllocateFullIDRange) { + const uint32_t kMaxPossibleRange = std::numeric_limits<uint32_t>::max(); + const ResourceId kFreedId = 555u; + IdAllocator* allocator = id_allocator(); + + ResourceId id1 = allocator->AllocateIDRange(kMaxPossibleRange); + EXPECT_EQ(1u, id1); + ResourceId id2 = allocator->AllocateID(); + EXPECT_EQ(0u, id2); + allocator->FreeID(kFreedId); + ResourceId id3 = allocator->AllocateID(); + EXPECT_EQ(kFreedId, id3); + ResourceId id4 = allocator->AllocateID(); + EXPECT_EQ(0u, id4); + allocator->FreeID(kFreedId + 1u); + allocator->FreeID(kFreedId + 4u); + allocator->FreeID(kFreedId + 3u); + allocator->FreeID(kFreedId + 5u); + allocator->FreeID(kFreedId + 2u); + ResourceId id5 = allocator->AllocateIDRange(5); + EXPECT_EQ(kFreedId + 1u, id5); +} + +TEST_F(IdAllocatorTest, AllocateIDRangeNoWrapInRange) { + const uint32_t kMaxPossibleRange = std::numeric_limits<uint32_t>::max(); + const ResourceId kAllocId = 10u; + IdAllocator* allocator = id_allocator(); + + ResourceId id1 = allocator->AllocateIDAtOrAbove(kAllocId); + EXPECT_EQ(kAllocId, id1); + ResourceId id2 = allocator->AllocateIDRange(kMaxPossibleRange - 5u); + EXPECT_EQ(0u, id2); + ResourceId id3 = allocator->AllocateIDRange(kMaxPossibleRange - kAllocId); + EXPECT_EQ(kAllocId + 1u, id3); +} + +TEST_F(IdAllocatorTest, AllocateIdMax) { + const uint32_t kMaxPossibleRange = std::numeric_limits<uint32_t>::max(); + + IdAllocator* allocator = id_allocator(); + ResourceId id = allocator->AllocateIDRange(kMaxPossibleRange); + EXPECT_EQ(1u, id); + allocator->FreeIDRange(id, kMaxPossibleRange - 1u); + ResourceId id2 = allocator->AllocateIDRange(kMaxPossibleRange); + EXPECT_EQ(0u, id2); + allocator->FreeIDRange(id, kMaxPossibleRange); + ResourceId id3 = allocator->AllocateIDRange(kMaxPossibleRange); + EXPECT_EQ(1u, id3); +} + +TEST_F(IdAllocatorTest, ZeroIdCases) { + IdAllocator* allocator = id_allocator(); + EXPECT_FALSE(allocator->InUse(0)); + ResourceId id1 = allocator->AllocateIDAtOrAbove(0); + EXPECT_NE(0u, id1); + EXPECT_FALSE(allocator->InUse(0)); + allocator->FreeID(0); + EXPECT_FALSE(allocator->InUse(0)); + EXPECT_TRUE(allocator->InUse(id1)); + allocator->FreeID(id1); + EXPECT_FALSE(allocator->InUse(id1)); +} } // namespace gpu diff --git a/chromium/gpu/command_buffer/common/time.h b/chromium/gpu/command_buffer/common/time.h index e4eb9422e7b..e58145b51f3 100644 --- a/chromium/gpu/command_buffer/common/time.h +++ b/chromium/gpu/command_buffer/common/time.h @@ -12,7 +12,7 @@ namespace gpu { inline uint64 MicrosecondsSinceOriginOfTime() { - return (base::TimeTicks::HighResNow() - base::TimeTicks()).InMicroseconds(); + return (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds(); } } // namespace gpu diff --git a/chromium/gpu/command_buffer/common/trace_event.h b/chromium/gpu/command_buffer/common/trace_event.h index e63517e5236..4bc18d7ae27 100644 --- a/chromium/gpu/command_buffer/common/trace_event.h +++ b/chromium/gpu/command_buffer/common/trace_event.h @@ -5,6 +5,6 @@ #ifndef GPU_COMMAND_BUFFER_COMMON_TRACE_EVENT_H_ #define GPU_COMMAND_BUFFER_COMMON_TRACE_EVENT_H_ -#include "base/debug/trace_event.h" +#include "base/trace_event/trace_event.h" #endif // GPU_COMMAND_BUFFER_COMMON_TRACE_EVENT_H_ diff --git a/chromium/gpu/command_buffer/common/unittest_main.cc b/chromium/gpu/command_buffer/common/unittest_main.cc index 2d6a2d116ea..17b6114c13e 100644 --- a/chromium/gpu/command_buffer/common/unittest_main.cc +++ b/chromium/gpu/command_buffer/common/unittest_main.cc @@ -5,11 +5,16 @@ #include "base/at_exit.h" #include "base/bind.h" #include "base/command_line.h" +#include "base/message_loop/message_loop.h" #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_suite.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_MACOSX) +#include "base/mac/scoped_nsautorelease_pool.h" +#endif + namespace { class NoAtExitBaseTestSuite : public base::TestSuite { @@ -20,6 +25,7 @@ class NoAtExitBaseTestSuite : public base::TestSuite { }; int RunTestSuite(int argc, char** argv) { + base::MessageLoop message_loop; return NoAtExitBaseTestSuite(argc, argv).Run(); } @@ -32,7 +38,10 @@ int main(int argc, char** argv) { #if !defined(OS_ANDROID) base::AtExitManager exit_manager; #endif - CommandLine::Init(argc, argv); + base::CommandLine::Init(argc, argv); +#if defined(OS_MACOSX) + base::mac::ScopedNSAutoreleasePool autorelease_pool; +#endif testing::InitGoogleMock(&argc, argv); return base::LaunchUnitTests(argc, argv, diff --git a/chromium/gpu/command_buffer/common/value_state.cc b/chromium/gpu/command_buffer/common/value_state.cc new file mode 100644 index 00000000000..d4dcdc22665 --- /dev/null +++ b/chromium/gpu/command_buffer/common/value_state.cc @@ -0,0 +1,24 @@ +// Copyright (c) 2014 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 "gpu/command_buffer/common/value_state.h" + +namespace gpu { + +ValueStateMap::ValueStateMap() { +} + +ValueStateMap::~ValueStateMap() { +} + +const ValueState* ValueStateMap::GetState(unsigned int target) const { + Map::const_iterator it = state_map_.find(target); + return it != state_map_.end() ? &it->second : NULL; +} + +void ValueStateMap::UpdateState(unsigned int target, const ValueState& state) { + state_map_[target] = state; +} + +} // namespace gpu diff --git a/chromium/gpu/command_buffer/common/value_state.h b/chromium/gpu/command_buffer/common/value_state.h new file mode 100644 index 00000000000..478924581b8 --- /dev/null +++ b/chromium/gpu/command_buffer/common/value_state.h @@ -0,0 +1,46 @@ +// Copyright (c) 2014 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. + +#ifndef GPU_COMMAND_BUFFER_COMMON_VALUE_STATE_H_ +#define GPU_COMMAND_BUFFER_COMMON_VALUE_STATE_H_ + +#include "base/containers/hash_tables.h" +#include "base/memory/ref_counted.h" +#include "gpu/gpu_export.h" + +namespace gpu { + +// Used to maintain Valuebuffer state, exposed to browser to +// support passing ValueStates via IPC. +union GPU_EXPORT ValueState { + float float_value[4]; + int int_value[4]; +}; + +// Refcounted wrapper for a hash_map of subscription targets to ValueStates +class GPU_EXPORT ValueStateMap : public base::RefCounted<ValueStateMap> { + public: + ValueStateMap(); + + // Returns NULL if there is not ValueState for the target + const ValueState* GetState(unsigned int target) const; + + void UpdateState(unsigned int target, const ValueState& state); + + protected: + virtual ~ValueStateMap(); + + private: + friend class base::RefCounted<ValueStateMap>; + + typedef base::hash_map<unsigned int, ValueState> Map; + + Map state_map_; + + DISALLOW_COPY_AND_ASSIGN(ValueStateMap); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_COMMON_VALUE_STATE_H_ diff --git a/chromium/gpu/command_buffer/service/BUILD.gn b/chromium/gpu/command_buffer/service/BUILD.gn index 4013c3ac035..0bcafdc97a8 100644 --- a/chromium/gpu/command_buffer/service/BUILD.gn +++ b/chromium/gpu/command_buffer/service/BUILD.gn @@ -5,10 +5,26 @@ import("//build/config/ui.gni") import("//third_party/protobuf/proto_library.gni") -source_set("service") { +group("service") { + if (is_component_build) { + public_deps = [ + "//gpu", + ] + } else { + public_deps = [ + ":service_sources", + ] + } +} + +source_set("service_sources") { + visibility = [ "//gpu/*" ] + sources = [ "async_pixel_transfer_delegate.cc", "async_pixel_transfer_delegate.h", + "async_pixel_transfer_manager.cc", + "async_pixel_transfer_manager.h", "async_pixel_transfer_manager_android.cc", "async_pixel_transfer_manager_idle.cc", "async_pixel_transfer_manager_idle.h", @@ -21,10 +37,8 @@ source_set("service") { "async_pixel_transfer_manager_sync.cc", "async_pixel_transfer_manager_sync.h", "async_pixel_transfer_manager_win.cc", - "async_pixel_transfer_manager.cc", - "async_pixel_transfer_manager.h", - "buffer_manager.h", "buffer_manager.cc", + "buffer_manager.h", "cmd_buffer_engine.h", "cmd_parser.cc", "cmd_parser.h", @@ -32,43 +46,44 @@ source_set("service") { "command_buffer_service.h", "common_decoder.cc", "common_decoder.h", - "context_group.h", "context_group.cc", + "context_group.h", + "context_state.cc", "context_state.h", "context_state_autogen.h", "context_state_impl_autogen.h", - "context_state.cc", "error_state.cc", "error_state.h", - "feature_info.h", "feature_info.cc", - "framebuffer_manager.h", + "feature_info.h", "framebuffer_manager.cc", + "framebuffer_manager.h", + "gl_context_virtual.cc", + "gl_context_virtual.h", + "gl_state_restorer_impl.cc", + "gl_state_restorer_impl.h", + "gl_utils.h", + "gles2_cmd_clear_framebuffer.cc", + "gles2_cmd_clear_framebuffer.h", "gles2_cmd_copy_texture_chromium.cc", "gles2_cmd_copy_texture_chromium.h", + "gles2_cmd_decoder.cc", "gles2_cmd_decoder.h", "gles2_cmd_decoder_autogen.h", - "gles2_cmd_decoder.cc", - "gles2_cmd_validation.h", "gles2_cmd_validation.cc", + "gles2_cmd_validation.h", "gles2_cmd_validation_autogen.h", "gles2_cmd_validation_implementation_autogen.h", - "gl_context_virtual.cc", - "gl_context_virtual.h", - "gl_state_restorer_impl.cc", - "gl_state_restorer_impl.h", - "gl_utils.h", "gpu_scheduler.cc", "gpu_scheduler.h", - "gpu_scheduler_mock.h", "gpu_state_tracer.cc", "gpu_state_tracer.h", "gpu_switches.cc", "gpu_switches.h", "gpu_tracer.cc", "gpu_tracer.h", - "id_manager.h", "id_manager.cc", + "id_manager.h", "image_factory.cc", "image_factory.h", "image_manager.cc", @@ -82,42 +97,42 @@ source_set("service") { "mailbox_manager_impl.h", "mailbox_manager_sync.cc", "mailbox_manager_sync.h", - "memory_program_cache.h", "memory_program_cache.cc", - "mocks.h", - "program_manager.h", + "memory_program_cache.h", + "program_cache.cc", + "program_cache.h", "program_manager.cc", - "query_manager.h", + "program_manager.h", "query_manager.cc", - "renderbuffer_manager.h", + "query_manager.h", "renderbuffer_manager.cc", - "program_cache.h", - "program_cache.cc", - "shader_manager.h", + "renderbuffer_manager.h", "shader_manager.cc", - "shader_translator.h", + "shader_manager.h", "shader_translator.cc", - "shader_translator_cache.h", + "shader_translator.h", "shader_translator_cache.cc", - "stream_texture_manager_in_process_android.h", + "shader_translator_cache.h", "stream_texture_manager_in_process_android.cc", - "texture_definition.h", + "stream_texture_manager_in_process_android.h", + "sync_point_manager.cc", + "sync_point_manager.h", "texture_definition.cc", - "texture_manager.h", + "texture_definition.h", "texture_manager.cc", + "texture_manager.h", "transfer_buffer_manager.cc", "transfer_buffer_manager.h", - "valuebuffer_manager.h", "valuebuffer_manager.cc", - "vertex_array_manager.h", + "valuebuffer_manager.h", "vertex_array_manager.cc", - "vertex_attrib_manager.h", + "vertex_array_manager.h", "vertex_attrib_manager.cc", + "vertex_attrib_manager.h", ] - defines = [ "GPU_IMPLEMENTATION" ] - configs += [ + "//gpu:gpu_implementation", "//third_party/khronos:khronos_headers", ] @@ -125,13 +140,14 @@ source_set("service") { include_dirs = [ "//third_party/mesa/src/include" ] public_deps = [ - "//gpu/command_buffer/common", + "//gpu/command_buffer/common:common_sources", ] deps = [ ":disk_cache_proto", "//base", "//base/third_party/dynamic_annotations", "//crypto", + "//gpu/config:config_sources", "//third_party/angle:translator", "//third_party/protobuf:protobuf_lite", "//third_party/re2", @@ -141,10 +157,6 @@ source_set("service") { "//ui/gl", ] - if (ui_compositor_image_transport) { - include_dirs += [ "//third_party/khronos" ] - } - if (is_win || is_android || (is_linux && use_x11)) { sources += [ "async_pixel_transfer_manager_egl.cc", @@ -152,6 +164,14 @@ source_set("service") { ] } + if (is_mac) { + # Required by gles2_cmd_decoder.cc on Mac. + libs = [ + "IOSurface.framework", + "OpenGL.framework", + ] + } + if (is_android && !is_debug) { # On Android optimize more since this component can be a bottleneck. configs -= [ "//build/config/compiler:optimize" ] @@ -160,5 +180,7 @@ source_set("service") { } proto_library("disk_cache_proto") { - sources = [ "disk_cache_proto.proto" ] + sources = [ + "disk_cache_proto.proto", + ] } diff --git a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc index eadc34f07a1..9b6b7e212c6 100644 --- a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc +++ b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc @@ -4,12 +4,14 @@ #include "gpu/command_buffer/service/async_pixel_transfer_manager.h" -#include "base/debug/trace_event.h" +#include "base/command_line.h" #include "base/sys_info.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/service/async_pixel_transfer_manager_egl.h" #include "gpu/command_buffer/service/async_pixel_transfer_manager_idle.h" #include "gpu/command_buffer/service/async_pixel_transfer_manager_stub.h" #include "gpu/command_buffer/service/async_pixel_transfer_manager_sync.h" +#include "gpu/command_buffer/service/gpu_switches.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" @@ -75,6 +77,16 @@ bool AllowTransferThreadForGpu() { AsyncPixelTransferManager* AsyncPixelTransferManager::Create( gfx::GLContext* context) { DCHECK(context->IsCurrent(NULL)); + base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + + // Threaded mailbox uses EGLImage which conflicts with EGL uploader. + // The spec only allows one EGL image per sibling group, but currently the + // image handle cannot be shared between the threaded mailbox code and + // AsyncPixelTransferManagerEGL. + bool uses_threaded_mailboxes = + cl->HasSwitch(switches::kEnableThreadedTextureMailboxes); + // TexImage2D orphans the EGLImage used for threaded mailbox sharing. + bool use_teximage2d_over_texsubimage2d = !uses_threaded_mailboxes; switch (gfx::GetGLImplementation()) { case gfx::kGLImplementationEGLGLES2: DCHECK(context); @@ -84,14 +96,16 @@ AsyncPixelTransferManager* AsyncPixelTransferManager::Create( context->HasExtension("EGL_KHR_image_base") && context->HasExtension("EGL_KHR_gl_texture_2D_image") && context->HasExtension("GL_OES_EGL_image") && - AllowTransferThreadForGpu()) { + !uses_threaded_mailboxes && AllowTransferThreadForGpu()) { TRACE_EVENT0("gpu", "AsyncPixelTransferManager_CreateWithThread"); return new AsyncPixelTransferManagerEGL; } - return new AsyncPixelTransferManagerIdle; + return new AsyncPixelTransferManagerIdle( + use_teximage2d_over_texsubimage2d); case gfx::kGLImplementationOSMesaGL: { TRACE_EVENT0("gpu", "AsyncPixelTransferManager_CreateIdle"); - return new AsyncPixelTransferManagerIdle; + return new AsyncPixelTransferManagerIdle( + use_teximage2d_over_texsubimage2d); } case gfx::kGLImplementationMockGL: return new AsyncPixelTransferManagerStub; diff --git a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc index 34e3a3702bf..971dc0d79da 100644 --- a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc +++ b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc @@ -8,13 +8,15 @@ #include <string> #include "base/bind.h" -#include "base/debug/trace_event.h" -#include "base/debug/trace_event_synthetic_delay.h" #include "base/lazy_instance.h" +#include "base/location.h" #include "base/logging.h" #include "base/memory/ref_counted.h" +#include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" +#include "base/trace_event/trace_event.h" +#include "base/trace_event/trace_event_synthetic_delay.h" #include "gpu/command_buffer/service/async_pixel_transfer_delegate.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_surface_egl.h" @@ -90,7 +92,7 @@ class TransferThread : public base::Thread { TransferThread() : base::Thread(kAsyncTransferThreadName) { Start(); #if defined(OS_ANDROID) || defined(OS_LINUX) - SetPriority(base::kThreadPriority_Background); + SetPriority(base::ThreadPriority::BACKGROUND); #endif } ~TransferThread() override { Stop(); } @@ -121,8 +123,8 @@ class TransferThread : public base::Thread { base::LazyInstance<TransferThread> g_transfer_thread = LAZY_INSTANCE_INITIALIZER; -base::MessageLoopProxy* transfer_message_loop_proxy() { - return g_transfer_thread.Pointer()->message_loop_proxy().get(); +base::SingleThreadTaskRunner* transfer_task_runner() { + return g_transfer_thread.Pointer()->task_runner().get(); } // Class which holds async pixel transfers state (EGLImage). @@ -256,7 +258,7 @@ class TransferStateInternal base::TimeTicks begin_time; if (texture_upload_stats.get()) - begin_time = base::TimeTicks::HighResNow(); + begin_time = base::TimeTicks::Now(); { TRACE_EVENT0("gpu", "glTexImage2D no data"); @@ -291,8 +293,7 @@ class TransferStateInternal DCHECK(CHECK_GL()); if (texture_upload_stats.get()) { - texture_upload_stats->AddUpload(base::TimeTicks::HighResNow() - - begin_time); + texture_upload_stats->AddUpload(base::TimeTicks::Now() - begin_time); } } @@ -314,7 +315,7 @@ class TransferStateInternal base::TimeTicks begin_time; if (texture_upload_stats.get()) - begin_time = base::TimeTicks::HighResNow(); + begin_time = base::TimeTicks::Now(); if (!thread_texture_id_) { TRACE_EVENT0("gpu", "glEGLImageTargetTexture2DOES"); @@ -335,8 +336,7 @@ class TransferStateInternal DCHECK(CHECK_GL()); if (texture_upload_stats.get()) { - texture_upload_stats->AddUpload(base::TimeTicks::HighResNow() - - begin_time); + texture_upload_stats->AddUpload(base::TimeTicks::Now() - begin_time); } } @@ -354,8 +354,8 @@ class TransferStateInternal eglDestroyImageKHR(display, egl_image_); } if (thread_texture_id_) { - transfer_message_loop_proxy()->PostTask(FROM_HERE, - base::Bind(&DeleteTexture, thread_texture_id_)); + transfer_task_runner()->PostTask( + FROM_HERE, base::Bind(&DeleteTexture, thread_texture_id_)); } } @@ -468,14 +468,14 @@ bool AsyncPixelTransferDelegateEGL::TransferIsInProgress() { void AsyncPixelTransferDelegateEGL::WaitForTransferCompletion() { if (state_->TransferIsInProgress()) { #if defined(OS_ANDROID) || defined(OS_LINUX) - g_transfer_thread.Pointer()->SetPriority(base::kThreadPriority_Display); + g_transfer_thread.Pointer()->SetPriority(base::ThreadPriority::DISPLAY); #endif state_->WaitForTransferCompletion(); DCHECK(!state_->TransferIsInProgress()); #if defined(OS_ANDROID) || defined(OS_LINUX) - g_transfer_thread.Pointer()->SetPriority(base::kThreadPriority_Background); + g_transfer_thread.Pointer()->SetPriority(base::ThreadPriority::BACKGROUND); #endif } } @@ -502,13 +502,10 @@ void AsyncPixelTransferDelegateEGL::AsyncTexImage2D( // Duplicate the shared memory so there is no way we can get // a use-after-free of the raw pixels. - transfer_message_loop_proxy()->PostTask(FROM_HERE, - base::Bind( - &TransferStateInternal::PerformAsyncTexImage2D, - state_, - tex_params, - mem_params, - shared_state_->texture_upload_stats)); + transfer_task_runner()->PostTask( + FROM_HERE, + base::Bind(&TransferStateInternal::PerformAsyncTexImage2D, state_, + tex_params, mem_params, shared_state_->texture_upload_stats)); DCHECK(CHECK_GL()); } @@ -534,13 +531,10 @@ void AsyncPixelTransferDelegateEGL::AsyncTexSubImage2D( // Duplicate the shared memory so there are no way we can get // a use-after-free of the raw pixels. - transfer_message_loop_proxy()->PostTask(FROM_HERE, - base::Bind( - &TransferStateInternal::PerformAsyncTexSubImage2D, - state_, - tex_params, - mem_params, - shared_state_->texture_upload_stats)); + transfer_task_runner()->PostTask( + FROM_HERE, + base::Bind(&TransferStateInternal::PerformAsyncTexSubImage2D, state_, + tex_params, mem_params, shared_state_->texture_upload_stats)); DCHECK(CHECK_GL()); } @@ -641,7 +635,7 @@ bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexSubImage2D( void* data = mem_params.GetDataAddress(); base::TimeTicks begin_time; if (shared_state_->texture_upload_stats.get()) - begin_time = base::TimeTicks::HighResNow(); + begin_time = base::TimeTicks::Now(); { TRACE_EVENT0("gpu", "glTexSubImage2D"); // Note we use define_params_ instead of tex_params. @@ -650,7 +644,7 @@ bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexSubImage2D( } if (shared_state_->texture_upload_stats.get()) { shared_state_->texture_upload_stats - ->AddUpload(base::TimeTicks::HighResNow() - begin_time); + ->AddUpload(base::TimeTicks::Now() - begin_time); } DCHECK(CHECK_GL()); @@ -703,11 +697,9 @@ void AsyncPixelTransferManagerEGL::AsyncNotifyCompletion( AsyncPixelTransferCompletionObserver* observer) { // Post a PerformNotifyCompletion task to the upload thread. This task // will run after all async transfers are complete. - transfer_message_loop_proxy()->PostTask( - FROM_HERE, - base::Bind(&PerformNotifyCompletion, - mem_params, - make_scoped_refptr(observer))); + transfer_task_runner()->PostTask( + FROM_HERE, base::Bind(&PerformNotifyCompletion, mem_params, + make_scoped_refptr(observer))); } uint32 AsyncPixelTransferManagerEGL::GetTextureUploadCount() { diff --git a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc index 61db3b68413..b555ebb60bc 100644 --- a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc +++ b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc @@ -5,10 +5,10 @@ #include "gpu/command_buffer/service/async_pixel_transfer_manager_idle.h" #include "base/bind.h" -#include "base/debug/trace_event.h" -#include "base/debug/trace_event_synthetic_delay.h" #include "base/lazy_instance.h" #include "base/memory/weak_ptr.h" +#include "base/trace_event/trace_event.h" +#include "base/trace_event/trace_event_synthetic_delay.h" #include "ui/gl/scoped_binders.h" namespace gpu { @@ -32,9 +32,10 @@ class AsyncPixelTransferDelegateIdle : public AsyncPixelTransferDelegate, public base::SupportsWeakPtr<AsyncPixelTransferDelegateIdle> { public: + typedef base::Callback<GLuint()> TextureIdCallback; AsyncPixelTransferDelegateIdle( AsyncPixelTransferManagerIdle::SharedState* state, - GLuint texture_id, + const TextureIdCallback& texture_id_callback, const AsyncTexImage2DParams& define_params); ~AsyncPixelTransferDelegateIdle() override; @@ -55,7 +56,7 @@ class AsyncPixelTransferDelegateIdle AsyncMemoryParams mem_params); uint64 id_; - GLuint texture_id_; + TextureIdCallback texture_id_callback_; bool transfer_in_progress_; AsyncTexImage2DParams define_params_; @@ -68,10 +69,10 @@ class AsyncPixelTransferDelegateIdle AsyncPixelTransferDelegateIdle::AsyncPixelTransferDelegateIdle( AsyncPixelTransferManagerIdle::SharedState* shared_state, - GLuint texture_id, + const TextureIdCallback& texture_id_callback, const AsyncTexImage2DParams& define_params) : id_(g_next_pixel_transfer_state_id++), - texture_id_(texture_id), + texture_id_callback_(texture_id_callback), transfer_in_progress_(false), define_params_(define_params), shared_state_(shared_state) {} @@ -144,8 +145,9 @@ void AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D( void* data = mem_params.GetDataAddress(); - base::TimeTicks begin_time(base::TimeTicks::HighResNow()); - gfx::ScopedTextureBinder texture_binder(tex_params.target, texture_id_); + base::TimeTicks begin_time(base::TimeTicks::Now()); + gfx::ScopedTextureBinder texture_binder(tex_params.target, + texture_id_callback_.Run()); { TRACE_EVENT0("gpu", "glTexImage2D"); @@ -165,7 +167,7 @@ void AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D( transfer_in_progress_ = false; shared_state_->texture_upload_count++; shared_state_->total_texture_upload_time += - base::TimeTicks::HighResNow() - begin_time; + base::TimeTicks::Now() - begin_time; // The texture is already fully bound so just call it now. bind_callback.Run(); @@ -180,12 +182,12 @@ void AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D( void* data = mem_params.GetDataAddress(); - base::TimeTicks begin_time(base::TimeTicks::HighResNow()); - gfx::ScopedTextureBinder texture_binder(tex_params.target, texture_id_); + base::TimeTicks begin_time(base::TimeTicks::Now()); + gfx::ScopedTextureBinder texture_binder(tex_params.target, + texture_id_callback_.Run()); - // If it's a full texture update, use glTexImage2D as it's faster. - // TODO(epenner): Make this configurable (http://crbug.com/259924) - if (tex_params.xoffset == 0 && + if (shared_state_->use_teximage2d_over_texsubimage2d && + tex_params.xoffset == 0 && tex_params.yoffset == 0 && tex_params.target == define_params_.target && tex_params.level == define_params_.level && @@ -220,7 +222,7 @@ void AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D( transfer_in_progress_ = false; shared_state_->texture_upload_count++; shared_state_->total_texture_upload_time += - base::TimeTicks::HighResNow() - begin_time; + base::TimeTicks::Now() - begin_time; } AsyncPixelTransferManagerIdle::Task::Task( @@ -234,8 +236,11 @@ AsyncPixelTransferManagerIdle::Task::Task( AsyncPixelTransferManagerIdle::Task::~Task() {} -AsyncPixelTransferManagerIdle::SharedState::SharedState() - : texture_upload_count(0) {} +AsyncPixelTransferManagerIdle::SharedState::SharedState( + bool use_teximage2d_over_texsubimage2d) + : use_teximage2d_over_texsubimage2d(use_teximage2d_over_texsubimage2d), + texture_upload_count(0) { +} AsyncPixelTransferManagerIdle::SharedState::~SharedState() {} @@ -250,8 +255,9 @@ void AsyncPixelTransferManagerIdle::SharedState::ProcessNotificationTasks() { } } -AsyncPixelTransferManagerIdle::AsyncPixelTransferManagerIdle() - : shared_state_() { +AsyncPixelTransferManagerIdle::AsyncPixelTransferManagerIdle( + bool use_teximage2d_over_texsubimage2d) + : shared_state_(use_teximage2d_over_texsubimage2d) { } AsyncPixelTransferManagerIdle::~AsyncPixelTransferManagerIdle() {} @@ -314,9 +320,15 @@ AsyncPixelTransferDelegate* AsyncPixelTransferManagerIdle::CreatePixelTransferDelegateImpl( gles2::TextureRef* ref, const AsyncTexImage2DParams& define_params) { - return new AsyncPixelTransferDelegateIdle(&shared_state_, - ref->service_id(), - define_params); + return new AsyncPixelTransferDelegateIdle( + &shared_state_, + // Not directly passing texture_ref->service_id here because it can change + // if avoid_egl_image_target_texture_reuse workaround is in effect. + // Unretained is safe because AsyncPixelTransferManager observes + // TextureRef destruction and destroys the delegate before TextureRef + // is destroyed. + base::Bind(&gles2::TextureRef::service_id, base::Unretained(ref)), + define_params); } } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h index 8aba7ff95ec..41a77b397dc 100644 --- a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h +++ b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h @@ -13,7 +13,8 @@ namespace gpu { class AsyncPixelTransferManagerIdle : public AsyncPixelTransferManager { public: - AsyncPixelTransferManagerIdle(); + explicit AsyncPixelTransferManagerIdle( + bool use_teximage2d_over_texsubimage2d); ~AsyncPixelTransferManagerIdle() override; // AsyncPixelTransferManager implementation: @@ -43,10 +44,11 @@ class AsyncPixelTransferManagerIdle : public AsyncPixelTransferManager { // State shared between Managers and Delegates. struct SharedState { - SharedState(); + explicit SharedState(bool use_teximage2d_over_texsubimage2d); ~SharedState(); void ProcessNotificationTasks(); + const bool use_teximage2d_over_texsubimage2d; int texture_upload_count; base::TimeDelta total_texture_upload_time; std::list<Task> tasks; diff --git a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_linux.cc b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_linux.cc index 8d25f00a0e4..b0cc463eb27 100644 --- a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_linux.cc +++ b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_linux.cc @@ -5,7 +5,7 @@ #include "gpu/command_buffer/service/async_pixel_transfer_manager.h" #include "base/command_line.h" -#include "base/debug/trace_event.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/service/async_pixel_transfer_manager_idle.h" #include "gpu/command_buffer/service/async_pixel_transfer_manager_share_group.h" #include "gpu/command_buffer/service/async_pixel_transfer_manager_stub.h" @@ -17,7 +17,7 @@ namespace gpu { AsyncPixelTransferManager* AsyncPixelTransferManager::Create( gfx::GLContext* context) { TRACE_EVENT0("gpu", "AsyncPixelTransferManager::Create"); - if (CommandLine::ForCurrentProcess()->HasSwitch( + if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableShareGroupAsyncTextureUpload)) { DCHECK(context); return static_cast<AsyncPixelTransferManager*> ( @@ -28,7 +28,7 @@ AsyncPixelTransferManager* AsyncPixelTransferManager::Create( case gfx::kGLImplementationOSMesaGL: case gfx::kGLImplementationDesktopGL: case gfx::kGLImplementationEGLGLES2: - return new AsyncPixelTransferManagerIdle; + return new AsyncPixelTransferManagerIdle(true); case gfx::kGLImplementationMockGL: return new AsyncPixelTransferManagerStub; default: diff --git a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc index 8c19b57d2fb..6d8562f1155 100644 --- a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc +++ b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc @@ -4,7 +4,7 @@ #include "gpu/command_buffer/service/async_pixel_transfer_manager.h" -#include "base/debug/trace_event.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/service/async_pixel_transfer_manager_idle.h" #include "gpu/command_buffer/service/async_pixel_transfer_manager_stub.h" #include "ui/gl/gl_implementation.h" @@ -17,8 +17,9 @@ AsyncPixelTransferManager* AsyncPixelTransferManager::Create( switch (gfx::GetGLImplementation()) { case gfx::kGLImplementationOSMesaGL: case gfx::kGLImplementationDesktopGL: + case gfx::kGLImplementationDesktopGLCoreProfile: case gfx::kGLImplementationAppleGL: - return new AsyncPixelTransferManagerIdle; + return new AsyncPixelTransferManagerIdle(true); case gfx::kGLImplementationMockGL: return new AsyncPixelTransferManagerStub; default: diff --git a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc index b6506bfb584..3c65f7210b0 100644 --- a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc +++ b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc @@ -7,17 +7,19 @@ #include <list> #include "base/bind.h" -#include "base/debug/trace_event.h" -#include "base/debug/trace_event_synthetic_delay.h" #include "base/lazy_instance.h" +#include "base/location.h" #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/single_thread_task_runner.h" #include "base/synchronization/cancellation_flag.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" #include "base/threading/thread_checker.h" +#include "base/trace_event/trace_event.h" +#include "base/trace_event/trace_event_synthetic_delay.h" #include "gpu/command_buffer/service/async_pixel_transfer_delegate.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" @@ -47,7 +49,7 @@ class TransferThread : public base::Thread { initialized_(false) { Start(); #if defined(OS_ANDROID) || defined(OS_LINUX) - SetPriority(base::kThreadPriority_Background); + SetPriority(base::ThreadPriority::BACKGROUND); #endif } @@ -62,12 +64,11 @@ class TransferThread : public base::Thread { return; base::WaitableEvent wait_for_init(true, false); - message_loop_proxy()->PostTask( - FROM_HERE, - base::Bind(&TransferThread::InitializeOnTransferThread, - base::Unretained(this), - base::Unretained(parent_context), - &wait_for_init)); + task_runner()->PostTask( + FROM_HERE, + base::Bind(&TransferThread::InitializeOnTransferThread, + base::Unretained(this), base::Unretained(parent_context), + &wait_for_init)); wait_for_init.Wait(); } @@ -123,8 +124,8 @@ class TransferThread : public base::Thread { base::LazyInstance<TransferThread>::Leaky g_transfer_thread = LAZY_INSTANCE_INITIALIZER; -base::MessageLoopProxy* transfer_message_loop_proxy() { - return g_transfer_thread.Pointer()->message_loop_proxy().get(); +base::SingleThreadTaskRunner* transfer_task_runner() { + return g_transfer_thread.Pointer()->task_runner().get(); } class PendingTask : public base::RefCountedThreadSafe<PendingTask> { @@ -246,10 +247,9 @@ class TransferStateInternal tex_params, mem_params, texture_upload_stats)); - transfer_message_loop_proxy()->PostTask( - FROM_HERE, - base::Bind( - &PendingTask::BindAndRun, pending_upload_task_, texture_id_)); + transfer_task_runner()->PostTask( + FROM_HERE, base::Bind(&PendingTask::BindAndRun, pending_upload_task_, + texture_id_)); // Save the late bind callback, so we can notify the client when it is // bound. @@ -267,10 +267,9 @@ class TransferStateInternal tex_params, mem_params, texture_upload_stats)); - transfer_message_loop_proxy()->PostTask( - FROM_HERE, - base::Bind( - &PendingTask::BindAndRun, pending_upload_task_, texture_id_)); + transfer_task_runner()->PostTask( + FROM_HERE, base::Bind(&PendingTask::BindAndRun, pending_upload_task_, + texture_id_)); } private: @@ -293,7 +292,7 @@ class TransferStateInternal base::TimeTicks begin_time; if (texture_upload_stats.get()) - begin_time = base::TimeTicks::HighResNow(); + begin_time = base::TimeTicks::Now(); void* data = mem_params.GetDataAddress(); @@ -312,8 +311,7 @@ class TransferStateInternal } if (texture_upload_stats.get()) { - texture_upload_stats->AddUpload(base::TimeTicks::HighResNow() - - begin_time); + texture_upload_stats->AddUpload(base::TimeTicks::Now() - begin_time); } } @@ -331,7 +329,7 @@ class TransferStateInternal base::TimeTicks begin_time; if (texture_upload_stats.get()) - begin_time = base::TimeTicks::HighResNow(); + begin_time = base::TimeTicks::Now(); void* data = mem_params.GetDataAddress(); { @@ -349,8 +347,7 @@ class TransferStateInternal } if (texture_upload_stats.get()) { - texture_upload_stats->AddUpload(base::TimeTicks::HighResNow() - - begin_time); + texture_upload_stats->AddUpload(base::TimeTicks::Now() - begin_time); } } @@ -507,11 +504,9 @@ void AsyncPixelTransferManagerShareGroup::AsyncNotifyCompletion( AsyncPixelTransferCompletionObserver* observer) { // Post a PerformNotifyCompletion task to the upload thread. This task // will run after all async transfers are complete. - transfer_message_loop_proxy()->PostTask( - FROM_HERE, - base::Bind(&PerformNotifyCompletion, - mem_params, - make_scoped_refptr(observer))); + transfer_task_runner()->PostTask( + FROM_HERE, base::Bind(&PerformNotifyCompletion, mem_params, + make_scoped_refptr(observer))); } uint32 AsyncPixelTransferManagerShareGroup::GetTextureUploadCount() { diff --git a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc index 4bc2ba20ea0..589598bca8f 100644 --- a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc +++ b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc @@ -45,7 +45,7 @@ void AsyncPixelTransferDelegateSync::AsyncTexImage2D( // Save the define params to return later during deferred // binding of the transfer texture. void* data = mem_params.GetDataAddress(); - base::TimeTicks begin_time(base::TimeTicks::HighResNow()); + base::TimeTicks begin_time(base::TimeTicks::Now()); glTexImage2D( tex_params.target, tex_params.level, @@ -58,7 +58,7 @@ void AsyncPixelTransferDelegateSync::AsyncTexImage2D( data); shared_state_->texture_upload_count++; shared_state_->total_texture_upload_time += - base::TimeTicks::HighResNow() - begin_time; + base::TimeTicks::Now() - begin_time; // The texture is already fully bound so just call it now. bind_callback.Run(); } @@ -67,7 +67,7 @@ void AsyncPixelTransferDelegateSync::AsyncTexSubImage2D( const AsyncTexSubImage2DParams& tex_params, const AsyncMemoryParams& mem_params) { void* data = mem_params.GetDataAddress(); - base::TimeTicks begin_time(base::TimeTicks::HighResNow()); + base::TimeTicks begin_time(base::TimeTicks::Now()); glTexSubImage2D( tex_params.target, tex_params.level, @@ -80,7 +80,7 @@ void AsyncPixelTransferDelegateSync::AsyncTexSubImage2D( data); shared_state_->texture_upload_count++; shared_state_->total_texture_upload_time += - base::TimeTicks::HighResNow() - begin_time; + base::TimeTicks::Now() - begin_time; } bool AsyncPixelTransferDelegateSync::TransferIsInProgress() { diff --git a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_win.cc b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_win.cc index 69558855d5f..dc106e8316d 100644 --- a/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_win.cc +++ b/chromium/gpu/command_buffer/service/async_pixel_transfer_manager_win.cc @@ -4,7 +4,7 @@ #include "gpu/command_buffer/service/async_pixel_transfer_manager.h" -#include "base/debug/trace_event.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/service/async_pixel_transfer_manager_idle.h" #include "gpu/command_buffer/service/async_pixel_transfer_manager_stub.h" #include "ui/gl/gl_implementation.h" @@ -18,7 +18,7 @@ AsyncPixelTransferManager* AsyncPixelTransferManager::Create( case gfx::kGLImplementationOSMesaGL: case gfx::kGLImplementationDesktopGL: case gfx::kGLImplementationEGLGLES2: - return new AsyncPixelTransferManagerIdle; + return new AsyncPixelTransferManagerIdle(true); case gfx::kGLImplementationMockGL: return new AsyncPixelTransferManagerStub; default: diff --git a/chromium/gpu/command_buffer/service/buffer_manager.cc b/chromium/gpu/command_buffer/service/buffer_manager.cc index 7b1c90dfbb3..c2a0ba5c297 100644 --- a/chromium/gpu/command_buffer/service/buffer_manager.cc +++ b/chromium/gpu/command_buffer/service/buffer_manager.cc @@ -4,14 +4,15 @@ #include "gpu/command_buffer/service/buffer_manager.h" #include <limits> -#include "base/debug/trace_event.h" #include "base/logging.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/error_state.h" #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_implementation.h" namespace gpu { namespace gles2 { @@ -23,6 +24,7 @@ BufferManager::BufferManager( new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)), feature_info_(feature_info), allow_buffers_on_multiple_targets_(false), + allow_fixed_attribs_(false), buffer_count_(0), have_context_(true), use_client_side_arrays_for_stream_buffers_( @@ -72,6 +74,27 @@ void BufferManager::StopTracking(Buffer* buffer) { --buffer_count_; } +Buffer::MappedRange::MappedRange( + GLintptr offset, GLsizeiptr size, GLenum access, void* pointer, + scoped_refptr<gpu::Buffer> shm) + : offset(offset), + size(size), + access(access), + pointer(pointer), + shm(shm) { + DCHECK(pointer); + DCHECK(shm.get() && GetShmPointer()); +} + +Buffer::MappedRange::~MappedRange() { +} + +void* Buffer::MappedRange::GetShmPointer() const { + DCHECK(shm.get()); + return shm->GetDataAddress(static_cast<unsigned int>(offset), + static_cast<unsigned int>(size)); +} + Buffer::Buffer(BufferManager* manager, GLuint service_id) : manager_(manager), size_(0), @@ -117,6 +140,7 @@ void Buffer::SetInfo( memset(shadow_.get(), 0, size); } } + mapped_range_.reset(nullptr); } bool Buffer::CheckRange( @@ -251,10 +275,13 @@ void BufferManager::SetInfo( Buffer* buffer, GLsizeiptr size, GLenum usage, const GLvoid* data) { DCHECK(buffer); memory_tracker_->TrackMemFree(buffer->size()); - bool is_client_side_array = IsUsageClientSideArray(usage); - bool shadow = buffer->target() == GL_ELEMENT_ARRAY_BUFFER || - allow_buffers_on_multiple_targets_ || - is_client_side_array; + const bool is_client_side_array = IsUsageClientSideArray(usage); + const bool support_fixed_attribs = + gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; + const bool shadow = buffer->target() == GL_ELEMENT_ARRAY_BUFFER || + allow_buffers_on_multiple_targets_ || + (allow_fixed_attribs_ && !support_fixed_attribs) || + is_client_side_array; buffer->SetInfo(size, usage, shadow, data, is_client_side_array); memory_tracker_->TrackMemAlloc(buffer->size()); } @@ -392,12 +419,23 @@ bool BufferManager::SetTarget(Buffer* buffer, GLenum target) { // Since one BufferManager can be shared by multiple decoders, ContextState is // passed in each time and not just passed in during initialization. Buffer* BufferManager::GetBufferInfoForTarget( - ContextState* state, GLenum target) { - DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER); - if (target == GL_ARRAY_BUFFER) { - return state->bound_array_buffer.get(); - } else { - return state->vertex_attrib_manager->element_array_buffer(); + ContextState* state, GLenum target) const { + switch (target) { + case GL_ARRAY_BUFFER: + return state->bound_array_buffer.get(); + case GL_ELEMENT_ARRAY_BUFFER: + return state->vertex_attrib_manager->element_array_buffer(); + case GL_COPY_READ_BUFFER: + case GL_COPY_WRITE_BUFFER: + case GL_PIXEL_PACK_BUFFER: + case GL_PIXEL_UNPACK_BUFFER: + case GL_TRANSFORM_FEEDBACK_BUFFER: + case GL_UNIFORM_BUFFER: + NOTIMPLEMENTED(); + return nullptr; + default: + NOTREACHED(); + return nullptr; } } diff --git a/chromium/gpu/command_buffer/service/buffer_manager.h b/chromium/gpu/command_buffer/service/buffer_manager.h index cc23f01604b..29bfaf4d431 100644 --- a/chromium/gpu/command_buffer/service/buffer_manager.h +++ b/chromium/gpu/command_buffer/service/buffer_manager.h @@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "gpu/command_buffer/common/buffer.h" #include "gpu/command_buffer/service/gl_utils.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "gpu/gpu_export.h" @@ -27,6 +28,19 @@ class TestHelper; // Info about Buffers currently in the system. class GPU_EXPORT Buffer : public base::RefCounted<Buffer> { public: + struct MappedRange { + GLintptr offset; + GLsizeiptr size; + GLenum access; + void* pointer; // Pointer returned by driver. + scoped_refptr<gpu::Buffer> shm; // Client side mem. + + MappedRange(GLintptr offset, GLsizeiptr size, GLenum access, + void* pointer, scoped_refptr<gpu::Buffer> shm); + ~MappedRange(); + void* GetShmPointer() const; + }; + Buffer(BufferManager* manager, GLuint service_id); GLuint service_id() const { @@ -67,6 +81,19 @@ class GPU_EXPORT Buffer : public base::RefCounted<Buffer> { return is_client_side_array_; } + void SetMappedRange(GLintptr offset, GLsizeiptr size, GLenum access, + void* pointer, scoped_refptr<gpu::Buffer> shm) { + mapped_range_.reset(new MappedRange(offset, size, access, pointer, shm)); + } + + void RemoveMappedRange() { + mapped_range_.reset(nullptr); + } + + const MappedRange* GetMappedRange() const { + return mapped_range_.get(); + } + private: friend class BufferManager; friend class BufferManagerTestBase; @@ -163,6 +190,9 @@ class GPU_EXPORT Buffer : public base::RefCounted<Buffer> { // Usage of buffer. GLenum usage_; + // Data cached from last glMapBufferRange call. + scoped_ptr<MappedRange> mapped_range_; + // A map of ranges to the highest value in that range of a certain type. typedef std::map<Range, GLuint, Range::Less> RangeToMaxValueMap; RangeToMaxValueMap range_set_; @@ -217,6 +247,10 @@ class GPU_EXPORT BufferManager { allow_buffers_on_multiple_targets_ = allow; } + void set_allow_fixed_attribs(bool allow) { + allow_fixed_attribs_ = allow; + } + size_t mem_represented() const { return memory_tracker_->GetMemRepresented(); } @@ -228,15 +262,16 @@ class GPU_EXPORT BufferManager { // set to a non-zero size. bool UseNonZeroSizeForClientSideArrayBuffer(); + Buffer* GetBufferInfoForTarget(ContextState* state, GLenum target) const; + private: friend class Buffer; friend class TestHelper; // Needs access to DoBufferData. friend class BufferManagerTestBase; // Needs access to DoBufferSubData. + void StartTracking(Buffer* buffer); void StopTracking(Buffer* buffer); - Buffer* GetBufferInfoForTarget(ContextState* state, GLenum target); - // Does a glBufferSubData and updates the approriate accounting. // Assumes the values have already been validated. void DoBufferSubData( @@ -270,6 +305,9 @@ class GPU_EXPORT BufferManager { // Whether or not buffers can be bound to multiple targets. bool allow_buffers_on_multiple_targets_; + // Whether or not allow using GL_FIXED type for vertex attribs. + bool allow_fixed_attribs_; + // Counts the number of Buffer allocated with 'this' as its manager. // Allows to check no Buffer will outlive this. unsigned int buffer_count_; diff --git a/chromium/gpu/command_buffer/service/buffer_manager_unittest.cc b/chromium/gpu/command_buffer/service/buffer_manager_unittest.cc index 5c24eb0ee8f..bef00896e69 100644 --- a/chromium/gpu/command_buffer/service/buffer_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/buffer_manager_unittest.cc @@ -210,21 +210,21 @@ TEST_F(BufferManagerTest, DoBufferSubData) { TEST_F(BufferManagerTest, GetRange) { const GLuint kClientBufferId = 1; const GLuint kServiceBufferId = 11; - const uint8 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; + const GLsizeiptr kDataSize = 10; manager_->CreateBuffer(kClientBufferId, kServiceBufferId); Buffer* buffer = manager_->GetBuffer(kClientBufferId); ASSERT_TRUE(buffer != NULL); manager_->SetTarget(buffer, GL_ELEMENT_ARRAY_BUFFER); - DoBufferData(buffer, sizeof(data), GL_STATIC_DRAW, NULL, GL_NO_ERROR); + DoBufferData(buffer, kDataSize, GL_STATIC_DRAW, NULL, GL_NO_ERROR); const char* buf = - static_cast<const char*>(buffer->GetRange(0, sizeof(data))); + static_cast<const char*>(buffer->GetRange(0, kDataSize)); ASSERT_TRUE(buf != NULL); const char* buf1 = - static_cast<const char*>(buffer->GetRange(1, sizeof(data) - 1)); + static_cast<const char*>(buffer->GetRange(1, kDataSize - 1)); EXPECT_EQ(buf + 1, buf1); - EXPECT_TRUE(buffer->GetRange(sizeof(data), 1) == NULL); - EXPECT_TRUE(buffer->GetRange(0, sizeof(data) + 1) == NULL); - EXPECT_TRUE(buffer->GetRange(-1, sizeof(data)) == NULL); + EXPECT_TRUE(buffer->GetRange(kDataSize, 1) == NULL); + EXPECT_TRUE(buffer->GetRange(0, kDataSize + 1) == NULL); + EXPECT_TRUE(buffer->GetRange(-1, kDataSize) == NULL); EXPECT_TRUE(buffer->GetRange(-0, -1) == NULL); const int size = 0x20000; DoBufferData(buffer, size / 2, GL_STATIC_DRAW, NULL, GL_NO_ERROR); @@ -350,7 +350,7 @@ TEST_F(BufferManagerTest, GetMaxValueForRangeUint32) { TEST_F(BufferManagerTest, UseDeletedBuffer) { const GLuint kClientBufferId = 1; const GLuint kServiceBufferId = 11; - const uint32 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; + const GLsizeiptr kDataSize = 10; manager_->CreateBuffer(kClientBufferId, kServiceBufferId); scoped_refptr<Buffer> buffer = manager_->GetBuffer(kClientBufferId); ASSERT_TRUE(buffer.get() != NULL); @@ -358,7 +358,7 @@ TEST_F(BufferManagerTest, UseDeletedBuffer) { // Remove buffer manager_->RemoveBuffer(kClientBufferId); // Use it after removing - DoBufferData(buffer.get(), sizeof(data), GL_STATIC_DRAW, NULL, GL_NO_ERROR); + DoBufferData(buffer.get(), kDataSize, GL_STATIC_DRAW, NULL, GL_NO_ERROR); // Check that it gets deleted when the last reference is released. EXPECT_CALL(*gl_, DeleteBuffersARB(1, ::testing::Pointee(kServiceBufferId))) .Times(1) diff --git a/chromium/gpu/command_buffer/service/cmd_parser.cc b/chromium/gpu/command_buffer/service/cmd_parser.cc index ffcdfff7645..d7dfc596267 100644 --- a/chromium/gpu/command_buffer/service/cmd_parser.cc +++ b/chromium/gpu/command_buffer/service/cmd_parser.cc @@ -7,7 +7,7 @@ #include "gpu/command_buffer/service/cmd_parser.h" #include "base/logging.h" -#include "base/debug/trace_event.h" +#include "base/trace_event/trace_event.h" namespace gpu { diff --git a/chromium/gpu/command_buffer/service/command_buffer_service.cc b/chromium/gpu/command_buffer/service/command_buffer_service.cc index 1453a0acfb8..f2444b31e9f 100644 --- a/chromium/gpu/command_buffer/service/command_buffer_service.cc +++ b/chromium/gpu/command_buffer/service/command_buffer_service.cc @@ -7,7 +7,7 @@ #include <limits> #include "base/logging.h" -#include "base/debug/trace_event.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/common/cmd_buffer_common.h" #include "gpu/command_buffer/common/command_buffer_shared.h" #include "gpu/command_buffer/service/transfer_buffer_manager.h" @@ -79,6 +79,10 @@ void CommandBufferService::Flush(int32 put_offset) { put_offset_change_callback_.Run(); } +void CommandBufferService::OrderingBarrier(int32 put_offset) { + Flush(put_offset); +} + void CommandBufferService::SetGetBuffer(int32 transfer_buffer_id) { DCHECK_EQ(-1, ring_buffer_id_); DCHECK_EQ(put_offset_, get_offset_); // Only if it's empty. diff --git a/chromium/gpu/command_buffer/service/command_buffer_service.h b/chromium/gpu/command_buffer/service/command_buffer_service.h index 69b9ad76eb9..28a5f6f7a9b 100644 --- a/chromium/gpu/command_buffer/service/command_buffer_service.h +++ b/chromium/gpu/command_buffer/service/command_buffer_service.h @@ -52,6 +52,7 @@ class GPU_EXPORT CommandBufferService : public CommandBufferServiceBase { State GetLastState() override; int32 GetLastToken() override; void Flush(int32 put_offset) override; + void OrderingBarrier(int32 put_offset) override; void WaitForTokenInRange(int32 start, int32 end) override; void WaitForGetOffsetInRange(int32 start, int32 end) override; void SetGetBuffer(int32 transfer_buffer_id) override; diff --git a/chromium/gpu/command_buffer/service/common_decoder.cc b/chromium/gpu/command_buffer/service/common_decoder.cc index 86a37ba77e5..99fdb765a08 100644 --- a/chromium/gpu/command_buffer/service/common_decoder.cc +++ b/chromium/gpu/command_buffer/service/common_decoder.cc @@ -3,10 +3,25 @@ // found in the LICENSE file. #include "gpu/command_buffer/service/common_decoder.h" + +#include "base/numerics/safe_math.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" namespace gpu { +const CommonDecoder::CommandInfo CommonDecoder::command_info[] = { +#define COMMON_COMMAND_BUFFER_CMD_OP(name) \ + { \ + &CommonDecoder::Handle##name, cmd::name::kArgFlags, \ + cmd::name::cmd_flags, \ + sizeof(cmd::name) / sizeof(CommandBufferEntry) - 1, \ + } \ + , /* NOLINT */ + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + #undef COMMON_COMMAND_BUFFER_CMD_OP +}; + + CommonDecoder::Bucket::Bucket() : size_(0) {} CommonDecoder::Bucket::~Bucket() {} @@ -56,6 +71,53 @@ bool CommonDecoder::Bucket::GetAsString(std::string* str) { return true; } +bool CommonDecoder::Bucket::GetAsStrings( + GLsizei* _count, std::vector<char*>* _string, std::vector<GLint>* _length) { + const size_t kMinBucketSize = sizeof(GLint); + // Each string has at least |length| in the header and a NUL character. + const size_t kMinStringSize = sizeof(GLint) + 1; + const size_t bucket_size = this->size(); + if (bucket_size < kMinBucketSize) { + return false; + } + char* bucket_data = this->GetDataAs<char*>(0, bucket_size); + GLint* header = reinterpret_cast<GLint*>(bucket_data); + GLsizei count = static_cast<GLsizei>(header[0]); + if (count < 0) { + return false; + } + const size_t max_count = (bucket_size - kMinBucketSize) / kMinStringSize; + if (max_count < static_cast<size_t>(count)) { + return false; + } + GLint* length = header + 1; + std::vector<char*> strs(count); + base::CheckedNumeric<size_t> total_size = sizeof(GLint); + total_size *= count + 1; // Header size. + if (!total_size.IsValid()) + return false; + for (GLsizei ii = 0; ii < count; ++ii) { + strs[ii] = bucket_data + total_size.ValueOrDefault(0); + total_size += length[ii]; + total_size += 1; // NUL char at the end of each char array. + if (!total_size.IsValid() || total_size.ValueOrDefault(0) > bucket_size || + strs[ii][length[ii]] != 0) { + return false; + } + } + if (total_size.ValueOrDefault(0) != bucket_size) { + return false; + } + DCHECK(_count && _string && _length); + *_count = count; + *_string = strs; + _length->resize(count); + for (GLsizei ii = 0; ii < count; ++ii) { + (*_length)[ii] = length[ii]; + } + return true; +} + CommonDecoder::CommonDecoder() : engine_(NULL) {} CommonDecoder::~CommonDecoder() {} @@ -108,29 +170,6 @@ RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) { return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))); } -// TODO(vmiura): Looks like this g_command_info is duplicated in -// common_decoder.cc -// and gles2_cmd_decoder.cc. Fix it! - -// A struct to hold info about each command. -struct CommandInfo { - uint8 arg_flags; // How to handle the arguments for this command - uint8 cmd_flags; // How to handle this command - uint16 arg_count; // How many arguments are expected for this command. -}; - -// A table of CommandInfo for all the commands. -const CommandInfo g_command_info[] = { - #define COMMON_COMMAND_BUFFER_CMD_OP(name) { \ - cmd::name::kArgFlags, \ - cmd::name::cmd_flags, \ - sizeof(cmd::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ - - COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) - - #undef COMMON_COMMAND_BUFFER_CMD_OP -}; - } // anonymous namespace. // Decode command with its arguments, and call the corresponding method. @@ -141,24 +180,14 @@ error::Error CommonDecoder::DoCommonCommand( unsigned int command, unsigned int arg_count, const void* cmd_data) { - if (command < arraysize(g_command_info)) { - const CommandInfo& info = g_command_info[command]; + if (command < arraysize(command_info)) { + const CommandInfo& info = command_info[command]; unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { uint32 immediate_data_size = (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT - switch (command) { - #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ - case cmd::name::kCmdId: \ - return Handle ## name( \ - immediate_data_size, \ - *static_cast<const cmd::name*>(cmd_data)); \ - - COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) - - #undef COMMON_COMMAND_BUFFER_CMD_OP - } + return (this->*info.cmd_handler)(immediate_data_size, cmd_data); } else { return error::kInvalidArguments; } @@ -168,20 +197,23 @@ error::Error CommonDecoder::DoCommonCommand( error::Error CommonDecoder::HandleNoop( uint32 immediate_data_size, - const cmd::Noop& args) { + const void* cmd_data) { return error::kNoError; } error::Error CommonDecoder::HandleSetToken( uint32 immediate_data_size, - const cmd::SetToken& args) { + const void* cmd_data) { + const cmd::SetToken& args = *static_cast<const cmd::SetToken*>(cmd_data); engine_->set_token(args.token); return error::kNoError; } error::Error CommonDecoder::HandleSetBucketSize( uint32 immediate_data_size, - const cmd::SetBucketSize& args) { + const void* cmd_data) { + const cmd::SetBucketSize& args = + *static_cast<const cmd::SetBucketSize*>(cmd_data); uint32 bucket_id = args.bucket_id; uint32 size = args.size; @@ -192,7 +224,9 @@ error::Error CommonDecoder::HandleSetBucketSize( error::Error CommonDecoder::HandleSetBucketData( uint32 immediate_data_size, - const cmd::SetBucketData& args) { + const void* cmd_data) { + const cmd::SetBucketData& args = + *static_cast<const cmd::SetBucketData*>(cmd_data); uint32 bucket_id = args.bucket_id; uint32 offset = args.offset; uint32 size = args.size; @@ -214,7 +248,9 @@ error::Error CommonDecoder::HandleSetBucketData( error::Error CommonDecoder::HandleSetBucketDataImmediate( uint32 immediate_data_size, - const cmd::SetBucketDataImmediate& args) { + const void* cmd_data) { + const cmd::SetBucketDataImmediate& args = + *static_cast<const cmd::SetBucketDataImmediate*>(cmd_data); const void* data = GetImmediateDataAs<const void*>(args); uint32 bucket_id = args.bucket_id; uint32 offset = args.offset; @@ -234,7 +270,9 @@ error::Error CommonDecoder::HandleSetBucketDataImmediate( error::Error CommonDecoder::HandleGetBucketStart( uint32 immediate_data_size, - const cmd::GetBucketStart& args) { + const void* cmd_data) { + const cmd::GetBucketStart& args = + *static_cast<const cmd::GetBucketStart*>(cmd_data); uint32 bucket_id = args.bucket_id; uint32* result = GetSharedMemoryAs<uint32*>( args.result_memory_id, args.result_memory_offset, sizeof(*result)); @@ -271,7 +309,9 @@ error::Error CommonDecoder::HandleGetBucketStart( error::Error CommonDecoder::HandleGetBucketData( uint32 immediate_data_size, - const cmd::GetBucketData& args) { + const void* cmd_data) { + const cmd::GetBucketData& args = + *static_cast<const cmd::GetBucketData*>(cmd_data); uint32 bucket_id = args.bucket_id; uint32 offset = args.offset; uint32 size = args.size; diff --git a/chromium/gpu/command_buffer/service/common_decoder.h b/chromium/gpu/command_buffer/service/common_decoder.h index aaf860fd7b3..53de875625a 100644 --- a/chromium/gpu/command_buffer/service/common_decoder.h +++ b/chromium/gpu/command_buffer/service/common_decoder.h @@ -14,6 +14,10 @@ #include "gpu/command_buffer/service/cmd_parser.h" #include "gpu/gpu_export.h" +// Forwardly declare a few GL types to avoid including GL header files. +typedef int GLsizei; +typedef int GLint; + namespace gpu { class CommandBufferEngine; @@ -82,6 +86,13 @@ class GPU_EXPORT CommonDecoder : NON_EXPORTED_BASE(public AsyncAPIInterface) { // is no string. bool GetAsString(std::string* str); + // Gets the bucket data as strings. + // On success, the number of strings are in |_count|, the string data are + // in |_string|, and string sizes are in |_length|.. + bool GetAsStrings(GLsizei* _count, + std::vector<char*>* _string, + std::vector<GLint>* _length); + private: bool OffsetSizeValid(size_t offset, size_t size) const { size_t temp = offset + size; @@ -155,9 +166,7 @@ class GPU_EXPORT CommonDecoder : NON_EXPORTED_BASE(public AsyncAPIInterface) { // Generate a member function prototype for each command in an automated and // typesafe way. #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ - error::Error Handle##name( \ - uint32 immediate_data_size, \ - const cmd::name& args); \ + error::Error Handle##name(uint32 immediate_data_size, const void* data); COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) @@ -167,6 +176,22 @@ class GPU_EXPORT CommonDecoder : NON_EXPORTED_BASE(public AsyncAPIInterface) { typedef std::map<uint32, linked_ptr<Bucket> > BucketMap; BucketMap buckets_; + + typedef Error (CommonDecoder::*CmdHandler)( + uint32 immediate_data_size, + const void* data); + + // A struct to hold info about each command. + struct CommandInfo { + CmdHandler cmd_handler; + uint8 arg_flags; // How to handle the arguments for this command + uint8 cmd_flags; // How to handle this command + uint16 arg_count; // How many arguments are expected for this command. + }; + + // A table of CommandInfo for all the commands. + static const CommandInfo command_info[]; + }; } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/common_decoder_unittest.cc b/chromium/gpu/command_buffer/service/common_decoder_unittest.cc index 5be7eea5997..31823ec0446 100644 --- a/chromium/gpu/command_buffer/service/common_decoder_unittest.cc +++ b/chromium/gpu/command_buffer/service/common_decoder_unittest.cc @@ -157,14 +157,16 @@ class CommonDecoderTest : public testing::Test { template <typename T> error::Error ExecuteCmd(const T& cmd) { - COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); + static_assert(T::kArgFlags == cmd::kFixed, + "T::kArgFlags should equal cmd::kFixed"); return decoder_.DoCommands( 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd)), 0); } template <typename T> error::Error ExecuteImmediateCmd(const T& cmd, size_t data_size) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + static_assert(T::kArgFlags == cmd::kAtLeastN, + "T::kArgFlags should equal cmd::kAtLeastN"); return decoder_.DoCommands( 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd) + data_size), 0); } diff --git a/chromium/gpu/command_buffer/service/context_group.cc b/chromium/gpu/command_buffer/service/context_group.cc index 6ee57e4c0d2..98ebbdbd033 100644 --- a/chromium/gpu/command_buffer/service/context_group.cc +++ b/chromium/gpu/command_buffer/service/context_group.cc @@ -32,11 +32,15 @@ ContextGroup::ContextGroup( const scoped_refptr<MemoryTracker>& memory_tracker, const scoped_refptr<ShaderTranslatorCache>& shader_translator_cache, const scoped_refptr<FeatureInfo>& feature_info, + const scoped_refptr<SubscriptionRefSet>& subscription_ref_set, + const scoped_refptr<ValueStateMap>& pending_valuebuffer_state, bool bind_generates_resource) : mailbox_manager_(mailbox_manager), memory_tracker_(memory_tracker), shader_translator_cache_(shader_translator_cache), - enforce_gl_minimums_(CommandLine::ForCurrentProcess()->HasSwitch( + subscription_ref_set_(subscription_ref_set), + pending_valuebuffer_state_(pending_valuebuffer_state), + enforce_gl_minimums_(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnforceGLMinimums)), bind_generates_resource_(bind_generates_resource), max_vertex_attribs_(0u), @@ -54,6 +58,10 @@ ContextGroup::ContextGroup( { if (!mailbox_manager_.get()) mailbox_manager_ = new MailboxManagerImpl; + if (!subscription_ref_set_.get()) + subscription_ref_set_ = new SubscriptionRefSet(); + if (!pending_valuebuffer_state_.get()) + pending_valuebuffer_state_ = new ValueStateMap(); if (!feature_info.get()) feature_info_ = new FeatureInfo; TransferBufferManager* manager = new TransferBufferManager(); @@ -89,7 +97,8 @@ bool ContextGroup::Initialize( GL_MAX_RENDERBUFFER_SIZE, kMinRenderbufferSize, &max_renderbuffer_size)) { LOG(ERROR) << "ContextGroup::Initialize failed because maximum " - << "renderbuffer size too small."; + << "renderbuffer size too small (" << max_renderbuffer_size + << ", should be " << kMinRenderbufferSize << ")."; return false; } GLint max_samples = 0; @@ -113,17 +122,17 @@ bool ContextGroup::Initialize( draw_buffer_ = GL_BACK; } - const bool depth24_supported = feature_info_->feature_flags().oes_depth24; - buffer_manager_.reset( new BufferManager(memory_tracker_.get(), feature_info_.get())); framebuffer_manager_.reset( new FramebufferManager(max_draw_buffers_, max_color_attachments_)); renderbuffer_manager_.reset(new RenderbufferManager( memory_tracker_.get(), max_renderbuffer_size, max_samples, - depth24_supported)); - valuebuffer_manager_.reset(new ValuebufferManager()); + feature_info_.get())); shader_manager_.reset(new ShaderManager()); + valuebuffer_manager_.reset( + new ValuebufferManager(subscription_ref_set_.get(), + pending_valuebuffer_state_.get())); // Lookup GL things we need to know. const GLint kGLES2RequiredMinimumVertexAttribs = 8u; @@ -146,21 +155,38 @@ bool ContextGroup::Initialize( GLint max_texture_size = 0; GLint max_cube_map_texture_size = 0; + GLint max_rectangle_texture_size = 0; + GLint max_3d_texture_size = 0; + const GLint kMinTextureSize = 2048; // GL actually says 64!?!? + // TODO(zmo): In ES3, max cubemap size is required to be at least 2048. const GLint kMinCubeMapSize = 256; // GL actually says 16!?!? - if (!QueryGLFeature( - GL_MAX_TEXTURE_SIZE, kMinTextureSize, &max_texture_size) || - !QueryGLFeature( - GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMinCubeMapSize, - &max_cube_map_texture_size)) { - LOG(ERROR) << "ContextGroup::Initialize failed because maximum texture size" - << "is too small."; + const GLint kMinRectangleTextureSize = 64; + const GLint kMin3DTextureSize = 256; + + if (!QueryGLFeature(GL_MAX_TEXTURE_SIZE, kMinTextureSize, + &max_texture_size) || + !QueryGLFeature(GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMinCubeMapSize, + &max_cube_map_texture_size) || + (feature_info_->gl_version_info().IsES3Capable() && + !QueryGLFeature(GL_MAX_3D_TEXTURE_SIZE, kMin3DTextureSize, + &max_3d_texture_size)) || + (feature_info_->feature_flags().arb_texture_rectangle && + !QueryGLFeature(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, + kMinRectangleTextureSize, + &max_rectangle_texture_size))) { + LOG(ERROR) << "ContextGroup::Initialize failed because maximum " + << "texture size is too small."; return false; } if (feature_info_->workarounds().max_texture_size) { max_texture_size = std::min( - max_texture_size, feature_info_->workarounds().max_texture_size); + max_texture_size, + feature_info_->workarounds().max_texture_size); + max_rectangle_texture_size = std::min( + max_rectangle_texture_size, + feature_info_->workarounds().max_texture_size); } if (feature_info_->workarounds().max_cube_map_texture_size) { max_cube_map_texture_size = std::min( @@ -172,6 +198,8 @@ bool ContextGroup::Initialize( feature_info_.get(), max_texture_size, max_cube_map_texture_size, + max_rectangle_texture_size, + max_3d_texture_size, bind_generates_resource_)); texture_manager_->set_framebuffer_manager(framebuffer_manager_.get()); @@ -188,7 +216,7 @@ bool ContextGroup::Initialize( return false; } - if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { + if (feature_info_->gl_version_info().BehavesLikeGLES()) { GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &max_fragment_uniform_vectors_); GetIntegerv(GL_MAX_VARYING_VECTORS, &max_varying_vectors_); @@ -302,11 +330,6 @@ void ContextGroup::Destroy(GLES2Decoder* decoder, bool have_context) { renderbuffer_manager_.reset(); } - if (valuebuffer_manager_ != NULL) { - valuebuffer_manager_->Destroy(); - valuebuffer_manager_.reset(); - } - if (texture_manager_ != NULL) { texture_manager_->Destroy(have_context); texture_manager_.reset(); @@ -322,6 +345,11 @@ void ContextGroup::Destroy(GLES2Decoder* decoder, bool have_context) { shader_manager_.reset(); } + if (valuebuffer_manager_ != NULL) { + valuebuffer_manager_->Destroy(); + valuebuffer_manager_.reset(); + } + memory_tracker_ = NULL; } @@ -336,10 +364,10 @@ uint32 ContextGroup::GetMemRepresented() const { return total; } -void ContextGroup::LoseContexts(GLenum reset_status) { +void ContextGroup::LoseContexts(error::ContextLostReason reason) { for (size_t ii = 0; ii < decoders_.size(); ++ii) { if (decoders_[ii].get()) { - decoders_[ii]->LoseContext(reset_status); + decoders_[ii]->MarkContextLost(reason); } } } @@ -383,5 +411,14 @@ bool ContextGroup::QueryGLFeatureU( return result; } +bool ContextGroup::GetBufferServiceId( + GLuint client_id, GLuint* service_id) const { + Buffer* buffer = buffer_manager_->GetBuffer(client_id); + if (!buffer) + return false; + *service_id = buffer->service_id(); + return true; +} + } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/context_group.h b/chromium/gpu/command_buffer/service/context_group.h index eb532528067..f2e832f0fd5 100644 --- a/chromium/gpu/command_buffer/service/context_group.h +++ b/chromium/gpu/command_buffer/service/context_group.h @@ -22,6 +22,7 @@ namespace gpu { class TransferBufferManagerInterface; +class ValueStateMap; namespace gles2 { @@ -34,6 +35,7 @@ class RenderbufferManager; class ProgramManager; class ShaderManager; class TextureManager; +class SubscriptionRefSet; class ValuebufferManager; class MemoryTracker; struct DisallowedFeatures; @@ -47,6 +49,8 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { const scoped_refptr<MemoryTracker>& memory_tracker, const scoped_refptr<ShaderTranslatorCache>& shader_translator_cache, const scoped_refptr<FeatureInfo>& feature_info, + const scoped_refptr<SubscriptionRefSet>& subscription_ref_set, + const scoped_refptr<ValueStateMap>& pending_valuebuffer_state, bool bind_generates_resource); // This should only be called by GLES2Decoder. This must be paired with a @@ -131,6 +135,10 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { return valuebuffer_manager_.get(); } + ValueStateMap* pending_valuebuffer_state() const { + return pending_valuebuffer_state_.get(); + } + TextureManager* texture_manager() const { return texture_manager_.get(); } @@ -158,7 +166,7 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { uint32 GetMemRepresented() const; // Loses all the context associated with this group. - void LoseContexts(GLenum reset_status); + void LoseContexts(error::ContextLostReason reason); // EXT_draw_buffer related states for backbuffer. GLenum draw_buffer() const { @@ -168,6 +176,63 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { draw_buffer_ = buf; } + bool GetBufferServiceId(GLuint client_id, GLuint* service_id) const; + + void AddSamplerId(GLuint client_id, GLuint service_id) { + samplers_id_map_[client_id] = service_id; + } + + bool GetSamplerServiceId(GLuint client_id, GLuint* service_id) const { + base::hash_map<GLuint, GLuint>::const_iterator iter = + samplers_id_map_.find(client_id); + if (iter == samplers_id_map_.end()) + return false; + if (service_id) + *service_id = iter->second; + return true; + } + + void RemoveSamplerId(GLuint client_id) { + samplers_id_map_.erase(client_id); + } + + void AddTransformFeedbackId(GLuint client_id, GLuint service_id) { + transformfeedbacks_id_map_[client_id] = service_id; + } + + bool GetTransformFeedbackServiceId( + GLuint client_id, GLuint* service_id) const { + base::hash_map<GLuint, GLuint>::const_iterator iter = + transformfeedbacks_id_map_.find(client_id); + if (iter == transformfeedbacks_id_map_.end()) + return false; + if (service_id) + *service_id = iter->second; + return true; + } + + void RemoveTransformFeedbackId(GLuint client_id) { + transformfeedbacks_id_map_.erase(client_id); + } + + void AddSyncId(GLuint client_id, GLsync service_id) { + syncs_id_map_[client_id] = service_id; + } + + bool GetSyncServiceId(GLuint client_id, GLsync* service_id) const { + base::hash_map<GLuint, GLsync>::const_iterator iter = + syncs_id_map_.find(client_id); + if (iter == syncs_id_map_.end()) + return false; + if (service_id) + *service_id = iter->second; + return true; + } + + void RemoveSyncId(GLuint client_id) { + syncs_id_map_.erase(client_id); + } + private: friend class base::RefCounted<ContextGroup>; ~ContextGroup(); @@ -182,6 +247,8 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { scoped_refptr<MemoryTracker> memory_tracker_; scoped_refptr<ShaderTranslatorCache> shader_translator_cache_; scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; + scoped_refptr<SubscriptionRefSet> subscription_ref_set_; + scoped_refptr<ValueStateMap> pending_valuebuffer_state_; bool enforce_gl_minimums_; bool bind_generates_resource_; @@ -204,18 +271,23 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { scoped_ptr<RenderbufferManager> renderbuffer_manager_; - scoped_ptr<ValuebufferManager> valuebuffer_manager_; - scoped_ptr<TextureManager> texture_manager_; scoped_ptr<ProgramManager> program_manager_; scoped_ptr<ShaderManager> shader_manager_; + scoped_ptr<ValuebufferManager> valuebuffer_manager_; + scoped_refptr<FeatureInfo> feature_info_; std::vector<base::WeakPtr<gles2::GLES2Decoder> > decoders_; + // Mappings from client side IDs to service side IDs. + base::hash_map<GLuint, GLuint> samplers_id_map_; + base::hash_map<GLuint, GLuint> transformfeedbacks_id_map_; + base::hash_map<GLuint, GLsync> syncs_id_map_; + GLenum draw_buffer_; DISALLOW_COPY_AND_ASSIGN(ContextGroup); diff --git a/chromium/gpu/command_buffer/service/context_group_unittest.cc b/chromium/gpu/command_buffer/service/context_group_unittest.cc index 13e5dc8caca..afd343d169d 100644 --- a/chromium/gpu/command_buffer/service/context_group_unittest.cc +++ b/chromium/gpu/command_buffer/service/context_group_unittest.cc @@ -5,11 +5,13 @@ #include "gpu/command_buffer/service/context_group.h" #include "base/memory/scoped_ptr.h" +#include "gpu/command_buffer/common/value_state.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/gpu_service_test.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/test_helper.h" #include "gpu/command_buffer/service/texture_manager.h" +#include "gpu/command_buffer/service/valuebuffer_manager.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_mock.h" @@ -38,8 +40,8 @@ class ContextGroupTest : public GpuServiceTest { void SetUp() override { GpuServiceTest::SetUp(); decoder_.reset(new MockGLES2Decoder()); - group_ = scoped_refptr<ContextGroup>( - new ContextGroup(NULL, NULL, NULL, NULL, kBindGeneratesResource)); + group_ = scoped_refptr<ContextGroup>(new ContextGroup( + NULL, NULL, NULL, NULL, NULL, NULL, kBindGeneratesResource)); } scoped_ptr<MockGLES2Decoder> decoder_; diff --git a/chromium/gpu/command_buffer/service/context_state.cc b/chromium/gpu/command_buffer/service/context_state.cc index eb7fc4933db..13c56b420f9 100644 --- a/chromium/gpu/command_buffer/service/context_state.cc +++ b/chromium/gpu/command_buffer/service/context_state.cc @@ -20,14 +20,6 @@ namespace gles2 { namespace { -static void EnableDisable(GLenum pname, bool enable) { - if (enable) { - glEnable(pname); - } else { - glDisable(pname); - } -} - GLuint Get2dServiceId(const TextureUnit& unit) { return unit.bound_texture_2d.get() ? unit.bound_texture_2d->service_id() : 0; @@ -89,6 +81,113 @@ TextureUnit::TextureUnit() TextureUnit::~TextureUnit() { } +bool Vec4::Equal(const Vec4& other) const { + if (type_ != other.type_) + return false; + switch (type_) { + case kFloat: + for (size_t ii = 0; ii < 4; ++ii) { + if (v_[ii].float_value != other.v_[ii].float_value) + return false; + } + break; + case kInt: + for (size_t ii = 0; ii < 4; ++ii) { + if (v_[ii].int_value != other.v_[ii].int_value) + return false; + } + break; + case kUInt: + for (size_t ii = 0; ii < 4; ++ii) { + if (v_[ii].uint_value != other.v_[ii].uint_value) + return false; + } + break; + } + return true; +} + +template <> +void Vec4::GetValues<GLfloat>(GLfloat* values) const { + DCHECK(values); + switch (type_) { + case kFloat: + for (size_t ii = 0; ii < 4; ++ii) + values[ii] = v_[ii].float_value; + break; + case kInt: + for (size_t ii = 0; ii < 4; ++ii) + values[ii] = static_cast<GLfloat>(v_[ii].int_value); + break; + case kUInt: + for (size_t ii = 0; ii < 4; ++ii) + values[ii] = static_cast<GLfloat>(v_[ii].uint_value); + break; + } +} + +template <> +void Vec4::GetValues<GLint>(GLint* values) const { + DCHECK(values); + switch (type_) { + case kFloat: + for (size_t ii = 0; ii < 4; ++ii) + values[ii] = static_cast<GLint>(v_[ii].float_value); + break; + case kInt: + for (size_t ii = 0; ii < 4; ++ii) + values[ii] = v_[ii].int_value; + break; + case kUInt: + for (size_t ii = 0; ii < 4; ++ii) + values[ii] = static_cast<GLint>(v_[ii].uint_value); + break; + } +} + +template<> +void Vec4::GetValues<GLuint>(GLuint* values) const { + DCHECK(values); + switch (type_) { + case kFloat: + for (size_t ii = 0; ii < 4; ++ii) + values[ii] = static_cast<GLuint>(v_[ii].float_value); + break; + case kInt: + for (size_t ii = 0; ii < 4; ++ii) + values[ii] = static_cast<GLuint>(v_[ii].int_value); + break; + case kUInt: + for (size_t ii = 0; ii < 4; ++ii) + values[ii] = v_[ii].uint_value; + break; + } +} + +template <> +void Vec4::SetValues<GLfloat>(const GLfloat* values) { + DCHECK(values); + for (size_t ii = 0; ii < 4; ++ii) + v_[ii].float_value = values[ii]; + type_ = kFloat; +} + +template <> +void Vec4::SetValues<GLint>(const GLint* values) { + DCHECK(values); + for (size_t ii = 0; ii < 4; ++ii) + v_[ii].int_value = values[ii]; + type_ = kInt; +} + +template <> +void Vec4::SetValues<GLuint>(const GLuint* values) { + DCHECK(values); + for (size_t ii = 0; ii < 4; ++ii) + v_[ii].uint_value = values[ii]; + type_ = kUInt; +} + ContextState::ContextState(FeatureInfo* feature_info, ErrorStateClient* error_state_client, Logger* logger) @@ -96,7 +195,7 @@ ContextState::ContextState(FeatureInfo* feature_info, bound_renderbuffer_valid(false), pack_reverse_row_order(false), ignore_cached_state(false), - fbo_binding_for_scissor_workaround_dirty_(false), + fbo_binding_for_scissor_workaround_dirty(false), feature_info_(feature_info), error_state_(ErrorState::Create(error_state_client, logger)) { Initialize(); @@ -193,7 +292,29 @@ void ContextState::RestoreActiveTextureUnitBinding(unsigned int target) const { void ContextState::RestoreVertexAttribValues() const { for (size_t attrib = 0; attrib < vertex_attrib_manager->num_attribs(); ++attrib) { - glVertexAttrib4fv(attrib, attrib_values[attrib].v); + switch (attrib_values[attrib].type()) { + case Vec4::kFloat: + { + GLfloat v[4]; + attrib_values[attrib].GetValues(v); + glVertexAttrib4fv(attrib, v); + } + break; + case Vec4::kInt: + { + GLint v[4]; + attrib_values[attrib].GetValues(v); + glVertexAttribI4iv(attrib, v); + } + break; + case Vec4::kUInt: + { + GLuint v[4]; + attrib_values[attrib].GetValues(v); + glVertexAttribI4uiv(attrib, v); + } + break; + } } } @@ -291,6 +412,18 @@ ErrorState* ContextState::GetErrorState() { return error_state_.get(); } +void ContextState::EnableDisable(GLenum pname, bool enable) const { + if (pname == GL_PRIMITIVE_RESTART_FIXED_INDEX) { + if (feature_info_->feature_flags().emulate_primitive_restart_fixed_index) + pname = GL_PRIMITIVE_RESTART; + } + if (enable) { + glEnable(pname); + } else { + glDisable(pname); + } +} + // Include the auto-generated part of this file. We split this because it means // we can easily edit the non-auto generated parts right here in this file // instead of having to edit some template or the code generator. diff --git a/chromium/gpu/command_buffer/service/context_state.h b/chromium/gpu/command_buffer/service/context_state.h index b4e812c295c..166a906f221 100644 --- a/chromium/gpu/command_buffer/service/context_state.h +++ b/chromium/gpu/command_buffer/service/context_state.h @@ -52,6 +52,13 @@ struct GPU_EXPORT TextureUnit { // glBindTexture scoped_refptr<TextureRef> bound_texture_rectangle_arb; + // texture currently bound to this unit's GL_TEXTURE_3D with glBindTexture + scoped_refptr<TextureRef> bound_texture_3d; + + // texture currently bound to this unit's GL_TEXTURE_2D_ARRAY with + // glBindTexture + scoped_refptr<TextureRef> bound_texture_2d_array; + scoped_refptr<TextureRef> GetInfoForSamplerType( GLenum type) { DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || @@ -65,6 +72,10 @@ struct GPU_EXPORT TextureUnit { return bound_texture_external_oes; case GL_SAMPLER_2D_RECT_ARB: return bound_texture_rectangle_arb; + case GL_SAMPLER_3D: + return bound_texture_3d; + case GL_SAMPLER_2D_ARRAY: + return bound_texture_2d_array; } NOTREACHED(); @@ -81,19 +92,68 @@ struct GPU_EXPORT TextureUnit { if (bound_texture_external_oes.get() == texture) { bound_texture_external_oes = NULL; } + if (bound_texture_3d.get() == texture) { + bound_texture_3d = NULL; + } + if (bound_texture_2d_array.get() == texture) { + bound_texture_2d_array = NULL; + } } }; -struct Vec4 { +class GPU_EXPORT Vec4 { + public: + enum DataType { + kFloat, + kInt, + kUInt, + }; + Vec4() { - v[0] = 0.0f; - v[1] = 0.0f; - v[2] = 0.0f; - v[3] = 1.0f; + v_[0].float_value = 0.0f; + v_[1].float_value = 0.0f; + v_[2].float_value = 0.0f; + v_[3].float_value = 1.0f; + type_ = kFloat; + } + + template <typename T> + void GetValues(T* values) const; + + template <typename T> + void SetValues(const T* values); + + DataType type() const { + return type_; } - float v[4]; + + bool Equal(const Vec4& other) const; + + private: + union ValueUnion { + GLfloat float_value; + GLint int_value; + GLuint uint_value; + }; + + ValueUnion v_[4]; + DataType type_; }; +template <> +GPU_EXPORT void Vec4::GetValues<GLfloat>(GLfloat* values) const; +template <> +GPU_EXPORT void Vec4::GetValues<GLint>(GLint* values) const; +template <> +GPU_EXPORT void Vec4::GetValues<GLuint>(GLuint* values) const; + +template <> +GPU_EXPORT void Vec4::SetValues<GLfloat>(const GLfloat* values); +template <> +GPU_EXPORT void Vec4::SetValues<GLint>(const GLint* values); +template <> +GPU_EXPORT void Vec4::SetValues<GLuint>(const GLuint* values); + struct GPU_EXPORT ContextState { ContextState(FeatureInfo* feature_info, ErrorStateClient* error_state_client, @@ -211,10 +271,12 @@ struct GPU_EXPORT ContextState { bool pack_reverse_row_order; bool ignore_cached_state; - mutable bool fbo_binding_for_scissor_workaround_dirty_; - FeatureInfo* feature_info_; + mutable bool fbo_binding_for_scissor_workaround_dirty; private: + void EnableDisable(GLenum pname, bool enable) const; + + FeatureInfo* feature_info_; scoped_ptr<ErrorState> error_state_; }; diff --git a/chromium/gpu/command_buffer/service/context_state_autogen.h b/chromium/gpu/command_buffer/service/context_state_autogen.h index fcae244ca8b..e2b65bf5d50 100644 --- a/chromium/gpu/command_buffer/service/context_state_autogen.h +++ b/chromium/gpu/command_buffer/service/context_state_autogen.h @@ -32,6 +32,10 @@ struct EnableFlags { bool cached_scissor_test; bool stencil_test; bool cached_stencil_test; + bool rasterizer_discard; + bool cached_rasterizer_discard; + bool primitive_restart_fixed_index; + bool cached_primitive_restart_fixed_index; }; GLfloat blend_color_red; @@ -150,6 +154,18 @@ inline void SetDeviceCapabilityState(GLenum cap, bool enable) { return; enable_flags.cached_stencil_test = enable; break; + case GL_RASTERIZER_DISCARD: + if (enable_flags.cached_rasterizer_discard == enable && + !ignore_cached_state) + return; + enable_flags.cached_rasterizer_discard = enable; + break; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + if (enable_flags.cached_primitive_restart_fixed_index == enable && + !ignore_cached_state) + return; + enable_flags.cached_primitive_restart_fixed_index = enable; + break; default: NOTREACHED(); return; diff --git a/chromium/gpu/command_buffer/service/context_state_impl_autogen.h b/chromium/gpu/command_buffer/service/context_state_impl_autogen.h index 037ac6c1a0b..fa5462f0460 100644 --- a/chromium/gpu/command_buffer/service/context_state_impl_autogen.h +++ b/chromium/gpu/command_buffer/service/context_state_impl_autogen.h @@ -30,7 +30,11 @@ ContextState::EnableFlags::EnableFlags() scissor_test(false), cached_scissor_test(false), stencil_test(false), - cached_stencil_test(false) { + cached_stencil_test(false), + rasterizer_discard(false), + cached_rasterizer_discard(false), + primitive_restart_fixed_index(false), + cached_primitive_restart_fixed_index(false) { } void ContextState::Initialize() { @@ -134,33 +138,54 @@ void ContextState::Initialize() { void ContextState::InitCapabilities(const ContextState* prev_state) const { if (prev_state) { - if (prev_state->enable_flags.cached_blend != enable_flags.cached_blend) + if (prev_state->enable_flags.cached_blend != enable_flags.cached_blend) { EnableDisable(GL_BLEND, enable_flags.cached_blend); + } if (prev_state->enable_flags.cached_cull_face != - enable_flags.cached_cull_face) + enable_flags.cached_cull_face) { EnableDisable(GL_CULL_FACE, enable_flags.cached_cull_face); + } if (prev_state->enable_flags.cached_depth_test != - enable_flags.cached_depth_test) + enable_flags.cached_depth_test) { EnableDisable(GL_DEPTH_TEST, enable_flags.cached_depth_test); - if (prev_state->enable_flags.cached_dither != enable_flags.cached_dither) + } + if (prev_state->enable_flags.cached_dither != enable_flags.cached_dither) { EnableDisable(GL_DITHER, enable_flags.cached_dither); + } if (prev_state->enable_flags.cached_polygon_offset_fill != - enable_flags.cached_polygon_offset_fill) + enable_flags.cached_polygon_offset_fill) { EnableDisable(GL_POLYGON_OFFSET_FILL, enable_flags.cached_polygon_offset_fill); + } if (prev_state->enable_flags.cached_sample_alpha_to_coverage != - enable_flags.cached_sample_alpha_to_coverage) + enable_flags.cached_sample_alpha_to_coverage) { EnableDisable(GL_SAMPLE_ALPHA_TO_COVERAGE, enable_flags.cached_sample_alpha_to_coverage); + } if (prev_state->enable_flags.cached_sample_coverage != - enable_flags.cached_sample_coverage) + enable_flags.cached_sample_coverage) { EnableDisable(GL_SAMPLE_COVERAGE, enable_flags.cached_sample_coverage); + } if (prev_state->enable_flags.cached_scissor_test != - enable_flags.cached_scissor_test) + enable_flags.cached_scissor_test) { EnableDisable(GL_SCISSOR_TEST, enable_flags.cached_scissor_test); + } if (prev_state->enable_flags.cached_stencil_test != - enable_flags.cached_stencil_test) + enable_flags.cached_stencil_test) { EnableDisable(GL_STENCIL_TEST, enable_flags.cached_stencil_test); + } + if (feature_info_->IsES3Capable()) { + if (prev_state->enable_flags.cached_rasterizer_discard != + enable_flags.cached_rasterizer_discard) { + EnableDisable(GL_RASTERIZER_DISCARD, + enable_flags.cached_rasterizer_discard); + } + if (prev_state->enable_flags.cached_primitive_restart_fixed_index != + enable_flags.cached_primitive_restart_fixed_index) { + EnableDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX, + enable_flags.cached_primitive_restart_fixed_index); + } + } } else { EnableDisable(GL_BLEND, enable_flags.cached_blend); EnableDisable(GL_CULL_FACE, enable_flags.cached_cull_face); @@ -173,6 +198,12 @@ void ContextState::InitCapabilities(const ContextState* prev_state) const { EnableDisable(GL_SAMPLE_COVERAGE, enable_flags.cached_sample_coverage); EnableDisable(GL_SCISSOR_TEST, enable_flags.cached_scissor_test); EnableDisable(GL_STENCIL_TEST, enable_flags.cached_stencil_test); + if (feature_info_->IsES3Capable()) { + EnableDisable(GL_RASTERIZER_DISCARD, + enable_flags.cached_rasterizer_discard); + EnableDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX, + enable_flags.cached_primitive_restart_fixed_index); + } } } @@ -220,7 +251,9 @@ void ContextState::InitState(const ContextState* prev_state) const { if ((front_face != prev_state->front_face)) glFrontFace(front_face); if (prev_state->hint_generate_mipmap != hint_generate_mipmap) { - glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap); + if (!feature_info_->gl_version_info().is_desktop_core_profile) { + glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap); + } } if (feature_info_->feature_flags().oes_standard_derivatives) { if (prev_state->hint_fragment_shader_derivative != @@ -308,7 +341,9 @@ void ContextState::InitState(const ContextState* prev_state) const { glDepthMask(cached_depth_mask); glDepthRange(z_near, z_far); glFrontFace(front_face); - glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap); + if (!feature_info_->gl_version_info().is_desktop_core_profile) { + glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap); + } if (feature_info_->feature_flags().oes_standard_derivatives) { glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES, hint_fragment_shader_derivative); @@ -358,6 +393,10 @@ bool ContextState::GetEnabled(GLenum cap) const { return enable_flags.scissor_test; case GL_STENCIL_TEST: return enable_flags.stencil_test; + case GL_RASTERIZER_DISCARD: + return enable_flags.rasterizer_discard; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + return enable_flags.primitive_restart_fixed_index; default: NOTREACHED(); return false; @@ -700,6 +739,19 @@ bool ContextState::GetStateAsGLint(GLenum pname, params[0] = static_cast<GLint>(enable_flags.stencil_test); } return true; + case GL_RASTERIZER_DISCARD: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(enable_flags.rasterizer_discard); + } + return true; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + *num_written = 1; + if (params) { + params[0] = + static_cast<GLint>(enable_flags.primitive_restart_fixed_index); + } + return true; default: return false; } @@ -1037,6 +1089,19 @@ bool ContextState::GetStateAsGLfloat(GLenum pname, params[0] = static_cast<GLfloat>(enable_flags.stencil_test); } return true; + case GL_RASTERIZER_DISCARD: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(enable_flags.rasterizer_discard); + } + return true; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + *num_written = 1; + if (params) { + params[0] = + static_cast<GLfloat>(enable_flags.primitive_restart_fixed_index); + } + return true; default: return false; } diff --git a/chromium/gpu/command_buffer/service/context_state_unittest.cc b/chromium/gpu/command_buffer/service/context_state_unittest.cc new file mode 100644 index 00000000000..5a835dec4f5 --- /dev/null +++ b/chromium/gpu/command_buffer/service/context_state_unittest.cc @@ -0,0 +1,86 @@ +// Copyright (c) 2015 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 "gpu/command_buffer/service/context_state.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { +namespace gles2 { + +TEST(ContextStateVec4Test, DefaultValues) { + Vec4 v; + EXPECT_EQ(Vec4::kFloat, v.type()); + GLfloat f[4]; + v.GetValues(f); + EXPECT_EQ(0.f, f[0]); + EXPECT_EQ(0.f, f[1]); + EXPECT_EQ(0.f, f[2]); + EXPECT_EQ(1.f, f[3]); +} + +TEST(ContextStateVec4Test, SetGetFloatValues) { + Vec4 v; + + const GLfloat kFloatValues[4] = { 2.f, 3.f, 4.f, 5.f }; + v.SetValues(kFloatValues); + EXPECT_EQ(Vec4::kFloat, v.type()); + GLfloat fv[4]; + v.GetValues(fv); + for (size_t ii = 0; ii < 4; ++ii) { + EXPECT_EQ(kFloatValues[ii], fv[ii]); + } +} + +TEST(ContextStateVec4Test, SetGetIntValues) { + Vec4 v; + + const GLint kIntValues[4] = { 2, 3, -4, 5 }; + v.SetValues(kIntValues); + EXPECT_EQ(Vec4::kInt, v.type()); + GLint iv[4]; + v.GetValues(iv); + for (size_t ii = 0; ii < 4; ++ii) { + EXPECT_EQ(kIntValues[ii], iv[ii]); + } +} + +TEST(ContextStateVec4Test, SetGetUIntValues) { + Vec4 v; + + const GLuint kUIntValues[4] = { 2, 3, 4, 5 }; + v.SetValues(kUIntValues); + EXPECT_EQ(Vec4::kUInt, v.type()); + GLuint uiv[4]; + v.GetValues(uiv); + for (size_t ii = 0; ii < 4; ++ii) { + EXPECT_EQ(kUIntValues[ii], uiv[ii]); + } +} + +TEST(ContextStateVec4Test, Equal) { + Vec4 v1, v2; + + const GLint kIntValues[4] = { 2, 3, 4, 5 }; + const GLuint kUIntValues[4] = { 2, 3, 4, 5 }; + + v1.SetValues(kIntValues); + v2.SetValues(kUIntValues); + EXPECT_FALSE(v1.Equal(v2)); + EXPECT_FALSE(v2.Equal(v1)); + + v2.SetValues(kIntValues); + EXPECT_TRUE(v1.Equal(v2)); + EXPECT_TRUE(v2.Equal(v1)); + + const GLint kIntValues2[4] = { 2, 3, 4, 6 }; + v2.SetValues(kIntValues2); + EXPECT_FALSE(v1.Equal(v2)); + EXPECT_FALSE(v2.Equal(v1)); +} + +} // namespace gles2 +} // namespace gpu + + diff --git a/chromium/gpu/command_buffer/service/feature_info.cc b/chromium/gpu/command_buffer/service/feature_info.cc index b06292abfa3..c5479d0d8ec 100644 --- a/chromium/gpu/command_buffer/service/feature_info.cc +++ b/chromium/gpu/command_buffer/service/feature_info.cc @@ -14,9 +14,15 @@ #include "base/strings/string_util.h" #include "gpu/command_buffer/service/gl_utils.h" #include "gpu/command_buffer/service/gpu_switches.h" +#include "gpu/command_buffer/service/texture_definition.h" +#include "gpu/config/gpu_switches.h" #include "ui/gl/gl_fence.h" #include "ui/gl/gl_implementation.h" +#if !defined(OS_MACOSX) +#include "ui/gl/gl_fence_egl.h" +#endif + namespace gpu { namespace gles2 { @@ -40,6 +46,10 @@ class StringSet { Init(str); } + StringSet(const std::vector<std::string>& strs) { + string_set_.insert(strs.begin(), strs.end()); + } + void Init(const char* s) { std::string str(s ? s : ""); Init(str); @@ -59,6 +69,10 @@ class StringSet { return string_set_.find(s) != string_set_.end(); } + const std::set<std::string>& GetImpl() { + return string_set_; + } + private: std::set<std::string> string_set_; }; @@ -128,7 +142,10 @@ FeatureInfo::FeatureFlags::FeatureFlags() use_arb_occlusion_query2_for_occlusion_query_boolean(false), use_arb_occlusion_query_for_occlusion_query_boolean(false), native_vertex_array_object(false), + ext_texture_format_atc(false), ext_texture_format_bgra8888(false), + ext_texture_format_dxt1(false), + ext_texture_format_dxt5(false), enable_shader_name_hashing(false), enable_samplers(false), ext_draw_buffers(false), @@ -139,13 +156,15 @@ FeatureInfo::FeatureFlags::FeatureFlags() map_buffer_range(false), ext_discard_framebuffer(false), angle_depth_texture(false), - is_angle(false), is_swiftshader(false), angle_texture_usage(false), ext_texture_storage(false), chromium_path_rendering(false), blend_equation_advanced(false), - blend_equation_advanced_coherent(false) { + blend_equation_advanced_coherent(false), + ext_texture_rg(false), + enable_subscribe_uniform(false), + emulate_primitive_restart_fixed_index(false) { } FeatureInfo::Workarounds::Workarounds() : @@ -160,14 +179,14 @@ FeatureInfo::Workarounds::Workarounds() : } FeatureInfo::FeatureInfo() { - InitializeBasicState(*CommandLine::ForCurrentProcess()); + InitializeBasicState(*base::CommandLine::ForCurrentProcess()); } -FeatureInfo::FeatureInfo(const CommandLine& command_line) { +FeatureInfo::FeatureInfo(const base::CommandLine& command_line) { InitializeBasicState(command_line); } -void FeatureInfo::InitializeBasicState(const CommandLine& command_line) { +void FeatureInfo::InitializeBasicState(const base::CommandLine& command_line) { if (command_line.HasSwitch(switches::kGpuDriverBugWorkarounds)) { std::string types = command_line.GetSwitchValueASCII( switches::kGpuDriverBugWorkarounds); @@ -179,6 +198,12 @@ void FeatureInfo::InitializeBasicState(const CommandLine& command_line) { feature_flags_.is_swiftshader = (command_line.GetSwitchValueASCII(switches::kUseGL) == "swiftshader"); + feature_flags_.enable_subscribe_uniform = + command_line.HasSwitch(switches::kEnableSubscribeUniformExtension); + + unsafe_es3_apis_enabled_ = + command_line.HasSwitch(switches::kEnableUnsafeES3APIs); + static const GLenum kAlphaTypes[] = { GL_UNSIGNED_BYTE, }; @@ -226,24 +251,70 @@ bool FeatureInfo::Initialize(const DisallowedFeatures& disallowed_features) { return true; } +bool IsGL_REDSupportedOnFBOs() { + // Skia uses GL_RED with frame buffers, unfortunately, Mesa claims to support + // GL_EXT_texture_rg, but it doesn't support it on frame buffers. To fix + // this, we try it, and if it fails, we don't expose GL_EXT_texture_rg. + GLint fb_binding = 0; + GLint tex_binding = 0; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb_binding); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex_binding); + + GLuint textureId = 0; + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); + GLubyte data[1] = {0}; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED_EXT, 1, 1, 0, GL_RED_EXT, + GL_UNSIGNED_BYTE, data); + GLuint textureFBOID = 0; + glGenFramebuffersEXT(1, &textureFBOID); + glBindFramebufferEXT(GL_FRAMEBUFFER, textureFBOID); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + textureId, 0); + bool result = + glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_UNSUPPORTED; + glDeleteFramebuffersEXT(1, &textureFBOID); + glDeleteTextures(1, &textureId); + + glBindFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLuint>(fb_binding)); + glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(tex_binding)); + + DCHECK(glGetError() == GL_NO_ERROR); + + return result; +} + void FeatureInfo::InitializeFeatures() { // Figure out what extensions to turn on. - StringSet extensions( - reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); + StringSet extensions; + // We need to figure out how to query the extension string before we + // have a GLVersionInfo available. + const char* version_str = + reinterpret_cast<const char*>(glGetString(GL_VERSION)); + unsigned major_version, minor_version; + bool is_es, is_es3; + gfx::GLVersionInfo::ParseVersionString( + version_str, &major_version, &minor_version, &is_es, &is_es3); + if (!is_es && major_version >= 3) { + std::vector<std::string> exts; + GLint num_extensions = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions); + for (GLint i = 0; i < num_extensions; ++i) { + const char* extension = reinterpret_cast<const char*>( + glGetStringi(GL_EXTENSIONS, i)); + DCHECK(extension != NULL); + exts.push_back(extension); + } + extensions = exts; + } else { + extensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); + } const char* renderer_str = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); - if (renderer_str) { - feature_flags_.is_angle = StartsWithASCII(renderer_str, "ANGLE", true); - } - bool is_es3 = false; - const char* version_str = - reinterpret_cast<const char*>(glGetString(GL_VERSION)); - if (version_str) { - std::string lstr(base::StringToLowerASCII(std::string(version_str))); - is_es3 = (lstr.substr(0, 12) == "opengl es 3."); - } + gl_version_info_.reset(new gfx::GLVersionInfo( + version_str, renderer_str, extensions.GetImpl())); AddExtensionString("GL_ANGLE_translated_shader_source"); AddExtensionString("GL_CHROMIUM_async_pixel_transfers"); @@ -259,8 +330,13 @@ void FeatureInfo::InitializeFeatures() { AddExtensionString("GL_CHROMIUM_resource_safe"); AddExtensionString("GL_CHROMIUM_strict_attribs"); AddExtensionString("GL_CHROMIUM_texture_mailbox"); + AddExtensionString("GL_CHROMIUM_trace_marker"); AddExtensionString("GL_EXT_debug_marker"); + if (feature_flags_.enable_subscribe_uniform) { + AddExtensionString("GL_CHROMIUM_subscribe_uniform"); + } + // OES_vertex_array_object is emulated if not present natively, // so the extension string is always exposed. AddExtensionString("GL_OES_vertex_array_object"); @@ -294,6 +370,8 @@ void FeatureInfo::InitializeFeatures() { } if (enable_dxt1) { + feature_flags_.ext_texture_format_dxt1 = true; + AddExtensionString("GL_EXT_texture_compression_dxt1"); validators_.compressed_texture_format.AddValue( GL_COMPRESSED_RGB_S3TC_DXT1_EXT); @@ -311,6 +389,8 @@ void FeatureInfo::InitializeFeatures() { } if (enable_dxt5) { + feature_flags_.ext_texture_format_dxt5 = true; + // The difference between GL_EXT_texture_compression_s3tc and // GL_CHROMIUM_texture_compression_dxt5 is that the former // requires on the fly compression. The latter does not. @@ -319,6 +399,17 @@ void FeatureInfo::InitializeFeatures() { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); } + bool have_atc = extensions.Contains("GL_AMD_compressed_ATC_texture") || + extensions.Contains("GL_ATI_texture_compression_atitc"); + if (have_atc) { + feature_flags_.ext_texture_format_atc = true; + + AddExtensionString("GL_AMD_compressed_ATC_texture"); + validators_.compressed_texture_format.AddValue(GL_ATC_RGB_AMD); + validators_.compressed_texture_format.AddValue( + GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD); + } + // Check if we should enable GL_EXT_texture_filter_anisotropic. if (extensions.Contains("GL_EXT_texture_filter_anisotropic")) { AddExtensionString("GL_EXT_texture_filter_anisotropic"); @@ -344,7 +435,9 @@ void FeatureInfo::InitializeFeatures() { if (!workarounds_.disable_depth_texture && (extensions.Contains("GL_ARB_depth_texture") || extensions.Contains("GL_OES_depth_texture") || - extensions.Contains("GL_ANGLE_depth_texture") || is_es3)) { + extensions.Contains("GL_ANGLE_depth_texture") || + gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile)) { enable_depth_texture = true; feature_flags_.angle_depth_texture = extensions.Contains("GL_ANGLE_depth_texture"); @@ -362,7 +455,9 @@ void FeatureInfo::InitializeFeatures() { } if (extensions.Contains("GL_EXT_packed_depth_stencil") || - extensions.Contains("GL_OES_packed_depth_stencil") || is_es3) { + extensions.Contains("GL_OES_packed_depth_stencil") || + gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile) { AddExtensionString("GL_OES_packed_depth_stencil"); feature_flags_.packed_depth24_stencil8 = true; if (enable_depth_texture) { @@ -375,7 +470,9 @@ void FeatureInfo::InitializeFeatures() { validators_.render_buffer_format.AddValue(GL_DEPTH24_STENCIL8); } - if (is_es3 || extensions.Contains("GL_OES_vertex_array_object") || + if (gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile || + extensions.Contains("GL_OES_vertex_array_object") || extensions.Contains("GL_ARB_vertex_array_object") || extensions.Contains("GL_APPLE_vertex_array_object")) { feature_flags_.native_vertex_array_object = true; @@ -388,14 +485,22 @@ void FeatureInfo::InitializeFeatures() { feature_flags_.native_vertex_array_object = false; } - if (is_es3 || extensions.Contains("GL_OES_element_index_uint") || + if (gl_version_info_->is_es3 || + extensions.Contains("GL_OES_element_index_uint") || gfx::HasDesktopGLFeatures()) { AddExtensionString("GL_OES_element_index_uint"); validators_.index_type.AddValue(GL_UNSIGNED_INT); } - if (is_es3 || extensions.Contains("GL_EXT_sRGB") || - gfx::HasDesktopGLFeatures()) { + // With EXT_sRGB, unsized SRGB_EXT and SRGB_ALPHA_EXT are accepted by the + // <format> and <internalformat> parameter of TexImage2D. GLES3 adds support + // for SRGB Textures but the accepted internal formats for TexImage2D are only + // sized formats GL_SRGB8 and GL_SRGB8_ALPHA8. Also, SRGB_EXT isn't a valid + // <format> in this case. So, even with GLES3 explicitly check for + // GL_EXT_sRGB. + if (((gl_version_info_->is_es3 || + extensions.Contains("GL_OES_rgb8_rgba8")) && + extensions.Contains("GL_EXT_sRGB")) || gfx::HasDesktopGLFeatures()) { AddExtensionString("GL_EXT_sRGB"); texture_format_validators_[GL_SRGB_EXT].AddValue(GL_UNSIGNED_BYTE); texture_format_validators_[GL_SRGB_ALPHA_EXT].AddValue(GL_UNSIGNED_BYTE); @@ -421,7 +526,9 @@ void FeatureInfo::InitializeFeatures() { enable_texture_format_bgra8888 = true; } - if (extensions.Contains("GL_EXT_bgra")) { + // Only desktop GL extension GL_EXT_bgra or ANGLE guarantee that we can + // allocate a renderbuffer with this format. + if (extensions.Contains("GL_EXT_bgra") || gl_version_info_->is_angle) { enable_render_buffer_bgra = true; } @@ -455,7 +562,9 @@ void FeatureInfo::InitializeFeatures() { } // Check if we should allow GL_OES_texture_npot - if (is_es3 || extensions.Contains("GL_ARB_texture_non_power_of_two") || + if (gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile || + extensions.Contains("GL_ARB_texture_non_power_of_two") || extensions.Contains("GL_OES_texture_npot")) { AddExtensionString("GL_OES_texture_npot"); feature_flags_.npot_ok = true; @@ -470,23 +579,31 @@ void FeatureInfo::InitializeFeatures() { bool may_enable_chromium_color_buffer_float = false; - if (extensions.Contains("GL_ARB_texture_float")) { + if (extensions.Contains("GL_ARB_texture_float") || + gl_version_info_->is_desktop_core_profile) { enable_texture_float = true; enable_texture_float_linear = true; enable_texture_half_float = true; enable_texture_half_float_linear = true; may_enable_chromium_color_buffer_float = true; } else { - if (is_es3 || extensions.Contains("GL_OES_texture_float")) { + // GLES3 adds support for Float type by default but it doesn't support all + // formats as GL_OES_texture_float(i.e.LUMINANCE_ALPHA,LUMINANCE and Alpha) + if (extensions.Contains("GL_OES_texture_float")) { enable_texture_float = true; if (extensions.Contains("GL_OES_texture_float_linear")) { enable_texture_float_linear = true; } - if ((is_es3 && extensions.Contains("GL_EXT_color_buffer_float")) || - feature_flags_.is_angle) { + // This extension allows a variety of floating point formats to be + // rendered to via framebuffer objects. Enable it's usage only if + // support for Floating textures is enabled. + if ((gl_version_info_->is_es3 && + extensions.Contains("GL_EXT_color_buffer_float")) || + gl_version_info_->is_angle) { may_enable_chromium_color_buffer_float = true; } } + // TODO(dshwang): GLES3 supports half float by default but GL_HALF_FLOAT_OES // isn't equal to GL_HALF_FLOAT. if (extensions.Contains("GL_OES_texture_half_float")) { @@ -526,11 +643,11 @@ void FeatureInfo::InitializeFeatures() { } if (may_enable_chromium_color_buffer_float) { - COMPILE_ASSERT(GL_RGBA32F_ARB == GL_RGBA32F && - GL_RGBA32F_EXT == GL_RGBA32F && - GL_RGB32F_ARB == GL_RGB32F && - GL_RGB32F_EXT == GL_RGB32F, - sized_float_internal_format_variations_must_match); + static_assert(GL_RGBA32F_ARB == GL_RGBA32F && + GL_RGBA32F_EXT == GL_RGBA32F && + GL_RGB32F_ARB == GL_RGB32F && + GL_RGB32F_EXT == GL_RGB32F, + "sized float internal format variations must match"); // We don't check extension support beyond ARB_texture_float on desktop GL, // and format support varies between GL configurations. For example, spec // prior to OpenGL 3.0 mandates framebuffer support only for one @@ -582,14 +699,17 @@ void FeatureInfo::InitializeFeatures() { } // Check for multisample support - if (!workarounds_.disable_multisampling) { + if (!workarounds_.disable_chromium_framebuffer_multisample) { bool ext_has_multisample = - extensions.Contains("GL_EXT_framebuffer_multisample") || is_es3; - if (feature_flags_.is_angle) { + extensions.Contains("GL_EXT_framebuffer_multisample") || + gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile; + if (gl_version_info_->is_angle) { ext_has_multisample |= extensions.Contains("GL_ANGLE_framebuffer_multisample"); } - feature_flags_.use_core_framebuffer_multisample = is_es3; + feature_flags_.use_core_framebuffer_multisample = + gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile; if (ext_has_multisample) { feature_flags_.chromium_framebuffer_multisample = true; validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT); @@ -599,6 +719,9 @@ void FeatureInfo::InitializeFeatures() { validators_.render_buffer_parameter.AddValue(GL_RENDERBUFFER_SAMPLES_EXT); AddExtensionString("GL_CHROMIUM_framebuffer_multisample"); } + } + + if (!workarounds_.disable_multisampled_render_to_texture) { if (extensions.Contains("GL_EXT_multisampled_render_to_texture")) { feature_flags_.multisampled_render_to_texture = true; } else if (extensions.Contains("GL_IMG_multisampled_render_to_texture")) { @@ -616,14 +739,15 @@ void FeatureInfo::InitializeFeatures() { } if (extensions.Contains("GL_OES_depth24") || gfx::HasDesktopGLFeatures() || - is_es3) { + gl_version_info_->is_es3) { AddExtensionString("GL_OES_depth24"); feature_flags_.oes_depth24 = true; validators_.render_buffer_format.AddValue(GL_DEPTH_COMPONENT24); } if (!workarounds_.disable_oes_standard_derivatives && - (is_es3 || extensions.Contains("GL_OES_standard_derivatives") || + (gl_version_info_->is_es3 || + extensions.Contains("GL_OES_standard_derivatives") || gfx::HasDesktopGLFeatures())) { AddExtensionString("GL_OES_standard_derivatives"); feature_flags_.oes_standard_derivatives = true; @@ -673,7 +797,8 @@ void FeatureInfo::InitializeFeatures() { // applications to start using it; they should use ordinary non- // power-of-two textures. However, for unit testing purposes we // expose it on all supported platforms. - if (extensions.Contains("GL_ARB_texture_rectangle")) { + if (extensions.Contains("GL_ARB_texture_rectangle") || + gl_version_info_->is_desktop_core_profile) { AddExtensionString("GL_ARB_texture_rectangle"); feature_flags_.arb_texture_rectangle = true; validators_.texture_bind_target.AddValue(GL_TEXTURE_RECTANGLE_ARB); @@ -717,11 +842,14 @@ void FeatureInfo::InitializeFeatures() { // However we expose GL_EXT_texture_storage when just ES3 because we don't // claim to handle GL_BGRA8. bool support_texture_storage_on_es3 = - (is_es3 && enable_immutable_texture_format_bgra_on_es3) || - (is_es3 && !enable_texture_format_bgra8888); + (gl_version_info_->is_es3 && + enable_immutable_texture_format_bgra_on_es3) || + (gl_version_info_->is_es3 && + !enable_texture_format_bgra8888); if (extensions.Contains("GL_EXT_texture_storage") || extensions.Contains("GL_ARB_texture_storage") || - support_texture_storage_on_es3) { + support_texture_storage_on_es3 || + gl_version_info_->is_desktop_core_profile) { feature_flags_.ext_texture_storage = true; AddExtensionString("GL_EXT_texture_storage"); validators_.texture_parameter.AddValue(GL_TEXTURE_IMMUTABLE_FORMAT_EXT); @@ -771,7 +899,7 @@ void FeatureInfo::InitializeFeatures() { (extensions.Contains("GL_ANGLE_instanced_arrays") || (extensions.Contains("GL_ARB_instanced_arrays") && extensions.Contains("GL_ARB_draw_instanced")) || - is_es3)) { + gl_version_info_->is_es3)) { AddExtensionString("GL_ANGLE_instanced_arrays"); feature_flags_.angle_instanced_arrays = true; validators_.vertex_attribute.AddValue(GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE); @@ -782,7 +910,9 @@ void FeatureInfo::InitializeFeatures() { extensions.Contains("GL_EXT_draw_buffers"); if (!workarounds_.disable_ext_draw_buffers && (vendor_agnostic_draw_buffers || - (extensions.Contains("GL_NV_draw_buffers") && is_es3))) { + (extensions.Contains("GL_NV_draw_buffers") && + gl_version_info_->is_es3) || + gl_version_info_->is_desktop_core_profile)) { AddExtensionString("GL_EXT_draw_buffers"); feature_flags_.ext_draw_buffers = true; @@ -803,8 +933,8 @@ void FeatureInfo::InitializeFeatures() { ++i) { validators_.attachment.AddValue(i); } - COMPILE_ASSERT(GL_COLOR_ATTACHMENT0_EXT == GL_COLOR_ATTACHMENT0, - color_attachment0_variation_must_match); + static_assert(GL_COLOR_ATTACHMENT0_EXT == GL_COLOR_ATTACHMENT0, + "GL_COLOR_ATTACHMENT0_EXT should equal GL_COLOR_ATTACHMENT0"); validators_.g_l_state.AddValue(GL_MAX_COLOR_ATTACHMENTS_EXT); validators_.g_l_state.AddValue(GL_MAX_DRAW_BUFFERS_ARB); @@ -817,13 +947,14 @@ void FeatureInfo::InitializeFeatures() { } } - if (is_es3 || extensions.Contains("GL_EXT_blend_minmax") || + if (gl_version_info_->is_es3 || + extensions.Contains("GL_EXT_blend_minmax") || gfx::HasDesktopGLFeatures()) { AddExtensionString("GL_EXT_blend_minmax"); validators_.equation.AddValue(GL_MIN_EXT); validators_.equation.AddValue(GL_MAX_EXT); - COMPILE_ASSERT(GL_MIN_EXT == GL_MIN && GL_MAX_EXT == GL_MAX, - min_max_variations_must_match); + static_assert(GL_MIN_EXT == GL_MIN && GL_MAX_EXT == GL_MAX, + "min & max variations must match"); } // TODO(dshwang): GLES3 supports gl_FragDepth, not gl_FragDepthEXT. @@ -852,12 +983,18 @@ void FeatureInfo::InitializeFeatures() { UMA_HISTOGRAM_BOOLEAN("GPU.FenceSupport", ui_gl_fence_works); feature_flags_.map_buffer_range = - is_es3 || extensions.Contains("GL_ARB_map_buffer_range"); + gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile || + extensions.Contains("GL_ARB_map_buffer_range") || + extensions.Contains("GL_EXT_map_buffer_range"); // Really it's part of core OpenGL 2.1 and up, but let's assume the // extension is still advertised. bool has_pixel_buffers = - is_es3 || extensions.Contains("GL_ARB_pixel_buffer_object"); + gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile || + extensions.Contains("GL_ARB_pixel_buffer_object") || + extensions.Contains("GL_NV_pixel_buffer_object"); // We will use either glMapBuffer() or glMapBufferRange() for async readbacks. if (has_pixel_buffers && ui_gl_fence_works && @@ -865,14 +1002,16 @@ void FeatureInfo::InitializeFeatures() { feature_flags_.use_async_readpixels = true; } - if (is_es3 || extensions.Contains("GL_ARB_sampler_objects")) { + if (gl_version_info_->is_es3 || + extensions.Contains("GL_ARB_sampler_objects")) { feature_flags_.enable_samplers = true; // TODO(dsinclair): Add AddExtensionString("GL_CHROMIUM_sampler_objects") // when available. } - if ((is_es3 || extensions.Contains("GL_EXT_discard_framebuffer")) && - !workarounds_.disable_ext_discard_framebuffer) { + if ((gl_version_info_->is_es3 || + extensions.Contains("GL_EXT_discard_framebuffer")) && + !workarounds_.disable_discard_framebuffer) { // DiscardFramebufferEXT is automatically bound to InvalidateFramebuffer. AddExtensionString("GL_EXT_discard_framebuffer"); feature_flags_.ext_discard_framebuffer = true; @@ -883,48 +1022,167 @@ void FeatureInfo::InitializeFeatures() { feature_flags_.chromium_sync_query = true; } - bool blend_equation_advanced_coherent = - extensions.Contains("GL_NV_blend_equation_advanced_coherent") || - extensions.Contains("GL_KHR_blend_equation_advanced_coherent"); - - if (blend_equation_advanced_coherent || - extensions.Contains("GL_NV_blend_equation_advanced") || - extensions.Contains("GL_KHR_blend_equation_advanced")) { - const GLenum equations[] = {GL_MULTIPLY_KHR, - GL_SCREEN_KHR, - GL_OVERLAY_KHR, - GL_DARKEN_KHR, - GL_LIGHTEN_KHR, - GL_COLORDODGE_KHR, - GL_COLORBURN_KHR, - GL_HARDLIGHT_KHR, - GL_SOFTLIGHT_KHR, - GL_DIFFERENCE_KHR, - GL_EXCLUSION_KHR, - GL_HSL_HUE_KHR, - GL_HSL_SATURATION_KHR, - GL_HSL_COLOR_KHR, - GL_HSL_LUMINOSITY_KHR}; - - for (GLenum equation : equations) - validators_.equation.AddValue(equation); - if (blend_equation_advanced_coherent) - AddExtensionString("GL_KHR_blend_equation_advanced_coherent"); - - AddExtensionString("GL_KHR_blend_equation_advanced"); - feature_flags_.blend_equation_advanced = true; - feature_flags_.blend_equation_advanced_coherent = - blend_equation_advanced_coherent; + if (!workarounds_.disable_blend_equation_advanced) { + bool blend_equation_advanced_coherent = + extensions.Contains("GL_NV_blend_equation_advanced_coherent") || + extensions.Contains("GL_KHR_blend_equation_advanced_coherent"); + + if (blend_equation_advanced_coherent || + extensions.Contains("GL_NV_blend_equation_advanced") || + extensions.Contains("GL_KHR_blend_equation_advanced")) { + const GLenum equations[] = {GL_MULTIPLY_KHR, + GL_SCREEN_KHR, + GL_OVERLAY_KHR, + GL_DARKEN_KHR, + GL_LIGHTEN_KHR, + GL_COLORDODGE_KHR, + GL_COLORBURN_KHR, + GL_HARDLIGHT_KHR, + GL_SOFTLIGHT_KHR, + GL_DIFFERENCE_KHR, + GL_EXCLUSION_KHR, + GL_HSL_HUE_KHR, + GL_HSL_SATURATION_KHR, + GL_HSL_COLOR_KHR, + GL_HSL_LUMINOSITY_KHR}; + + for (GLenum equation : equations) + validators_.equation.AddValue(equation); + if (blend_equation_advanced_coherent) + AddExtensionString("GL_KHR_blend_equation_advanced_coherent"); + + AddExtensionString("GL_KHR_blend_equation_advanced"); + feature_flags_.blend_equation_advanced = true; + feature_flags_.blend_equation_advanced_coherent = + blend_equation_advanced_coherent; + } } if (extensions.Contains("GL_NV_path_rendering")) { - if (extensions.Contains("GL_EXT_direct_state_access") || is_es3) { + if (extensions.Contains("GL_EXT_direct_state_access") || + gl_version_info_->is_es3) { AddExtensionString("GL_CHROMIUM_path_rendering"); feature_flags_.chromium_path_rendering = true; validators_.g_l_state.AddValue(GL_PATH_MODELVIEW_MATRIX_CHROMIUM); validators_.g_l_state.AddValue(GL_PATH_PROJECTION_MATRIX_CHROMIUM); } } + + if ((gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile || + extensions.Contains("GL_EXT_texture_rg") || + extensions.Contains("GL_ARB_texture_rg")) && + IsGL_REDSupportedOnFBOs()) { + feature_flags_.ext_texture_rg = true; + AddExtensionString("GL_EXT_texture_rg"); + + validators_.texture_format.AddValue(GL_RED_EXT); + validators_.texture_format.AddValue(GL_RG_EXT); + validators_.texture_internal_format.AddValue(GL_RED_EXT); + validators_.texture_internal_format.AddValue(GL_R8_EXT); + validators_.texture_internal_format.AddValue(GL_RG_EXT); + validators_.texture_internal_format.AddValue(GL_RG8_EXT); + validators_.read_pixel_format.AddValue(GL_RED_EXT); + validators_.read_pixel_format.AddValue(GL_RG_EXT); + validators_.render_buffer_format.AddValue(GL_R8_EXT); + validators_.render_buffer_format.AddValue(GL_RG8_EXT); + + texture_format_validators_[GL_RED_EXT].AddValue(GL_UNSIGNED_BYTE); + texture_format_validators_[GL_RG_EXT].AddValue(GL_UNSIGNED_BYTE); + + if (enable_texture_float) { + texture_format_validators_[GL_RED_EXT].AddValue(GL_FLOAT); + texture_format_validators_[GL_RG_EXT].AddValue(GL_FLOAT); + } + if (enable_texture_half_float) { + texture_format_validators_[GL_RED_EXT].AddValue(GL_HALF_FLOAT_OES); + texture_format_validators_[GL_RG_EXT].AddValue(GL_HALF_FLOAT_OES); + } + } + UMA_HISTOGRAM_BOOLEAN("GPU.TextureRG", feature_flags_.ext_texture_rg); + +#if !defined(OS_MACOSX) + if (workarounds_.ignore_egl_sync_failures) { + gfx::GLFenceEGL::SetIgnoreFailures(); + } +#endif + + if (workarounds_.avoid_egl_image_target_texture_reuse) { + TextureDefinition::AvoidEGLTargetTextureReuse(); + } + + if (gl_version_info_->IsLowerThanGL(4, 3)) { + // crbug.com/481184. + // GL_PRIMITIVE_RESTART_FIXED_INDEX is only available on Desktop GL 4.3+, + // but we emulate ES 3.0 on top of Desktop GL 4.2+. + feature_flags_.emulate_primitive_restart_fixed_index = true; + } +} + +bool FeatureInfo::IsES3Capable() const { + if (!unsafe_es3_apis_enabled_) + return false; + if (gl_version_info_) + return gl_version_info_->IsES3Capable(); + return false; +} + +void FeatureInfo::EnableES3Validators() { + DCHECK(IsES3Capable()); + validators_.UpdateValuesES3(); + + GLint max_color_attachments = 0; + glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments); + const int kTotalColorAttachmentEnums = 16; + const GLenum kColorAttachments[] = { + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3, + GL_COLOR_ATTACHMENT4, + GL_COLOR_ATTACHMENT5, + GL_COLOR_ATTACHMENT6, + GL_COLOR_ATTACHMENT7, + GL_COLOR_ATTACHMENT8, + GL_COLOR_ATTACHMENT9, + GL_COLOR_ATTACHMENT10, + GL_COLOR_ATTACHMENT11, + GL_COLOR_ATTACHMENT12, + GL_COLOR_ATTACHMENT13, + GL_COLOR_ATTACHMENT14, + GL_COLOR_ATTACHMENT15, + }; + if (max_color_attachments < kTotalColorAttachmentEnums) { + validators_.attachment.RemoveValues( + kColorAttachments + max_color_attachments, + kTotalColorAttachmentEnums - max_color_attachments); + } + + GLint max_draw_buffers = 0; + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers); + const int kTotalDrawBufferEnums = 16; + const GLenum kDrawBuffers[] = { + GL_DRAW_BUFFER0, + GL_DRAW_BUFFER1, + GL_DRAW_BUFFER2, + GL_DRAW_BUFFER3, + GL_DRAW_BUFFER4, + GL_DRAW_BUFFER5, + GL_DRAW_BUFFER6, + GL_DRAW_BUFFER7, + GL_DRAW_BUFFER8, + GL_DRAW_BUFFER9, + GL_DRAW_BUFFER10, + GL_DRAW_BUFFER11, + GL_DRAW_BUFFER12, + GL_DRAW_BUFFER13, + GL_DRAW_BUFFER14, + GL_DRAW_BUFFER15, + }; + if (max_draw_buffers < kTotalDrawBufferEnums) { + validators_.g_l_state.RemoveValues( + kDrawBuffers + max_draw_buffers, + kTotalDrawBufferEnums - max_draw_buffers); + } } void FeatureInfo::AddExtensionString(const char* s) { diff --git a/chromium/gpu/command_buffer/service/feature_info.h b/chromium/gpu/command_buffer/service/feature_info.h index b69f2e4b7a1..c3ed1502d02 100644 --- a/chromium/gpu/command_buffer/service/feature_info.h +++ b/chromium/gpu/command_buffer/service/feature_info.h @@ -14,6 +14,7 @@ #include "gpu/command_buffer/service/gles2_cmd_validation.h" #include "gpu/config/gpu_driver_bug_workaround_type.h" #include "gpu/gpu_export.h" +#include "ui/gl/gl_version_info.h" namespace base { class CommandLine; @@ -55,7 +56,10 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { bool use_arb_occlusion_query2_for_occlusion_query_boolean; bool use_arb_occlusion_query_for_occlusion_query_boolean; bool native_vertex_array_object; + bool ext_texture_format_atc; bool ext_texture_format_bgra8888; + bool ext_texture_format_dxt1; + bool ext_texture_format_dxt5; bool enable_shader_name_hashing; bool enable_samplers; bool ext_draw_buffers; @@ -66,13 +70,15 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { bool map_buffer_range; bool ext_discard_framebuffer; bool angle_depth_texture; - bool is_angle; bool is_swiftshader; bool angle_texture_usage; bool ext_texture_storage; bool chromium_path_rendering; bool blend_equation_advanced; bool blend_equation_advanced_coherent; + bool ext_texture_rg; + bool enable_subscribe_uniform; + bool emulate_primitive_restart_fixed_index; }; struct Workarounds { @@ -120,6 +126,14 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { return workarounds_; } + const gfx::GLVersionInfo& gl_version_info() const { + DCHECK(gl_version_info_.get()); + return *(gl_version_info_.get()); + } + + bool IsES3Capable() const; + void EnableES3Validators(); + private: friend class base::RefCounted<FeatureInfo>; friend class BufferManagerClientSideArraysTest; @@ -146,6 +160,11 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { // Flags for Workarounds. Workarounds workarounds_; + // Whether the command line switch kEnableUnsafeES3APIs is passed in. + bool unsafe_es3_apis_enabled_; + + scoped_ptr<gfx::GLVersionInfo> gl_version_info_; + DISALLOW_COPY_AND_ASSIGN(FeatureInfo); }; diff --git a/chromium/gpu/command_buffer/service/feature_info_unittest.cc b/chromium/gpu/command_buffer/service/feature_info_unittest.cc index 69bd4d3544d..0136f41fe14 100644 --- a/chromium/gpu/command_buffer/service/feature_info_unittest.cc +++ b/chromium/gpu/command_buffer/service/feature_info_unittest.cc @@ -8,10 +8,10 @@ #include "base/memory/scoped_ptr.h" #include "base/strings/string_number_conversions.h" #include "gpu/command_buffer/service/gpu_service_test.h" -#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/test_helper.h" #include "gpu/command_buffer/service/texture_manager.h" #include "gpu/config/gpu_driver_bug_workaround_type.h" +#include "gpu/config/gpu_switches.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_fence.h" #include "ui/gl/gl_implementation.h" @@ -36,13 +36,36 @@ namespace { const char kGLRendererStringANGLE[] = "ANGLE (some renderer)"; } // anonymous namespace -class FeatureInfoTest : public GpuServiceTest { +enum MockedGLVersionKind { + Version3_0, + Version3_2Compatibility +}; + +class FeatureInfoTest + : public GpuServiceTest, + public ::testing::WithParamInterface<MockedGLVersionKind> { public: FeatureInfoTest() { } void SetupInitExpectations(const char* extensions) { - SetupInitExpectationsWithGLVersion(extensions, "", ""); + std::string extensions_str = extensions; + // Most of the tests' expectations currently assume the desktop + // OpenGL compatibility profile. + switch (GetParam()) { + case Version3_0: + SetupInitExpectationsWithGLVersion(extensions_str.c_str(), "", "3.0"); + break; + case Version3_2Compatibility: + if (extensions_str.find("GL_ARB_compatibility") == std::string::npos) { + extensions_str += " GL_ARB_compatibility"; + } + SetupInitExpectationsWithGLVersion(extensions_str.c_str(), "", "3.2"); + break; + default: + NOTREACHED(); + break; + } } void SetupInitExpectationsWithGLVersion( @@ -54,13 +77,14 @@ class FeatureInfoTest : public GpuServiceTest { info_->Initialize(); } - void SetupWithCommandLine(const CommandLine& command_line) { + void SetupWithCommandLine(const base::CommandLine& command_line) { GpuServiceTest::SetUp(); info_ = new FeatureInfo(command_line); } void SetupInitExpectationsWithCommandLine( - const char* extensions, const CommandLine& command_line) { + const char* extensions, + const base::CommandLine& command_line) { GpuServiceTest::SetUpWithGLVersion("2.0", extensions); TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( gl_.get(), extensions, "", ""); @@ -96,7 +120,16 @@ struct FormatInfo { } // anonymous namespace. -TEST_F(FeatureInfoTest, Basic) { +static const MockedGLVersionKind kGLVersionKinds[] = { + Version3_0, + Version3_2Compatibility +}; + +INSTANTIATE_TEST_CASE_P(Service, + FeatureInfoTest, + ::testing::ValuesIn(kGLVersionKinds)); + +TEST_P(FeatureInfoTest, Basic) { SetupWithoutInit(); // Test it starts off uninitialized. EXPECT_FALSE(info_->feature_flags().chromium_framebuffer_multisample); @@ -127,13 +160,13 @@ TEST_F(FeatureInfoTest, Basic) { EXPECT_FALSE(info_->feature_flags().nv_draw_buffers); EXPECT_FALSE(info_->feature_flags().ext_discard_framebuffer); EXPECT_FALSE(info_->feature_flags().angle_depth_texture); - EXPECT_FALSE(info_->feature_flags().is_angle); #define GPU_OP(type, name) EXPECT_FALSE(info_->workarounds().name); GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP) #undef GPU_OP EXPECT_EQ(0, info_->workarounds().max_texture_size); EXPECT_EQ(0, info_->workarounds().max_cube_map_texture_size); + EXPECT_FALSE(info_->workarounds().gl_clear_broken); // Test good types. { @@ -227,13 +260,14 @@ TEST_F(FeatureInfoTest, Basic) { } } -TEST_F(FeatureInfoTest, InitializeNoExtensions) { +TEST_P(FeatureInfoTest, InitializeNoExtensions) { SetupInitExpectations(""); // Check default extensions are there EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_resource_safe")); EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_strict_attribs")); EXPECT_THAT(info_->extensions(), HasSubstr("GL_ANGLE_translated_shader_source")); + EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_trace_marker")); // Check a couple of random extensions that should not be there. EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_OES_texture_npot"))); @@ -342,24 +376,24 @@ TEST_F(FeatureInfoTest, InitializeNoExtensions) { GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)); } -TEST_F(FeatureInfoTest, InitializeWithANGLE) { +TEST_P(FeatureInfoTest, InitializeWithANGLE) { SetupInitExpectationsWithGLVersion("", kGLRendererStringANGLE, ""); - EXPECT_TRUE(info_->feature_flags().is_angle); + EXPECT_TRUE(info_->gl_version_info().is_angle); } -TEST_F(FeatureInfoTest, InitializeNPOTExtensionGLES) { +TEST_P(FeatureInfoTest, InitializeNPOTExtensionGLES) { SetupInitExpectations("GL_OES_texture_npot"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_npot")); EXPECT_TRUE(info_->feature_flags().npot_ok); } -TEST_F(FeatureInfoTest, InitializeNPOTExtensionGL) { +TEST_P(FeatureInfoTest, InitializeNPOTExtensionGL) { SetupInitExpectations("GL_ARB_texture_non_power_of_two"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_npot")); EXPECT_TRUE(info_->feature_flags().npot_ok); } -TEST_F(FeatureInfoTest, InitializeDXTExtensionGLES2) { +TEST_P(FeatureInfoTest, InitializeDXTExtensionGLES2) { SetupInitExpectations("GL_EXT_texture_compression_dxt1"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_compression_dxt1")); @@ -373,7 +407,7 @@ TEST_F(FeatureInfoTest, InitializeDXTExtensionGLES2) { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)); } -TEST_F(FeatureInfoTest, InitializeDXTExtensionGL) { +TEST_P(FeatureInfoTest, InitializeDXTExtensionGL) { SetupInitExpectations("GL_EXT_texture_compression_s3tc"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_compression_dxt1")); @@ -391,7 +425,7 @@ TEST_F(FeatureInfoTest, InitializeDXTExtensionGL) { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GLES2) { +TEST_P(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GLES2) { SetupInitExpectations("GL_EXT_texture_format_BGRA8888"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); @@ -405,7 +439,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GLES2) { GL_BGRA8_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GL) { +TEST_P(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GL) { SetupInitExpectations("GL_EXT_bgra"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); @@ -425,7 +459,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GL) { GL_BGRA8_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888Apple) { +TEST_P(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888Apple) { SetupInitExpectations("GL_APPLE_texture_format_BGRA8888"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); @@ -439,7 +473,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888Apple) { GL_BGRA8_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_read_format_bgra) { +TEST_P(FeatureInfoTest, InitializeEXT_read_format_bgra) { SetupInitExpectations("GL_EXT_read_format_bgra"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_read_format_bgra")); @@ -453,8 +487,8 @@ TEST_F(FeatureInfoTest, InitializeEXT_read_format_bgra) { GL_BGRA8_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_sRGB) { - SetupInitExpectations("GL_EXT_sRGB"); +TEST_P(FeatureInfoTest, InitializeEXT_sRGB) { + SetupInitExpectations("GL_EXT_sRGB GL_OES_rgb8_rgba8"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_sRGB")); EXPECT_TRUE(info_->GetTextureFormatValidator(GL_SRGB_EXT).IsValid( @@ -475,7 +509,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_sRGB) { GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_texture_storage) { +TEST_P(FeatureInfoTest, InitializeEXT_texture_storage) { SetupInitExpectations("GL_EXT_texture_storage"); EXPECT_TRUE(info_->feature_flags().ext_texture_storage); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); @@ -505,7 +539,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_storage) { GL_LUMINANCE_ALPHA16F_EXT)); } -TEST_F(FeatureInfoTest, InitializeARB_texture_storage) { +TEST_P(FeatureInfoTest, InitializeARB_texture_storage) { SetupInitExpectations("GL_ARB_texture_storage"); EXPECT_TRUE(info_->feature_flags().ext_texture_storage); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); @@ -513,7 +547,7 @@ TEST_F(FeatureInfoTest, InitializeARB_texture_storage) { GL_TEXTURE_IMMUTABLE_FORMAT_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_texture_storage_BGRA) { +TEST_P(FeatureInfoTest, InitializeEXT_texture_storage_BGRA) { SetupInitExpectations("GL_EXT_texture_storage GL_EXT_bgra"); EXPECT_TRUE(info_->feature_flags().ext_texture_storage); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); @@ -522,7 +556,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_storage_BGRA) { EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); } -TEST_F(FeatureInfoTest, InitializeARB_texture_storage_BGRA) { +TEST_P(FeatureInfoTest, InitializeARB_texture_storage_BGRA) { SetupInitExpectations("GL_ARB_texture_storage GL_EXT_bgra"); EXPECT_TRUE(info_->feature_flags().ext_texture_storage); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); @@ -531,7 +565,7 @@ TEST_F(FeatureInfoTest, InitializeARB_texture_storage_BGRA) { EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); } -TEST_F(FeatureInfoTest, InitializeEXT_texture_storage_BGRA8888) { +TEST_P(FeatureInfoTest, InitializeEXT_texture_storage_BGRA8888) { SetupInitExpectations( "GL_EXT_texture_storage GL_EXT_texture_format_BGRA8888"); EXPECT_TRUE(info_->feature_flags().ext_texture_storage); @@ -542,7 +576,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_storage_BGRA8888) { EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_format_BGRA8888")); } -TEST_F(FeatureInfoTest, InitializeEXT_texture_storage_float) { +TEST_P(FeatureInfoTest, InitializeEXT_texture_storage_float) { SetupInitExpectations("GL_EXT_texture_storage GL_OES_texture_float"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_float")); @@ -558,7 +592,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_storage_float) { GL_LUMINANCE_ALPHA32F_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_texture_storage_half_float) { +TEST_P(FeatureInfoTest, InitializeEXT_texture_storage_half_float) { SetupInitExpectations("GL_EXT_texture_storage GL_OES_texture_half_float"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_half_float")); @@ -574,12 +608,12 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_storage_half_float) { GL_LUMINANCE_ALPHA16F_EXT)); } -// Check how to handle ES, texture_storage and BGRA combination; 8 tests. +// Check how to handle ES, texture_storage and BGRA combination; 10 tests. // 1- ES2 + GL_EXT_texture_storage -> GL_EXT_texture_storage (and no // GL_EXT_texture_format_BGRA8888 - we don't claim to handle GL_BGRA8 in // glTexStorage2DEXT) -TEST_F(FeatureInfoTest, InitializeGLES2_texture_storage) { +TEST_P(FeatureInfoTest, InitializeGLES2_texture_storage) { SetupInitExpectationsWithGLVersion( "GL_EXT_texture_storage", "", "OpenGL ES 2.0"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); @@ -589,7 +623,7 @@ TEST_F(FeatureInfoTest, InitializeGLES2_texture_storage) { // 2- ES2 + GL_EXT_texture_storage + (GL_EXT_texture_format_BGRA8888 or // GL_APPLE_texture_format_bgra8888) -TEST_F(FeatureInfoTest, InitializeGLES2_texture_storage_BGRA) { +TEST_P(FeatureInfoTest, InitializeGLES2_texture_storage_BGRA) { SetupInitExpectationsWithGLVersion( "GL_EXT_texture_storage GL_EXT_texture_format_BGRA8888", "", @@ -599,7 +633,7 @@ TEST_F(FeatureInfoTest, InitializeGLES2_texture_storage_BGRA) { } // 3- ES2 + GL_EXT_texture_format_BGRA8888 or GL_APPLE_texture_format_bgra8888 -TEST_F(FeatureInfoTest, InitializeGLES2_texture_format_BGRA) { +TEST_P(FeatureInfoTest, InitializeGLES2_texture_format_BGRA) { SetupInitExpectationsWithGLVersion( "GL_EXT_texture_format_BGRA8888", "", "OpenGL ES 2.0"); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_texture_storage"))); @@ -608,7 +642,7 @@ TEST_F(FeatureInfoTest, InitializeGLES2_texture_format_BGRA) { // 4- ES2 (neither GL_EXT_texture_storage nor GL_EXT_texture_format_BGRA8888) -> // nothing -TEST_F(FeatureInfoTest, InitializeGLES2_neither_texture_storage_nor_BGRA) { +TEST_P(FeatureInfoTest, InitializeGLES2_neither_texture_storage_nor_BGRA) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 2.0"); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_texture_storage"))); EXPECT_THAT(info_->extensions(), @@ -618,7 +652,7 @@ TEST_F(FeatureInfoTest, InitializeGLES2_neither_texture_storage_nor_BGRA) { // 5- ES3 + GL_EXT_texture_format_BGRA8888 -> GL_EXT_texture_format_BGRA8888 // (we can't expose GL_EXT_texture_storage because we fail the GL_BGRA8 // requirement) -TEST_F(FeatureInfoTest, InitializeGLES3_texture_storage_EXT_BGRA) { +TEST_P(FeatureInfoTest, InitializeGLES3_texture_storage_EXT_BGRA) { SetupInitExpectationsWithGLVersion( "GL_EXT_texture_format_BGRA8888", "", "OpenGL ES 3.0"); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_texture_storage"))); @@ -628,7 +662,7 @@ TEST_F(FeatureInfoTest, InitializeGLES3_texture_storage_EXT_BGRA) { // 6- ES3 + GL_APPLE_texture_format_bgra8888 -> GL_EXT_texture_storage + // GL_EXT_texture_format_BGRA8888 (driver promises to handle GL_BGRA8 by // exposing GL_APPLE_texture_format_bgra8888) -TEST_F(FeatureInfoTest, InitializeGLES3_texture_storage_APPLE_BGRA) { +TEST_P(FeatureInfoTest, InitializeGLES3_texture_storage_APPLE_BGRA) { SetupInitExpectationsWithGLVersion( "GL_APPLE_texture_format_BGRA8888", "", "OpenGL ES 3.0"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); @@ -638,7 +672,7 @@ TEST_F(FeatureInfoTest, InitializeGLES3_texture_storage_APPLE_BGRA) { // 7- ES3 + GL_EXT_texture_storage + GL_EXT_texture_format_BGRA8888 -> // GL_EXT_texture_storage + GL_EXT_texture_format_BGRA8888 (driver promises to // handle GL_BGRA8 by exposing GL_EXT_texture_storage) -TEST_F(FeatureInfoTest, InitializeGLES3_EXT_texture_storage_EXT_BGRA) { +TEST_P(FeatureInfoTest, InitializeGLES3_EXT_texture_storage_EXT_BGRA) { SetupInitExpectationsWithGLVersion( "GL_EXT_texture_storage GL_EXT_texture_format_BGRA8888", "", @@ -649,14 +683,32 @@ TEST_F(FeatureInfoTest, InitializeGLES3_EXT_texture_storage_EXT_BGRA) { // 8- ES3 + none of the above -> GL_EXT_texture_storage (and no // GL_EXT_texture_format_BGRA8888 - we don't claim to handle GL_BGRA8) -TEST_F(FeatureInfoTest, InitializeGLES3_texture_storage) { +TEST_P(FeatureInfoTest, InitializeGLES3_texture_storage) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_storage")); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_texture_format_BGRA8888"))); } -TEST_F(FeatureInfoTest, InitializeARB_texture_float) { +// 9- ANGLE will add the GL_CHROMIUM_renderbuffer_format_BGRA8888 extension and +// the GL_BGRA8_EXT render buffer format. +TEST_P(FeatureInfoTest, InitializeWithANGLE_BGRA8) { + SetupInitExpectationsWithGLVersion("", kGLRendererStringANGLE, ""); + EXPECT_TRUE(info_->gl_version_info().is_angle); + EXPECT_THAT(info_->extensions(), + HasSubstr("GL_CHROMIUM_renderbuffer_format_BGRA8888")); + EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid(GL_BGRA8_EXT)); +} + +// 10- vanilla opengl es means no GL_CHROMIUM_renderbuffer_format_BGRA8888 +TEST_P(FeatureInfoTest, + InitializeGLES2_no_CHROMIUM_renderbuffer_format_BGRA8888) { + SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 2.0"); + EXPECT_THAT(info_->extensions(), + Not(HasSubstr("GL_CHROMIUM_renderbuffer_format_BGRA8888"))); +} + +TEST_P(FeatureInfoTest, InitializeARB_texture_float) { SetupInitExpectations("GL_ARB_texture_float"); EXPECT_TRUE(info_->feature_flags().chromium_color_buffer_float_rgba); EXPECT_TRUE(info_->feature_flags().chromium_color_buffer_float_rgb); @@ -669,7 +721,48 @@ TEST_F(FeatureInfoTest, InitializeARB_texture_float) { GL_RGB32F)); } -TEST_F(FeatureInfoTest, InitializeOES_texture_floatGLES2) { +TEST_P(FeatureInfoTest, Initialize_texture_floatGLES3) { + SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); + EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_OES_texture_float"))); + EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_OES_texture_half_float"))); + EXPECT_THAT(info_->extensions(), + Not(HasSubstr("GL_OES_texture_float_linear"))); + EXPECT_THAT(info_->extensions(), + Not(HasSubstr("GL_OES_texture_half_float_linear"))); + EXPECT_FALSE(info_->GetTextureFormatValidator(GL_RGB).IsValid( + GL_FLOAT)); + EXPECT_FALSE(info_->GetTextureFormatValidator(GL_RGBA).IsValid( + GL_FLOAT)); + EXPECT_FALSE(info_->GetTextureFormatValidator(GL_LUMINANCE).IsValid( + GL_FLOAT)); + EXPECT_FALSE(info_->GetTextureFormatValidator(GL_LUMINANCE_ALPHA).IsValid( + GL_FLOAT)); + EXPECT_FALSE(info_->GetTextureFormatValidator(GL_ALPHA).IsValid( + GL_FLOAT)); +} + +TEST_P(FeatureInfoTest, Initialize_sRGBGLES3) { + SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); + EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_EXT_sRGB"))); + EXPECT_FALSE(info_->GetTextureFormatValidator(GL_SRGB_EXT).IsValid( + GL_UNSIGNED_BYTE)); + EXPECT_FALSE(info_->GetTextureFormatValidator(GL_SRGB_ALPHA_EXT).IsValid( + GL_UNSIGNED_BYTE)); + EXPECT_FALSE(info_->validators()->texture_format.IsValid( + GL_SRGB_EXT)); + EXPECT_FALSE(info_->validators()->texture_format.IsValid( + GL_SRGB_ALPHA_EXT)); + EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid( + GL_SRGB_EXT)); + EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid( + GL_SRGB_ALPHA_EXT)); + EXPECT_FALSE(info_->validators()->render_buffer_format.IsValid( + GL_SRGB8_ALPHA8_EXT)); + EXPECT_FALSE(info_->validators()->frame_buffer_parameter.IsValid( + GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)); +} + +TEST_P(FeatureInfoTest, InitializeOES_texture_floatGLES2) { SetupInitExpectations("GL_OES_texture_float"); EXPECT_FALSE(info_->feature_flags().enable_texture_float_linear); EXPECT_FALSE(info_->feature_flags().enable_texture_half_float_linear); @@ -703,7 +796,7 @@ TEST_F(FeatureInfoTest, InitializeOES_texture_floatGLES2) { GL_HALF_FLOAT_OES)); } -TEST_F(FeatureInfoTest, InitializeOES_texture_float_linearGLES2) { +TEST_P(FeatureInfoTest, InitializeOES_texture_float_linearGLES2) { SetupInitExpectations("GL_OES_texture_float GL_OES_texture_float_linear"); EXPECT_TRUE(info_->feature_flags().enable_texture_float_linear); EXPECT_FALSE(info_->feature_flags().enable_texture_half_float_linear); @@ -736,7 +829,7 @@ TEST_F(FeatureInfoTest, InitializeOES_texture_float_linearGLES2) { GL_HALF_FLOAT_OES)); } -TEST_F(FeatureInfoTest, InitializeOES_texture_half_floatGLES2) { +TEST_P(FeatureInfoTest, InitializeOES_texture_half_floatGLES2) { SetupInitExpectations("GL_OES_texture_half_float"); EXPECT_FALSE(info_->feature_flags().enable_texture_float_linear); EXPECT_FALSE(info_->feature_flags().enable_texture_half_float_linear); @@ -770,7 +863,7 @@ TEST_F(FeatureInfoTest, InitializeOES_texture_half_floatGLES2) { GL_HALF_FLOAT_OES)); } -TEST_F(FeatureInfoTest, InitializeOES_texture_half_float_linearGLES2) { +TEST_P(FeatureInfoTest, InitializeOES_texture_half_float_linearGLES2) { SetupInitExpectations( "GL_OES_texture_half_float GL_OES_texture_half_float_linear"); EXPECT_FALSE(info_->feature_flags().enable_texture_float_linear); @@ -805,7 +898,7 @@ TEST_F(FeatureInfoTest, InitializeOES_texture_half_float_linearGLES2) { GL_HALF_FLOAT_OES)); } -TEST_F(FeatureInfoTest, InitializeEXT_framebuffer_multisample) { +TEST_P(FeatureInfoTest, InitializeEXT_framebuffer_multisample) { SetupInitExpectations("GL_EXT_framebuffer_multisample"); EXPECT_TRUE(info_->feature_flags().chromium_framebuffer_multisample); EXPECT_THAT(info_->extensions(), @@ -822,7 +915,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_framebuffer_multisample) { GL_RENDERBUFFER_SAMPLES_EXT)); } -TEST_F(FeatureInfoTest, InitializeANGLE_framebuffer_multisample) { +TEST_P(FeatureInfoTest, InitializeANGLE_framebuffer_multisample) { SetupInitExpectationsWithGLVersion( "GL_ANGLE_framebuffer_multisample", kGLRendererStringANGLE, ""); EXPECT_TRUE(info_->feature_flags().chromium_framebuffer_multisample); @@ -843,7 +936,7 @@ TEST_F(FeatureInfoTest, InitializeANGLE_framebuffer_multisample) { // We don't allow ANGLE_framebuffer_multisample on non-ANGLE implementations, // because we wouldn't be choosing the right driver entry point and because the // extension was falsely advertised on some Android devices (crbug.com/165736). -TEST_F(FeatureInfoTest, InitializeANGLE_framebuffer_multisampleWithoutANGLE) { +TEST_P(FeatureInfoTest, InitializeANGLE_framebuffer_multisampleWithoutANGLE) { SetupInitExpectations("GL_ANGLE_framebuffer_multisample"); EXPECT_FALSE(info_->feature_flags().chromium_framebuffer_multisample); EXPECT_THAT(info_->extensions(), @@ -860,7 +953,7 @@ TEST_F(FeatureInfoTest, InitializeANGLE_framebuffer_multisampleWithoutANGLE) { GL_RENDERBUFFER_SAMPLES_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_multisampled_render_to_texture) { +TEST_P(FeatureInfoTest, InitializeEXT_multisampled_render_to_texture) { SetupInitExpectations("GL_EXT_multisampled_render_to_texture"); EXPECT_TRUE(info_->feature_flags( ).multisampled_render_to_texture); @@ -876,7 +969,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_multisampled_render_to_texture) { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT)); } -TEST_F(FeatureInfoTest, InitializeIMG_multisampled_render_to_texture) { +TEST_P(FeatureInfoTest, InitializeIMG_multisampled_render_to_texture) { SetupInitExpectations("GL_IMG_multisampled_render_to_texture"); EXPECT_TRUE(info_->feature_flags( ).multisampled_render_to_texture); @@ -892,7 +985,7 @@ TEST_F(FeatureInfoTest, InitializeIMG_multisampled_render_to_texture) { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_texture_filter_anisotropic) { +TEST_P(FeatureInfoTest, InitializeEXT_texture_filter_anisotropic) { SetupInitExpectations("GL_EXT_texture_filter_anisotropic"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_texture_filter_anisotropic")); @@ -902,7 +995,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_filter_anisotropic) { GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_ARB_depth_texture) { +TEST_P(FeatureInfoTest, InitializeEXT_ARB_depth_texture) { SetupInitExpectations("GL_ARB_depth_texture"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_GOOGLE_depth_texture")); @@ -922,7 +1015,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_ARB_depth_texture) { GL_UNSIGNED_INT_24_8)); } -TEST_F(FeatureInfoTest, InitializeOES_ARB_depth_texture) { +TEST_P(FeatureInfoTest, InitializeOES_ARB_depth_texture) { SetupInitExpectations("GL_OES_depth_texture"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_GOOGLE_depth_texture")); @@ -942,7 +1035,7 @@ TEST_F(FeatureInfoTest, InitializeOES_ARB_depth_texture) { GL_UNSIGNED_INT_24_8)); } -TEST_F(FeatureInfoTest, InitializeANGLE_depth_texture) { +TEST_P(FeatureInfoTest, InitializeANGLE_depth_texture) { SetupInitExpectations("GL_ANGLE_depth_texture"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_GOOGLE_depth_texture")); @@ -971,7 +1064,7 @@ TEST_F(FeatureInfoTest, InitializeANGLE_depth_texture) { GL_UNSIGNED_INT_24_8)); } -TEST_F(FeatureInfoTest, InitializeEXT_packed_depth_stencil) { +TEST_P(FeatureInfoTest, InitializeEXT_packed_depth_stencil) { SetupInitExpectations("GL_EXT_packed_depth_stencil"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_packed_depth_stencil")); @@ -984,7 +1077,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_packed_depth_stencil) { EXPECT_FALSE(info_->validators()->pixel_type.IsValid(GL_UNSIGNED_INT)); } -TEST_F(FeatureInfoTest, InitializeOES_packed_depth_stencil) { +TEST_P(FeatureInfoTest, InitializeOES_packed_depth_stencil) { SetupInitExpectations("GL_OES_packed_depth_stencil"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_packed_depth_stencil")); @@ -997,7 +1090,7 @@ TEST_F(FeatureInfoTest, InitializeOES_packed_depth_stencil) { EXPECT_FALSE(info_->validators()->pixel_type.IsValid(GL_UNSIGNED_INT)); } -TEST_F(FeatureInfoTest, +TEST_P(FeatureInfoTest, InitializeOES_packed_depth_stencil_and_GL_ARB_depth_texture) { SetupInitExpectations("GL_OES_packed_depth_stencil GL_ARB_depth_texture"); EXPECT_THAT(info_->extensions(), @@ -1018,7 +1111,7 @@ TEST_F(FeatureInfoTest, GL_UNSIGNED_INT_24_8)); } -TEST_F(FeatureInfoTest, InitializeOES_depth24) { +TEST_P(FeatureInfoTest, InitializeOES_depth24) { SetupInitExpectations("GL_OES_depth24"); EXPECT_TRUE(info_->feature_flags().oes_depth24); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_depth24")); @@ -1026,7 +1119,7 @@ TEST_F(FeatureInfoTest, InitializeOES_depth24) { GL_DEPTH_COMPONENT24)); } -TEST_F(FeatureInfoTest, InitializeOES_standard_derivatives) { +TEST_P(FeatureInfoTest, InitializeOES_standard_derivatives) { SetupInitExpectations("GL_OES_standard_derivatives"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_standard_derivatives")); EXPECT_TRUE(info_->feature_flags().oes_standard_derivatives); @@ -1036,7 +1129,7 @@ TEST_F(FeatureInfoTest, InitializeOES_standard_derivatives) { GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES)); } -TEST_F(FeatureInfoTest, InitializeOES_rgb8_rgba8) { +TEST_P(FeatureInfoTest, InitializeOES_rgb8_rgba8) { SetupInitExpectations("GL_OES_rgb8_rgba8"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_rgb8_rgba8")); @@ -1046,7 +1139,7 @@ TEST_F(FeatureInfoTest, InitializeOES_rgb8_rgba8) { GL_RGBA8_OES)); } -TEST_F(FeatureInfoTest, InitializeOES_EGL_image_external) { +TEST_P(FeatureInfoTest, InitializeOES_EGL_image_external) { SetupInitExpectations("GL_OES_EGL_image_external"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_EGL_image_external")); @@ -1061,7 +1154,7 @@ TEST_F(FeatureInfoTest, InitializeOES_EGL_image_external) { GL_TEXTURE_BINDING_EXTERNAL_OES)); } -TEST_F(FeatureInfoTest, InitializeOES_compressed_ETC1_RGB8_texture) { +TEST_P(FeatureInfoTest, InitializeOES_compressed_ETC1_RGB8_texture) { SetupInitExpectations("GL_OES_compressed_ETC1_RGB8_texture"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_compressed_ETC1_RGB8_texture")); @@ -1071,7 +1164,7 @@ TEST_F(FeatureInfoTest, InitializeOES_compressed_ETC1_RGB8_texture) { GL_ETC1_RGB8_OES)); } -TEST_F(FeatureInfoTest, InitializeAMD_compressed_ATC_texture) { +TEST_P(FeatureInfoTest, InitializeAMD_compressed_ATC_texture) { SetupInitExpectations("GL_AMD_compressed_ATC_texture"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_AMD_compressed_ATC_texture")); @@ -1083,7 +1176,7 @@ TEST_F(FeatureInfoTest, InitializeAMD_compressed_ATC_texture) { GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD)); } -TEST_F(FeatureInfoTest, InitializeIMG_texture_compression_pvrtc) { +TEST_P(FeatureInfoTest, InitializeIMG_texture_compression_pvrtc) { SetupInitExpectations("GL_IMG_texture_compression_pvrtc"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_IMG_texture_compression_pvrtc")); @@ -1097,7 +1190,7 @@ TEST_F(FeatureInfoTest, InitializeIMG_texture_compression_pvrtc) { GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG)); } -TEST_F(FeatureInfoTest, InitializeEXT_occlusion_query_boolean) { +TEST_P(FeatureInfoTest, InitializeEXT_occlusion_query_boolean) { SetupInitExpectations("GL_EXT_occlusion_query_boolean"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_occlusion_query_boolean")); @@ -1108,7 +1201,7 @@ TEST_F(FeatureInfoTest, InitializeEXT_occlusion_query_boolean) { ).use_arb_occlusion_query_for_occlusion_query_boolean); } -TEST_F(FeatureInfoTest, InitializeARB_occlusion_query) { +TEST_P(FeatureInfoTest, InitializeARB_occlusion_query) { SetupInitExpectations("GL_ARB_occlusion_query"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_occlusion_query_boolean")); @@ -1119,7 +1212,7 @@ TEST_F(FeatureInfoTest, InitializeARB_occlusion_query) { ).use_arb_occlusion_query_for_occlusion_query_boolean); } -TEST_F(FeatureInfoTest, InitializeARB_occlusion_query2) { +TEST_P(FeatureInfoTest, InitializeARB_occlusion_query2) { SetupInitExpectations("GL_ARB_occlusion_query2 GL_ARB_occlusion_query2"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_occlusion_query_boolean")); @@ -1130,28 +1223,28 @@ TEST_F(FeatureInfoTest, InitializeARB_occlusion_query2) { ).use_arb_occlusion_query_for_occlusion_query_boolean); } -TEST_F(FeatureInfoTest, InitializeOES_vertex_array_object) { +TEST_P(FeatureInfoTest, InitializeOES_vertex_array_object) { SetupInitExpectations("GL_OES_vertex_array_object"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_vertex_array_object")); EXPECT_TRUE(info_->feature_flags().native_vertex_array_object); } -TEST_F(FeatureInfoTest, InitializeARB_vertex_array_object) { +TEST_P(FeatureInfoTest, InitializeARB_vertex_array_object) { SetupInitExpectations("GL_ARB_vertex_array_object"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_vertex_array_object")); EXPECT_TRUE(info_->feature_flags().native_vertex_array_object); } -TEST_F(FeatureInfoTest, InitializeAPPLE_vertex_array_object) { +TEST_P(FeatureInfoTest, InitializeAPPLE_vertex_array_object) { SetupInitExpectations("GL_APPLE_vertex_array_object"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_vertex_array_object")); EXPECT_TRUE(info_->feature_flags().native_vertex_array_object); } -TEST_F(FeatureInfoTest, InitializeNo_vertex_array_object) { +TEST_P(FeatureInfoTest, InitializeNo_vertex_array_object) { SetupInitExpectations(""); // Even if the native extensions are not available the implementation // may still emulate the GL_OES_vertex_array_object functionality. In this @@ -1161,15 +1254,15 @@ TEST_F(FeatureInfoTest, InitializeNo_vertex_array_object) { EXPECT_FALSE(info_->feature_flags().native_vertex_array_object); } -TEST_F(FeatureInfoTest, InitializeOES_element_index_uint) { +TEST_P(FeatureInfoTest, InitializeOES_element_index_uint) { SetupInitExpectations("GL_OES_element_index_uint"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_element_index_uint")); EXPECT_TRUE(info_->validators()->index_type.IsValid(GL_UNSIGNED_INT)); } -TEST_F(FeatureInfoTest, InitializeVAOsWithClientSideArrays) { - CommandLine command_line(0, NULL); +TEST_P(FeatureInfoTest, InitializeVAOsWithClientSideArrays) { + base::CommandLine command_line(0, NULL); command_line.AppendSwitchASCII( switches::kGpuDriverBugWorkarounds, base::IntToString(gpu::USE_CLIENT_SIDE_ARRAYS_FOR_STREAM_BUFFERS)); @@ -1179,38 +1272,38 @@ TEST_F(FeatureInfoTest, InitializeVAOsWithClientSideArrays) { EXPECT_FALSE(info_->feature_flags().native_vertex_array_object); } -TEST_F(FeatureInfoTest, InitializeEXT_blend_minmax) { +TEST_P(FeatureInfoTest, InitializeEXT_blend_minmax) { SetupInitExpectations("GL_EXT_blend_minmax"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_blend_minmax")); EXPECT_TRUE(info_->validators()->equation.IsValid(GL_MIN_EXT)); EXPECT_TRUE(info_->validators()->equation.IsValid(GL_MAX_EXT)); } -TEST_F(FeatureInfoTest, InitializeEXT_frag_depth) { +TEST_P(FeatureInfoTest, InitializeEXT_frag_depth) { SetupInitExpectations("GL_EXT_frag_depth"); EXPECT_TRUE(info_->feature_flags().ext_frag_depth); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_frag_depth")); } -TEST_F(FeatureInfoTest, InitializeEXT_shader_texture_lod) { +TEST_P(FeatureInfoTest, InitializeEXT_shader_texture_lod) { SetupInitExpectations("GL_EXT_shader_texture_lod"); EXPECT_TRUE(info_->feature_flags().ext_shader_texture_lod); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_shader_texture_lod")); } -TEST_F(FeatureInfoTest, InitializeEXT_discard_framebuffer) { +TEST_P(FeatureInfoTest, InitializeEXT_discard_framebuffer) { SetupInitExpectations("GL_EXT_discard_framebuffer"); EXPECT_TRUE(info_->feature_flags().ext_discard_framebuffer); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_discard_framebuffer")); } -TEST_F(FeatureInfoTest, InitializeSamplersWithARBSamplerObjects) { +TEST_P(FeatureInfoTest, InitializeSamplersWithARBSamplerObjects) { SetupInitExpectationsWithGLVersion( "GL_ARB_sampler_objects", "", "OpenGL 3.0"); EXPECT_TRUE(info_->feature_flags().enable_samplers); } -TEST_F(FeatureInfoTest, InitializeWithES3) { +TEST_P(FeatureInfoTest, InitializeWithES3) { SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); EXPECT_TRUE(info_->feature_flags().chromium_framebuffer_multisample); EXPECT_TRUE(info_->feature_flags().use_core_framebuffer_multisample); @@ -1255,13 +1348,13 @@ TEST_F(FeatureInfoTest, InitializeWithES3) { EXPECT_TRUE(gfx::GLFence::IsSupported()); } -TEST_F(FeatureInfoTest, InitializeWithoutSamplers) { +TEST_P(FeatureInfoTest, InitializeWithoutSamplers) { SetupInitExpectationsWithGLVersion("", "", "OpenGL GL 3.0"); EXPECT_FALSE(info_->feature_flags().enable_samplers); } -TEST_F(FeatureInfoTest, ParseDriverBugWorkaroundsSingle) { - CommandLine command_line(0, NULL); +TEST_P(FeatureInfoTest, ParseDriverBugWorkaroundsSingle) { + base::CommandLine command_line(0, NULL); command_line.AppendSwitchASCII( switches::kGpuDriverBugWorkarounds, base::IntToString(gpu::EXIT_ON_CONTEXT_LOST)); @@ -1270,8 +1363,8 @@ TEST_F(FeatureInfoTest, ParseDriverBugWorkaroundsSingle) { EXPECT_TRUE(info_->workarounds().exit_on_context_lost); } -TEST_F(FeatureInfoTest, ParseDriverBugWorkaroundsMultiple) { - CommandLine command_line(0, NULL); +TEST_P(FeatureInfoTest, ParseDriverBugWorkaroundsMultiple) { + base::CommandLine command_line(0, NULL); command_line.AppendSwitchASCII( switches::kGpuDriverBugWorkarounds, base::IntToString(gpu::EXIT_ON_CONTEXT_LOST) + "," + @@ -1284,33 +1377,33 @@ TEST_F(FeatureInfoTest, ParseDriverBugWorkaroundsMultiple) { EXPECT_EQ(4096, info_->workarounds().max_texture_size); } -TEST_F(FeatureInfoTest, InitializeWithARBSync) { +TEST_P(FeatureInfoTest, InitializeWithARBSync) { SetupInitExpectations("GL_ARB_sync"); EXPECT_TRUE(info_->feature_flags().chromium_sync_query); EXPECT_TRUE(gfx::GLFence::IsSupported()); } -TEST_F(FeatureInfoTest, InitializeWithNVFence) { +TEST_P(FeatureInfoTest, InitializeWithNVFence) { SetupInitExpectations("GL_NV_fence"); EXPECT_TRUE(info_->feature_flags().chromium_sync_query); EXPECT_TRUE(gfx::GLFence::IsSupported()); } -TEST_F(FeatureInfoTest, InitializeWithNVDrawBuffers) { +TEST_P(FeatureInfoTest, InitializeWithNVDrawBuffers) { SetupInitExpectationsWithGLVersion("GL_NV_draw_buffers", "", "OpenGL ES 3.0"); EXPECT_TRUE(info_->feature_flags().nv_draw_buffers); EXPECT_TRUE(info_->feature_flags().ext_draw_buffers); } -TEST_F(FeatureInfoTest, InitializeWithPreferredEXTDrawBuffers) { +TEST_P(FeatureInfoTest, InitializeWithPreferredEXTDrawBuffers) { SetupInitExpectationsWithGLVersion( "GL_NV_draw_buffers GL_EXT_draw_buffers", "", "OpenGL ES 3.0"); EXPECT_FALSE(info_->feature_flags().nv_draw_buffers); EXPECT_TRUE(info_->feature_flags().ext_draw_buffers); } -TEST_F(FeatureInfoTest, ARBSyncDisabled) { - CommandLine command_line(0, NULL); +TEST_P(FeatureInfoTest, ARBSyncDisabled) { + base::CommandLine command_line(0, NULL); command_line.AppendSwitchASCII( switches::kGpuDriverBugWorkarounds, base::IntToString(gpu::DISABLE_ARB_SYNC)); @@ -1319,61 +1412,75 @@ TEST_F(FeatureInfoTest, ARBSyncDisabled) { EXPECT_FALSE(gfx::GLFence::IsSupported()); } -TEST_F(FeatureInfoTest, InitializeCHROMIUM_path_rendering) { +TEST_P(FeatureInfoTest, BlendEquationAdvancedDisabled) { + base::CommandLine command_line(0, NULL); + command_line.AppendSwitchASCII( + switches::kGpuDriverBugWorkarounds, + base::IntToString(gpu::DISABLE_BLEND_EQUATION_ADVANCED)); + SetupInitExpectationsWithCommandLine( + "GL_KHR_blend_equation_advanced_coherent GL_KHR_blend_equation_advanced", + command_line); + EXPECT_FALSE(info_->feature_flags().blend_equation_advanced); + EXPECT_FALSE(info_->feature_flags().blend_equation_advanced_coherent); +} + +TEST_P(FeatureInfoTest, InitializeCHROMIUM_path_rendering) { SetupInitExpectationsWithGLVersion( - "GL_NV_path_rendering GL_EXT_direct_state_access", "", "4.3"); + "GL_ARB_compatibility GL_NV_path_rendering GL_EXT_direct_state_access", + "", "4.3"); EXPECT_TRUE(info_->feature_flags().chromium_path_rendering); EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_path_rendering")); } -TEST_F(FeatureInfoTest, InitializeCHROMIUM_path_rendering2) { +TEST_P(FeatureInfoTest, InitializeCHROMIUM_path_rendering2) { SetupInitExpectationsWithGLVersion( "GL_NV_path_rendering", "", "OpenGL ES 3.1"); EXPECT_TRUE(info_->feature_flags().chromium_path_rendering); EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_path_rendering")); } -TEST_F(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering) { - SetupInitExpectationsWithGLVersion("", "", "4.3"); +TEST_P(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering) { + SetupInitExpectationsWithGLVersion("GL_ARB_compatibility", "", "4.3"); EXPECT_FALSE(info_->feature_flags().chromium_path_rendering); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_CHROMIUM_path_rendering"))); } -TEST_F(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering2) { - SetupInitExpectationsWithGLVersion("GL_NV_path_rendering", "", "4.3"); +TEST_P(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering2) { + SetupInitExpectationsWithGLVersion( + "GL_ARB_compatibility GL_NV_path_rendering", "", "4.3"); EXPECT_FALSE(info_->feature_flags().chromium_path_rendering); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_CHROMIUM_path_rendering"))); } -TEST_F(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced) { - SetupInitExpectationsWithGLVersion("", "", "4.3"); +TEST_P(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced) { + SetupInitExpectationsWithGLVersion("GL_ARB_compatibility", "", "4.3"); EXPECT_FALSE(info_->feature_flags().blend_equation_advanced); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_KHR_blend_equation_advanced"))); } -TEST_F(FeatureInfoTest, InitializeKHR_blend_equations_advanced) { +TEST_P(FeatureInfoTest, InitializeKHR_blend_equations_advanced) { SetupInitExpectations("GL_KHR_blend_equation_advanced"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_KHR_blend_equation_advanced")); EXPECT_TRUE(info_->feature_flags().blend_equation_advanced); } -TEST_F(FeatureInfoTest, InitializeNV_blend_equations_advanced) { +TEST_P(FeatureInfoTest, InitializeNV_blend_equations_advanced) { SetupInitExpectations("GL_NV_blend_equation_advanced"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_KHR_blend_equation_advanced")); EXPECT_TRUE(info_->feature_flags().blend_equation_advanced); } -TEST_F(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced_coherent) { - SetupInitExpectationsWithGLVersion("", "", "4.3"); +TEST_P(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced_coherent) { + SetupInitExpectationsWithGLVersion("GL_ARB_compatibility ", "", "4.3"); EXPECT_FALSE(info_->feature_flags().blend_equation_advanced_coherent); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_KHR_blend_equation_advanced_coherent"))); } -TEST_F(FeatureInfoTest, InitializeKHR_blend_equations_advanced_coherent) { +TEST_P(FeatureInfoTest, InitializeKHR_blend_equations_advanced_coherent) { SetupInitExpectations("GL_KHR_blend_equation_advanced_coherent"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_KHR_blend_equation_advanced_coherent")); @@ -1381,5 +1488,57 @@ TEST_F(FeatureInfoTest, InitializeKHR_blend_equations_advanced_coherent) { EXPECT_TRUE(info_->feature_flags().blend_equation_advanced_coherent); } +TEST_P(FeatureInfoTest, InitializeEXT_texture_rgWithFloat) { + SetupInitExpectations( + "GL_EXT_texture_rg GL_OES_texture_float GL_OES_texture_half_float"); + EXPECT_TRUE(info_->feature_flags().ext_texture_rg); + + EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_RED_EXT)); + EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_RG_EXT)); + EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid(GL_RED_EXT)); + EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid(GL_RG_EXT)); + EXPECT_TRUE(info_->validators()->read_pixel_format.IsValid(GL_RED_EXT)); + EXPECT_TRUE(info_->validators()->read_pixel_format.IsValid(GL_RG_EXT)); + EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid(GL_R8_EXT)); + EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid(GL_RG8_EXT)); + + EXPECT_TRUE( + info_->GetTextureFormatValidator(GL_RED_EXT).IsValid(GL_HALF_FLOAT_OES)); + EXPECT_TRUE( + info_->GetTextureFormatValidator(GL_RG_EXT).IsValid(GL_HALF_FLOAT_OES)); + EXPECT_TRUE( + info_->GetTextureFormatValidator(GL_RED_EXT).IsValid(GL_UNSIGNED_BYTE)); + EXPECT_TRUE( + info_->GetTextureFormatValidator(GL_RG_EXT).IsValid(GL_UNSIGNED_BYTE)); + + EXPECT_FALSE(info_->GetTextureFormatValidator(GL_RED_EXT).IsValid(GL_BYTE)); + EXPECT_FALSE(info_->GetTextureFormatValidator(GL_RG_EXT).IsValid(GL_BYTE)); + EXPECT_FALSE(info_->GetTextureFormatValidator(GL_RED_EXT).IsValid(GL_SHORT)); + EXPECT_FALSE(info_->GetTextureFormatValidator(GL_RG_EXT).IsValid(GL_SHORT)); +} + +TEST_P(FeatureInfoTest, InitializeARB_texture_rgNoFloat) { + SetupInitExpectations("GL_ARB_texture_rg"); + EXPECT_TRUE(info_->feature_flags().ext_texture_rg); + + EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_RED_EXT)); + EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_RG_EXT)); + EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid(GL_RED_EXT)); + EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid(GL_RG_EXT)); + EXPECT_TRUE(info_->validators()->read_pixel_format.IsValid(GL_RED_EXT)); + EXPECT_TRUE(info_->validators()->read_pixel_format.IsValid(GL_RG_EXT)); + EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid(GL_R8_EXT)); + EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid(GL_RG8_EXT)); + + EXPECT_FALSE( + info_->GetTextureFormatValidator(GL_RED_EXT).IsValid(GL_HALF_FLOAT_OES)); + EXPECT_FALSE( + info_->GetTextureFormatValidator(GL_RG_EXT).IsValid(GL_HALF_FLOAT_OES)); + EXPECT_TRUE( + info_->GetTextureFormatValidator(GL_RED_EXT).IsValid(GL_UNSIGNED_BYTE)); + EXPECT_TRUE( + info_->GetTextureFormatValidator(GL_RG_EXT).IsValid(GL_UNSIGNED_BYTE)); +} + } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/framebuffer_manager.cc b/chromium/gpu/command_buffer/service/framebuffer_manager.cc index d766abb96f0..173c2868ed0 100644 --- a/chromium/gpu/command_buffer/service/framebuffer_manager.cc +++ b/chromium/gpu/command_buffer/service/framebuffer_manager.cc @@ -135,7 +135,7 @@ class TextureAttachment GLsizei temp_width = 0; GLsizei temp_height = 0; texture_ref_->texture()->GetLevelSize( - target_, level_, &temp_width, &temp_height); + target_, level_, &temp_width, &temp_height, nullptr); return temp_width; } @@ -143,7 +143,7 @@ class TextureAttachment GLsizei temp_width = 0; GLsizei temp_height = 0; texture_ref_->texture()->GetLevelSize( - target_, level_, &temp_width, &temp_height); + target_, level_, &temp_width, &temp_height, nullptr); return temp_height; } @@ -631,6 +631,14 @@ void FramebufferManager::RemoveFramebuffer(GLuint client_id) { } } +void Framebuffer::DoUnbindGLAttachmentsForWorkaround(GLenum target) { + // Replace all attachments with the default Renderbuffer. + for (AttachmentMap::const_iterator it = attachments_.begin(); + it != attachments_.end(); ++it) { + glFramebufferRenderbufferEXT(target, it->first, GL_RENDERBUFFER, 0); + } +} + void Framebuffer::AttachRenderbuffer( GLenum attachment, Renderbuffer* renderbuffer) { const Attachment* a = GetAttachment(attachment); diff --git a/chromium/gpu/command_buffer/service/framebuffer_manager.h b/chromium/gpu/command_buffer/service/framebuffer_manager.h index 78c11ad2244..75f7e2a7ec6 100644 --- a/chromium/gpu/command_buffer/service/framebuffer_manager.h +++ b/chromium/gpu/command_buffer/service/framebuffer_manager.h @@ -74,6 +74,11 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { GLenum attachment, bool cleared); + // Unbinds all attachments from this framebuffer for workaround + // 'unbind_attachments_on_bound_render_fbo_delete'. The Framebuffer must be + // bound when calling this. + void DoUnbindGLAttachmentsForWorkaround(GLenum target); + // Attaches a renderbuffer to a particlar attachment. // Pass null to detach. void AttachRenderbuffer( diff --git a/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc index 88567b795a5..e1af82d1059 100644 --- a/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc @@ -21,11 +21,12 @@ namespace { const GLint kMaxTextureSize = 64; const GLint kMaxCubemapSize = 64; +const GLint kMaxRectangleTextureSize = 64; +const GLint kMax3DTextureSize = 256; const GLint kMaxRenderbufferSize = 64; const GLint kMaxSamples = 4; const uint32 kMaxDrawBuffers = 16; const uint32 kMaxColorAttachments = 16; -const bool kDepth24Supported = false; const bool kUseDefaultTextures = false; } // namespace @@ -34,26 +35,31 @@ class FramebufferManagerTest : public GpuServiceTest { public: FramebufferManagerTest() : manager_(1, 1), - texture_manager_(NULL, - new FeatureInfo(), - kMaxTextureSize, - kMaxCubemapSize, - kUseDefaultTextures), - renderbuffer_manager_(NULL, - kMaxRenderbufferSize, - kMaxSamples, - kDepth24Supported) {} + feature_info_(new FeatureInfo()) { + texture_manager_.reset(new TextureManager(NULL, + feature_info_.get(), + kMaxTextureSize, + kMaxCubemapSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, + kUseDefaultTextures)); + renderbuffer_manager_.reset(new RenderbufferManager(NULL, + kMaxRenderbufferSize, + kMaxSamples, + feature_info_.get())); + } ~FramebufferManagerTest() override { manager_.Destroy(false); - texture_manager_.Destroy(false); - renderbuffer_manager_.Destroy(false); + texture_manager_->Destroy(false); + renderbuffer_manager_->Destroy(false); } protected: FramebufferManager manager_; - TextureManager texture_manager_; - RenderbufferManager renderbuffer_manager_; + scoped_refptr<FeatureInfo> feature_info_; + scoped_ptr<TextureManager> texture_manager_; + scoped_ptr<RenderbufferManager> renderbuffer_manager_; }; TEST_F(FramebufferManagerTest, Basic) { @@ -107,26 +113,32 @@ class FramebufferInfoTest : public GpuServiceTest { FramebufferInfoTest() : manager_(kMaxDrawBuffers, kMaxColorAttachments), - feature_info_(new FeatureInfo()), - renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples, - kDepth24Supported) { + feature_info_(new FeatureInfo()) { texture_manager_.reset(new TextureManager(NULL, feature_info_.get(), kMaxTextureSize, kMaxCubemapSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures)); + renderbuffer_manager_.reset(new RenderbufferManager(NULL, + kMaxRenderbufferSize, + kMaxSamples, + feature_info_.get())); } ~FramebufferInfoTest() override { manager_.Destroy(false); texture_manager_->Destroy(false); - renderbuffer_manager_.Destroy(false); + renderbuffer_manager_->Destroy(false); } protected: - void SetUp() override { InitializeContext("", ""); } + void SetUp() override { + InitializeContext("2.0", "GL_EXT_framebuffer_object"); + } void InitializeContext(const char* gl_version, const char* extensions) { - GpuServiceTest::SetUp(); + GpuServiceTest::SetUpWithGLVersion(gl_version, extensions); TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(gl_.get(), extensions, "", gl_version); feature_info_->Initialize(); @@ -140,7 +152,7 @@ class FramebufferInfoTest : public GpuServiceTest { Framebuffer* framebuffer_; scoped_refptr<FeatureInfo> feature_info_; scoped_ptr<TextureManager> texture_manager_; - RenderbufferManager renderbuffer_manager_; + scoped_ptr<RenderbufferManager> renderbuffer_manager_; scoped_ptr<MockErrorState> error_state_; }; @@ -200,10 +212,10 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { EXPECT_FALSE( framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)); - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient1Id, kRenderbufferService1Id); Renderbuffer* renderbuffer1 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id); ASSERT_TRUE(renderbuffer1 != NULL); // check adding one attachment @@ -219,13 +231,13 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { EXPECT_TRUE(framebuffer_->IsCleared()); // Try a format that's not good for COLOR_ATTACHMENT0. - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer1, kSamples1, kBadFormat1, kWidth1, kHeight1); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), framebuffer_->IsPossiblyComplete()); // Try a good format. - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1); EXPECT_EQ(static_cast<GLenum>(kFormat1), framebuffer_->GetColorAttachmentFormat()); @@ -236,10 +248,10 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { EXPECT_FALSE(framebuffer_->IsCleared()); // check adding another - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient2Id, kRenderbufferService2Id); Renderbuffer* renderbuffer2 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient2Id); ASSERT_TRUE(renderbuffer2 != NULL); framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer2); EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); @@ -258,7 +270,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT); EXPECT_FALSE(framebuffer_->IsCleared()); - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer2, kSamples2, kFormat2, kWidth2, kHeight2); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), framebuffer_->IsPossiblyComplete()); @@ -267,7 +279,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { // check marking them as cleared. manager_.MarkAttachmentsAsCleared( - framebuffer_, &renderbuffer_manager_, texture_manager_.get()); + framebuffer_, renderbuffer_manager_.get(), texture_manager_.get()); EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT)); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), @@ -275,14 +287,14 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { EXPECT_TRUE(framebuffer_->IsCleared()); // Check adding one that is already cleared. - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient3Id, kRenderbufferService3Id); Renderbuffer* renderbuffer3 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient3Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient3Id); ASSERT_TRUE(renderbuffer3 != NULL); - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer3, kSamples3, kFormat3, kWidth3, kHeight3); - renderbuffer_manager_.SetCleared(renderbuffer3, true); + renderbuffer_manager_->SetCleared(renderbuffer3, true); framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer3); EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT)); @@ -295,7 +307,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { EXPECT_TRUE(framebuffer_->IsCleared()); // Check marking the renderbuffer as unclared. - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1); EXPECT_EQ(static_cast<GLenum>(kFormat1), framebuffer_->GetColorAttachmentFormat()); @@ -318,17 +330,17 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { // Clear it. manager_.MarkAttachmentsAsCleared( - framebuffer_, &renderbuffer_manager_, texture_manager_.get()); + framebuffer_, renderbuffer_manager_.get(), texture_manager_.get()); EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); EXPECT_TRUE(framebuffer_->IsCleared()); // Check replacing an attachment - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient4Id, kRenderbufferService4Id); Renderbuffer* renderbuffer4 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient4Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient4Id); ASSERT_TRUE(renderbuffer4 != NULL); - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer4, kSamples4, kFormat4, kWidth4, kHeight4); framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer4); @@ -346,7 +358,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { framebuffer_->IsPossiblyComplete()); // Check changing an attachment. - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer4, kSamples4, kFormat4, kWidth4 + 1, kHeight4); attachment = framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT); @@ -374,7 +386,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { // Remove depth, Set color to 0 size. framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, NULL); - renderbuffer_manager_.SetInfo(renderbuffer1, kSamples1, kFormat1, 0, 0); + renderbuffer_manager_->SetInfo(renderbuffer1, kSamples1, kFormat1, 0, 0); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), framebuffer_->IsPossiblyComplete()); @@ -730,15 +742,15 @@ TEST_F(FramebufferInfoTest, UnbindRenderbuffer) { const GLuint kRenderbufferClient2Id = 34; const GLuint kRenderbufferService2Id = 334; - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient1Id, kRenderbufferService1Id); Renderbuffer* renderbuffer1 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id); ASSERT_TRUE(renderbuffer1 != NULL); - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient2Id, kRenderbufferService2Id); Renderbuffer* renderbuffer2 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient2Id); ASSERT_TRUE(renderbuffer2 != NULL); // Attach to 2 attachment points. @@ -806,10 +818,10 @@ TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) { const GLint kLevel1 = 0; const GLint kSamples1 = 0; - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient1Id, kRenderbufferService1Id); Renderbuffer* renderbuffer1 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id); ASSERT_TRUE(renderbuffer1 != NULL); texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id); scoped_refptr<TextureRef> texture2( @@ -831,7 +843,7 @@ TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) { // Check MarkAttachmentsAsCleared marks as complete. manager_.MarkAttachmentsAsCleared( - framebuffer_, &renderbuffer_manager_, texture_manager_.get()); + framebuffer_, renderbuffer_manager_.get(), texture_manager_.get()); EXPECT_TRUE(manager_.IsComplete(framebuffer_)); // Check Unbind marks as not complete. @@ -852,10 +864,10 @@ TEST_F(FramebufferInfoTest, GetStatus) { const GLint kLevel1 = 0; const GLint kSamples1 = 0; - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient1Id, kRenderbufferService1Id); Renderbuffer* renderbuffer1 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id); ASSERT_TRUE(renderbuffer1 != NULL); texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id); scoped_refptr<TextureRef> texture2( diff --git a/chromium/gpu/command_buffer/service/gl_context_mock.cc b/chromium/gpu/command_buffer/service/gl_context_mock.cc new file mode 100644 index 00000000000..ce5d10f2770 --- /dev/null +++ b/chromium/gpu/command_buffer/service/gl_context_mock.cc @@ -0,0 +1,14 @@ +// Copyright 2015 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 "gpu/command_buffer/service/gl_context_mock.h" + +namespace gpu { + +GLContextMock::GLContextMock() { +} +GLContextMock::~GLContextMock() { +} + +} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/gl_context_mock.h b/chromium/gpu/command_buffer/service/gl_context_mock.h new file mode 100644 index 00000000000..77d669cad6a --- /dev/null +++ b/chromium/gpu/command_buffer/service/gl_context_mock.h @@ -0,0 +1,25 @@ +// Copyright 2015 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. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_GL_CONTEXT_MOCK_H_ +#define GPU_COMMAND_BUFFER_SERVICE_GL_CONTEXT_MOCK_H_ + +#include "testing/gmock/include/gmock/gmock.h" +#include "ui/gl/gl_context_stub_with_extensions.h" + +namespace gpu { + +class GLContextMock : public gfx::GLContextStubWithExtensions { + public: + GLContextMock(); + + MOCK_METHOD1(MakeCurrent, bool(gfx::GLSurface* surface)); + + protected: + virtual ~GLContextMock(); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_GL_CONTEXT_MOCK_H_ diff --git a/chromium/gpu/command_buffer/service/gl_context_virtual.cc b/chromium/gpu/command_buffer/service/gl_context_virtual.cc index a29e540981b..3abcb137308 100644 --- a/chromium/gpu/command_buffer/service/gl_context_virtual.cc +++ b/chromium/gpu/command_buffer/service/gl_context_virtual.cc @@ -6,7 +6,9 @@ #include "gpu/command_buffer/service/gl_state_restorer_impl.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" +#include "ui/gl/gl_gl_api_implementation.h" #include "ui/gl/gl_surface.h" +#include "ui/gl/gpu_timing.h" namespace gpu { @@ -16,20 +18,13 @@ GLContextVirtual::GLContextVirtual( base::WeakPtr<gles2::GLES2Decoder> decoder) : GLContext(share_group), shared_context_(shared_context), - display_(NULL), decoder_(decoder) { } -gfx::Display* GLContextVirtual::display() { - return display_; -} - bool GLContextVirtual::Initialize( gfx::GLSurface* compatible_surface, gfx::GpuPreference gpu_preference) { SetGLStateRestorer(new GLStateRestorerImpl(decoder_)); - display_ = static_cast<gfx::Display*>(compatible_surface->GetDisplay()); - // Virtual contexts obviously can't make a context that is compatible // with the surface (the context already exists), but we do need to // make a context current for SetupForVirtualization() below. @@ -50,7 +45,6 @@ bool GLContextVirtual::Initialize( void GLContextVirtual::Destroy() { shared_context_->OnReleaseVirtuallyCurrent(this); shared_context_ = NULL; - display_ = NULL; } bool GLContextVirtual::MakeCurrent(gfx::GLSurface* surface) { @@ -82,7 +76,11 @@ void* GLContextVirtual::GetHandle() { return shared_context_->GetHandle(); } -void GLContextVirtual::SetSwapInterval(int interval) { +scoped_refptr<gfx::GPUTimingClient> GLContextVirtual::CreateGPUTimingClient() { + return shared_context_->CreateGPUTimingClient(); +} + +void GLContextVirtual::OnSetSwapInterval(int interval) { shared_context_->SetSwapInterval(interval); } @@ -109,6 +107,21 @@ void GLContextVirtual::SetUnbindFboOnMakeCurrent() { shared_context_->SetUnbindFboOnMakeCurrent(); } +base::Closure GLContextVirtual::GetStateWasDirtiedExternallyCallback() { + return shared_context_->GetStateWasDirtiedExternallyCallback(); +} + +void GLContextVirtual::RestoreStateIfDirtiedExternally() { + // The dirty bit should only be cleared after the state has been restored, + // which should be done only when the context is current. + DCHECK(IsCurrent(NULL)); + if (!shared_context_->GetStateWasDirtiedExternally()) + return; + gfx::ScopedSetGLToRealGLApi scoped_set_gl_api; + GetGLStateRestorer()->RestoreState(NULL); + shared_context_->SetStateWasDirtiedExternally(false); +} + GLContextVirtual::~GLContextVirtual() { Destroy(); } diff --git a/chromium/gpu/command_buffer/service/gl_context_virtual.h b/chromium/gpu/command_buffer/service/gl_context_virtual.h index ed610169a08..1d82d5ac784 100644 --- a/chromium/gpu/command_buffer/service/gl_context_virtual.h +++ b/chromium/gpu/command_buffer/service/gl_context_virtual.h @@ -31,8 +31,6 @@ class GPU_EXPORT GLContextVirtual : public gfx::GLContext { gfx::GLContext* shared_context, base::WeakPtr<gles2::GLES2Decoder> decoder); - gfx::Display* display(); - // Implement GLContext. bool Initialize(gfx::GLSurface* compatible_surface, gfx::GpuPreference gpu_preference) override; @@ -41,19 +39,21 @@ class GPU_EXPORT GLContextVirtual : public gfx::GLContext { void ReleaseCurrent(gfx::GLSurface* surface) override; bool IsCurrent(gfx::GLSurface* surface) override; void* GetHandle() override; - void SetSwapInterval(int interval) override; + scoped_refptr<gfx::GPUTimingClient> CreateGPUTimingClient() override; + void OnSetSwapInterval(int interval) override; std::string GetExtensions() override; bool GetTotalGpuMemory(size_t* bytes) override; void SetSafeToForceGpuSwitch() override; bool WasAllocatedUsingRobustnessExtension() override; void SetUnbindFboOnMakeCurrent() override; + base::Closure GetStateWasDirtiedExternallyCallback() override; + void RestoreStateIfDirtiedExternally() override; protected: ~GLContextVirtual() override; private: scoped_refptr<gfx::GLContext> shared_context_; - gfx::Display* display_; base::WeakPtr<gles2::GLES2Decoder> decoder_; DISALLOW_COPY_AND_ASSIGN(GLContextVirtual); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.cc b/chromium/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.cc new file mode 100644 index 00000000000..4a9aaa7824f --- /dev/null +++ b/chromium/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.cc @@ -0,0 +1,188 @@ +// Copyright 2014 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 "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h" + +#include "base/basictypes.h" +#include "gpu/command_buffer/service/gl_utils.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder.h" + +namespace { + +#define SHADER(src) \ + "#ifdef GL_ES\n" \ + "precision mediump float;\n" \ + "#endif\n" #src + +const char* g_vertex_shader_source = { + SHADER( + uniform float u_clear_depth; + attribute vec4 a_position; + void main(void) { + gl_Position = vec4(a_position.x, a_position.y, u_clear_depth, 1.0); + } + ), +}; + +const char* g_fragment_shader_source = { + SHADER( + uniform vec4 u_clear_color; + void main(void) { + gl_FragColor = u_clear_color; + } + ), +}; + +void CompileShader(GLuint shader, const char* shader_source) { + glShaderSource(shader, 1, &shader_source, 0); + glCompileShader(shader); +#if DCHECK_IS_ON() + GLint compile_status = GL_FALSE; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); + if (GL_TRUE != compile_status) { + char buffer[1024]; + GLsizei length = 0; + glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer); + std::string log(buffer, length); + DLOG(ERROR) << "Error compiling shader: " << log; + DLOG(ERROR) << "Shader compilation failure."; + } +#endif +} + +} // namespace + +namespace gpu { + +ClearFramebufferResourceManager::ClearFramebufferResourceManager( + const gles2::GLES2Decoder* decoder) + : initialized_(false), program_(0u), buffer_id_(0u) { + Initialize(decoder); +} + +ClearFramebufferResourceManager::~ClearFramebufferResourceManager() { + Destroy(); + DCHECK(!buffer_id_); +} + +void ClearFramebufferResourceManager::Initialize( + const gles2::GLES2Decoder* decoder) { + static_assert( + kVertexPositionAttrib == 0u, + "kVertexPositionAttrib must be 0"); + DCHECK(!buffer_id_); + + glGenBuffersARB(1, &buffer_id_); + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); + const GLfloat kQuadVertices[] = {-1.0f, -1.0f, + 1.0f, -1.0f, + 1.0f, 1.0f, + -1.0f, 1.0f}; + glBufferData( + GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, GL_STATIC_DRAW); + decoder->RestoreBufferBindings(); + initialized_ = true; +} + +void ClearFramebufferResourceManager::Destroy() { + if (!initialized_) + return; + + glDeleteProgram(program_); + glDeleteBuffersARB(1, &buffer_id_); + buffer_id_ = 0; +} + +void ClearFramebufferResourceManager::ClearFramebuffer( + const gles2::GLES2Decoder* decoder, + const gfx::Size& framebuffer_size, + GLbitfield mask, + GLfloat clear_color_red, + GLfloat clear_color_green, + GLfloat clear_color_blue, + GLfloat clear_color_alpha, + GLfloat clear_depth_value, + GLint clear_stencil_value) { + if (!initialized_) { + DLOG(ERROR) << "Uninitialized manager."; + return; + } + + if (!program_) { + program_ = glCreateProgram(); + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + CompileShader(vertex_shader, g_vertex_shader_source); + glAttachShader(program_, vertex_shader); + GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + CompileShader(fragment_shader, g_fragment_shader_source); + glAttachShader(program_, fragment_shader); + glBindAttribLocation(program_, kVertexPositionAttrib, "a_position"); + glLinkProgram(program_); +#if DCHECK_IS_ON() + GLint linked = GL_FALSE; + glGetProgramiv(program_, GL_LINK_STATUS, &linked); + if (GL_TRUE != linked) + DLOG(ERROR) << "Program link failure."; +#endif + depth_handle_ = glGetUniformLocation(program_, "u_clear_depth"); + color_handle_ = glGetUniformLocation(program_, "u_clear_color"); + glDeleteShader(fragment_shader); + glDeleteShader(vertex_shader); + } + glUseProgram(program_); + +#if DCHECK_IS_ON() + glValidateProgram(program_); + GLint validation_status = GL_FALSE; + glGetProgramiv(program_, GL_VALIDATE_STATUS, &validation_status); + if (GL_TRUE != validation_status) + DLOG(ERROR) << "Invalid shader."; +#endif + + decoder->ClearAllAttributes(); + glEnableVertexAttribArray(kVertexPositionAttrib); + + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); + glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); + + glUniform1f(depth_handle_, clear_depth_value); + glUniform4f(color_handle_, clear_color_red, clear_color_green, + clear_color_blue, clear_color_alpha); + + if (!(mask & GL_COLOR_BUFFER_BIT)) { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + } + + if (mask & GL_DEPTH_BUFFER_BIT) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + } else { + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + } + + if (mask & GL_STENCIL_BUFFER_BIT) { + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, clear_stencil_value, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + } else { + glDisable(GL_STENCIL_TEST); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilMask(0); + } + + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glDisable(GL_POLYGON_OFFSET_FILL); + + glViewport(0, 0, framebuffer_size.width(), framebuffer_size.height()); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + decoder->RestoreAllAttributes(); + decoder->RestoreProgramBindings(); + decoder->RestoreBufferBindings(); + decoder->RestoreGlobalState(); +} + +} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h b/chromium/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h new file mode 100644 index 00000000000..6b533f51a56 --- /dev/null +++ b/chromium/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h @@ -0,0 +1,54 @@ +// Copyright 2014 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. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_CLEAR_FRAMEBUFFER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_CLEAR_FRAMEBUFFER_H_ + +#include "gpu/command_buffer/service/gl_utils.h" +#include "gpu/gpu_export.h" + +namespace gfx { +class Size; +} + +namespace gpu { +namespace gles2 { +class GLES2Decoder; +} + +class GPU_EXPORT ClearFramebufferResourceManager { + public: + ClearFramebufferResourceManager(const gles2::GLES2Decoder* decoder); + ~ClearFramebufferResourceManager(); + + + void ClearFramebuffer(const gles2::GLES2Decoder* decoder, + const gfx::Size& framebuffer_size, + GLbitfield mask, + GLfloat clear_color_red, + GLfloat clear_color_green, + GLfloat clear_color_blue, + GLfloat clear_color_alpha, + GLfloat clear_depth_value, + GLint clear_stencil_value); + + private: + void Initialize(const gles2::GLES2Decoder* decoder); + void Destroy(); + + // The attributes used during invocation of the extension. + static const GLuint kVertexPositionAttrib = 0; + + bool initialized_; + GLuint program_; + GLuint depth_handle_; + GLuint color_handle_; + GLuint buffer_id_; + + DISALLOW_COPY_AND_ASSIGN(ClearFramebufferResourceManager); +}; + +} // namespace gpu. + +#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_CLEAR_FRAMEBUFFER_H_ diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc index f98ca2e2424..d41ee9db3a3 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc @@ -21,8 +21,8 @@ "#define SamplerType sampler2D\n" \ "#define TextureLookup texture2D\n" SHADER(src) #define SHADER_RECTANGLE_ARB(src) \ - "#define SamplerType samplerRect\n" \ - "#define TextureLookup textureRect\n" SHADER(src) + "#define SamplerType sampler2DRect\n" \ + "#define TextureLookup texture2DRect\n" SHADER(src) #define SHADER_EXTERNAL_OES(src) \ "#extension GL_OES_EGL_image_external : require\n" \ "#define SamplerType samplerExternalOES\n" \ @@ -32,6 +32,11 @@ namespace { +const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f}; + enum VertexShaderId { VERTEX_SHADER_COPY_TEXTURE, VERTEX_SHADER_COPY_TEXTURE_FLIP_Y, @@ -188,7 +193,6 @@ void DeleteShader(GLuint shader) { bool BindFramebufferTexture2D(GLenum target, GLuint texture_id, - GLint level, GLuint framebuffer) { DCHECK(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB); glActiveTexture(GL_TEXTURE0); @@ -200,8 +204,8 @@ bool BindFramebufferTexture2D(GLenum target, glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer); - glFramebufferTexture2DEXT( - GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, texture_id, level); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, + texture_id, 0); #ifndef NDEBUG GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); @@ -217,28 +221,48 @@ void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder, GLenum source_target, GLuint source_id, GLuint dest_id, - GLint dest_level, GLenum dest_internal_format, GLsizei width, GLsizei height, GLuint framebuffer) { DCHECK(source_target == GL_TEXTURE_2D || source_target == GL_TEXTURE_RECTANGLE_ARB); - if (BindFramebufferTexture2D( - source_target, source_id, 0 /* level */, framebuffer)) { + if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) { glBindTexture(GL_TEXTURE_2D, dest_id); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glCopyTexImage2D(GL_TEXTURE_2D, - dest_level, - dest_internal_format, - 0 /* x */, - 0 /* y */, - width, - height, - 0 /* border */); + glCopyTexImage2D(GL_TEXTURE_2D, 0 /* level */, dest_internal_format, + 0 /* x */, 0 /* y */, width, height, 0 /* border */); + } + + decoder->RestoreTextureState(source_id); + decoder->RestoreTextureState(dest_id); + decoder->RestoreTextureUnitBindings(0); + decoder->RestoreActiveTexture(); + decoder->RestoreFramebufferBindings(); +} + +void DoCopyTexSubImage2D(const gpu::gles2::GLES2Decoder* decoder, + GLenum source_target, + GLuint source_id, + GLuint dest_id, + GLint xoffset, + GLint yoffset, + GLsizei source_width, + GLsizei source_height, + GLuint framebuffer) { + DCHECK(source_target == GL_TEXTURE_2D || + source_target == GL_TEXTURE_RECTANGLE_ARB); + if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) { + glBindTexture(GL_TEXTURE_2D, dest_id); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0 /* level */, xoffset, yoffset, + 0 /* x */, 0 /* y */, source_width, source_height); } decoder->RestoreTextureState(source_id); @@ -248,6 +272,17 @@ void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder, decoder->RestoreFramebufferBindings(); } +// Copy from SkMatrix44::preTranslate +void PreTranslate(GLfloat* matrix, GLfloat dx, GLfloat dy, GLfloat dz) { + if (!dx && !dy && !dz) + return; + + for (int i = 0; i < 4; ++i) { + matrix[(3 * 4) + i] = matrix[(0 * 4) + i] * dx + matrix[(1 * 4) + i] * dy + + matrix[(2 * 4) + i] * dz + matrix[(3 * 4) + i]; + } +} + } // namespace namespace gpu { @@ -260,15 +295,16 @@ CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() framebuffer_(0u) {} CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() { - DCHECK(!buffer_id_); - DCHECK(!framebuffer_); + // |buffer_id_| and |framebuffer_| can be not-null because when GPU context is + // lost, this class can be deleted without releasing resources like + // GLES2DecoderImpl. } void CopyTextureCHROMIUMResourceManager::Initialize( const gles2::GLES2Decoder* decoder) { - COMPILE_ASSERT( + static_assert( kVertexPositionAttrib == 0u, - Position_attribs_must_be_0); + "kVertexPositionAttrib must be 0"); DCHECK(!buffer_id_); DCHECK(!framebuffer_); DCHECK(programs_.empty()); @@ -317,7 +353,6 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTexture( GLuint source_id, GLenum source_internal_format, GLuint dest_id, - GLint dest_level, GLenum dest_internal_format, GLsizei width, GLsizei height, @@ -330,7 +365,8 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTexture( // format of internalformat. // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml bool source_format_contain_superset_of_dest_format = - source_internal_format == dest_internal_format || + (source_internal_format == dest_internal_format && + source_internal_format != GL_BGRA_EXT) || (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, // so restrict this to GL_TEXTURE_2D. @@ -340,7 +376,6 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTexture( source_target, source_id, dest_id, - dest_level, dest_internal_format, width, height, @@ -348,22 +383,51 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTexture( return; } - // Use default transform matrix if no transform passed in. - const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f}; - DoCopyTextureWithTransform(decoder, - source_target, - source_id, - dest_id, - dest_level, - width, - height, - flip_y, - premultiply_alpha, - unpremultiply_alpha, - default_matrix); + // Use kIdentityMatrix if no transform passed in. + DoCopyTextureWithTransform(decoder, source_target, source_id, dest_id, width, + height, flip_y, premultiply_alpha, + unpremultiply_alpha, kIdentityMatrix); +} + +void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( + const gles2::GLES2Decoder* decoder, + GLenum source_target, + GLuint source_id, + GLenum source_internal_format, + GLuint dest_id, + GLenum dest_internal_format, + GLint xoffset, + GLint yoffset, + GLsizei dest_width, + GLsizei dest_height, + GLsizei source_width, + GLsizei source_height, + bool flip_y, + bool premultiply_alpha, + bool unpremultiply_alpha) { + bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; + // GL_INVALID_OPERATION is generated if the currently bound framebuffer's + // format does not contain a superset of the components required by the base + // format of internalformat. + // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml + bool source_format_contain_superset_of_dest_format = + (source_internal_format == dest_internal_format && + source_internal_format != GL_BGRA_EXT) || + (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); + // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, + // so restrict this to GL_TEXTURE_2D. + if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && + source_format_contain_superset_of_dest_format) { + DoCopyTexSubImage2D(decoder, source_target, source_id, dest_id, xoffset, + yoffset, source_width, source_height, framebuffer_); + return; + } + + // Use kIdentityMatrix if no transform passed in. + DoCopySubTextureWithTransform( + decoder, source_target, source_id, dest_id, xoffset, yoffset, dest_width, + dest_height, source_width, source_height, flip_y, premultiply_alpha, + unpremultiply_alpha, kIdentityMatrix); } void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( @@ -371,16 +435,61 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( GLenum source_target, GLuint source_id, GLuint dest_id, - GLint dest_level, GLsizei width, GLsizei height, bool flip_y, bool premultiply_alpha, bool unpremultiply_alpha, const GLfloat transform_matrix[16]) { + GLsizei dest_width = width; + GLsizei dest_height = height; + DoCopyTextureInternal(decoder, source_target, source_id, dest_id, 0, 0, + dest_width, dest_height, width, height, flip_y, + premultiply_alpha, unpremultiply_alpha, + transform_matrix); +} + +void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform( + const gles2::GLES2Decoder* decoder, + GLenum source_target, + GLuint source_id, + GLuint dest_id, + GLint xoffset, + GLint yoffset, + GLsizei dest_width, + GLsizei dest_height, + GLsizei source_width, + GLsizei source_height, + bool flip_y, + bool premultiply_alpha, + bool unpremultiply_alpha, + const GLfloat transform_matrix[16]) { + DoCopyTextureInternal(decoder, source_target, source_id, dest_id, xoffset, + yoffset, dest_width, dest_height, source_width, + source_height, flip_y, premultiply_alpha, + unpremultiply_alpha, transform_matrix); +} + +void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( + const gles2::GLES2Decoder* decoder, + GLenum source_target, + GLuint source_id, + GLuint dest_id, + GLint xoffset, + GLint yoffset, + GLsizei dest_width, + GLsizei dest_height, + GLsizei source_width, + GLsizei source_height, + bool flip_y, + bool premultiply_alpha, + bool unpremultiply_alpha, + const GLfloat transform_matrix[16]) { DCHECK(source_target == GL_TEXTURE_2D || source_target == GL_TEXTURE_RECTANGLE_ARB || source_target == GL_TEXTURE_EXTERNAL_OES); + DCHECK(xoffset >= 0 && xoffset + source_width <= dest_width); + DCHECK(yoffset >= 0 && yoffset + source_height <= dest_height); if (!initialized_) { DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; return; @@ -424,24 +533,38 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( } glUseProgram(info->program); -#ifndef NDEBUG - glValidateProgram(info->program); - GLint validation_status; - glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); - if (GL_TRUE != validation_status) { - DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; - return; + if (!xoffset && !yoffset) { + glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix); + } else { + // transform offsets from ([0, dest_width], [0, dest_height]) coord. + // to ([-1, 1], [-1, 1]) coord. + GLfloat xoffset_on_vertex = ((2.f * xoffset) / dest_width); + GLfloat yoffset_on_vertex = ((2.f * yoffset) / dest_height); + + // Pass view_matrix * offset_matrix to the program. + GLfloat view_transform[16]; + memcpy(view_transform, transform_matrix, 16 * sizeof(GLfloat)); + PreTranslate(view_transform, xoffset_on_vertex, yoffset_on_vertex, 0); + glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, view_transform); } -#endif - - glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix); if (source_target == GL_TEXTURE_RECTANGLE_ARB) - glUniform2f(info->half_size_handle, width / 2.0f, height / 2.0f); + glUniform2f(info->half_size_handle, source_width / 2.0f, + source_height / 2.0f); else glUniform2f(info->half_size_handle, 0.5f, 0.5f); - if (BindFramebufferTexture2D( - GL_TEXTURE_2D, dest_id, dest_level, framebuffer_)) { + if (BindFramebufferTexture2D(GL_TEXTURE_2D, dest_id, framebuffer_)) { +#ifndef NDEBUG + // glValidateProgram of MACOSX validates FBO unlike other platforms, so + // glValidateProgram must be called after FBO binding. crbug.com/463439 + glValidateProgram(info->program); + GLint validation_status; + glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); + if (GL_TRUE != validation_status) { + DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; + return; + } +#endif decoder->ClearAllAttributes(); glEnableVertexAttribArray(kVertexPositionAttrib); @@ -464,7 +587,7 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( glDepthMask(GL_FALSE); glDisable(GL_BLEND); - glViewport(0, 0, width, height); + glViewport(0, 0, dest_width, dest_height); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h b/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h index 083fc4c8578..5c62141149d 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h @@ -35,7 +35,6 @@ class GPU_EXPORT CopyTextureCHROMIUMResourceManager { GLuint source_id, GLenum source_internal_format, GLuint dest_id, - GLint dest_level, GLenum dest_internal_format, GLsizei width, GLsizei height, @@ -43,13 +42,28 @@ class GPU_EXPORT CopyTextureCHROMIUMResourceManager { bool premultiply_alpha, bool unpremultiply_alpha); + void DoCopySubTexture(const gles2::GLES2Decoder* decoder, + GLenum source_target, + GLuint source_id, + GLenum source_internal_format, + GLuint dest_id, + GLenum dest_internal_format, + GLint xoffset, + GLint yoffset, + GLsizei dest_width, + GLsizei dest_height, + GLsizei source_width, + GLsizei source_height, + bool flip_y, + bool premultiply_alpha, + bool unpremultiply_alpha); + // This will apply a transform on the source texture before copying to // destination texture. void DoCopyTextureWithTransform(const gles2::GLES2Decoder* decoder, GLenum source_target, GLuint source_id, GLuint dest_id, - GLint dest_level, GLsizei width, GLsizei height, bool flip_y, @@ -57,6 +71,21 @@ class GPU_EXPORT CopyTextureCHROMIUMResourceManager { bool unpremultiply_alpha, const GLfloat transform_matrix[16]); + void DoCopySubTextureWithTransform(const gles2::GLES2Decoder* decoder, + GLenum source_target, + GLuint source_id, + GLuint dest_id, + GLint xoffset, + GLint yoffset, + GLsizei dest_width, + GLsizei dest_height, + GLsizei source_width, + GLsizei source_height, + bool flip_y, + bool premultiply_alpha, + bool unpremultiply_alpha, + const GLfloat transform_matrix[16]); + // The attributes used during invocation of the extension. static const GLuint kVertexPositionAttrib = 0; @@ -74,6 +103,21 @@ class GPU_EXPORT CopyTextureCHROMIUMResourceManager { GLuint sampler_handle; }; + void DoCopyTextureInternal(const gles2::GLES2Decoder* decoder, + GLenum source_target, + GLuint source_id, + GLuint dest_id, + GLint xoffset, + GLint yoffset, + GLsizei dest_width, + GLsizei dest_height, + GLsizei source_width, + GLsizei source_height, + bool flip_y, + bool premultiply_alpha, + bool unpremultiply_alpha, + const GLfloat transform_matrix[16]); + bool initialized_; typedef std::vector<GLuint> ShaderVector; ShaderVector vertex_shaders_; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc index 8577d820d15..89a65acee04 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -7,8 +7,10 @@ #include <stdio.h> #include <algorithm> +#include <cmath> #include <list> #include <map> +#include <queue> #include <stack> #include <string> #include <vector> @@ -17,13 +19,12 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/command_line.h" -#include "base/debug/trace_event.h" -#include "base/debug/trace_event_synthetic_delay.h" -#include "base/float_util.h" #include "base/memory/scoped_ptr.h" #include "base/numerics/safe_math.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" +#include "base/trace_event/trace_event.h" +#include "base/trace_event/trace_event_synthetic_delay.h" #include "build/build_config.h" #define GLES2_GPU_SERVICE 1 #include "gpu/command_buffer/common/debug_marker_manager.h" @@ -41,6 +42,7 @@ #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/framebuffer_manager.h" #include "gpu/command_buffer/service/gl_utils.h" +#include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h" #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" #include "gpu/command_buffer/service/gles2_cmd_validation.h" #include "gpu/command_buffer/service/gpu_state_tracer.h" @@ -80,10 +82,15 @@ namespace gles2 { namespace { -static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives"; -static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth"; -static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers"; -static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod"; +const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives"; +const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth"; +const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers"; +const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod"; + +const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f}; static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin, GLint rangeMax, @@ -93,7 +100,7 @@ static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin, static void GetShaderPrecisionFormatImpl(GLenum shader_type, GLenum precision_type, - GLint *range, GLint *precision) { + GLint* range, GLint* precision) { switch (precision_type) { case GL_LOW_INT: case GL_MEDIUM_INT: @@ -166,6 +173,14 @@ static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) { } } +struct Vec4f { + explicit Vec4f(const Vec4& data) { + data.GetValues(v); + } + + GLfloat v[4]; +}; + } // namespace class GLES2DecoderImpl; @@ -197,12 +212,12 @@ class GLES2DecoderImpl; // a few others) are 32bits. If they are not 32bits the code will have to change // to call those GL functions with service side memory and then copy the results // to shared memory, converting the sizes. -COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT - GLint_not_same_size_as_uint32); -COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT - GLint_not_same_size_as_uint32); -COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT - GLfloat_not_same_size_as_float); +static_assert(sizeof(GLint) == sizeof(uint32), // NOLINT + "GLint should be the same size as uint32"); +static_assert(sizeof(GLsizei) == sizeof(uint32), // NOLINT + "GLsizei should be the same size as uint32"); +static_assert(sizeof(GLfloat) == sizeof(float), // NOLINT + "GLfloat should be the same size as float"); // TODO(kbr): the use of this anonymous namespace core dumps the // linker on Mac OS X 10.6 when the symbol ordering file is used @@ -497,7 +512,7 @@ class BackFramebuffer { }; struct FenceCallback { - explicit FenceCallback() + FenceCallback() : fence(gfx::GLFence::Create()) { DCHECK(fence); } @@ -541,7 +556,8 @@ bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id, GLES2Decoder::GLES2Decoder() : initialized_(false), debug_(false), - log_commands_(false) { + log_commands_(false), + unsafe_es3_apis_enabled_(false) { } GLES2Decoder::~GLES2Decoder() { @@ -583,7 +599,7 @@ class GLES2DecoderImpl : public GLES2Decoder, bool Initialize(const scoped_refptr<gfx::GLSurface>& surface, const scoped_refptr<gfx::GLContext>& context, bool offscreen, - const gfx::Size& size, + const gfx::Size& offscreen_size, const DisallowedFeatures& disallowed_features, const std::vector<int32>& attribs) override; void Destroy(bool have_context) override; @@ -628,7 +644,13 @@ class GLES2DecoderImpl : public GLES2Decoder, return vertex_array_manager_.get(); } ImageManager* GetImageManager() override { return image_manager_.get(); } + + ValuebufferManager* GetValuebufferManager() override { + return valuebuffer_manager(); + } + bool ProcessPendingQueries(bool did_finish) override; + bool HasMoreIdleWork() override; void PerformIdleWork() override; @@ -653,6 +675,7 @@ class GLES2DecoderImpl : public GLES2Decoder, void SetAsyncPixelTransferManagerForTest( AsyncPixelTransferManager* manager) override; void SetIgnoreCachedStateForTest(bool ignore) override; + void SetAllowExit(bool allow_exit) override; void ProcessFinishedAsyncTransfers(); bool GetServiceTextureId(uint32 client_texture_id, @@ -746,6 +769,9 @@ class GLES2DecoderImpl : public GLES2Decoder, void OnFboChanged() const; void OnUseFramebuffer() const; + error::ContextLostReason GetContextLostReasonFromResetStatus( + GLenum reset_status) const; + // TODO(gman): Cache these pointers? BufferManager* buffer_manager() { return group_->buffer_manager(); @@ -846,6 +872,18 @@ class GLES2DecoderImpl : public GLES2Decoder, GLsizei image_size, const void* data); + // Wrapper for CompressedTexImage3D commands. + error::Error DoCompressedTexImage3D( + GLenum target, + GLint level, + GLenum internal_format, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei image_size, + const void* data); + // Wrapper for CompressedTexSubImage2D. void DoCompressedTexSubImage2D( GLenum target, @@ -858,6 +896,20 @@ class GLES2DecoderImpl : public GLES2Decoder, GLsizei imageSize, const void * data); + // Wrapper for CompressedTexSubImage3D. + void DoCompressedTexSubImage3D( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei image_size, + const void* data); + // Wrapper for CopyTexImage2D. void DoCopyTexImage2D( GLenum target, @@ -872,6 +924,9 @@ class GLES2DecoderImpl : public GLES2Decoder, // Wrapper for SwapBuffers. void DoSwapBuffers(); + // Wrapper for SwapInterval. + void DoSwapInterval(int interval); + // Wrapper for CopyTexSubImage2D. void DoCopyTexSubImage2D( GLenum target, @@ -925,13 +980,17 @@ class GLES2DecoderImpl : public GLES2Decoder, GLuint io_surface_id, GLuint plane); - void DoCopyTextureCHROMIUM( - GLenum target, - GLuint source_id, - GLuint target_id, - GLint level, - GLenum internal_format, - GLenum dest_type); + void DoCopyTextureCHROMIUM(GLenum target, + GLuint source_id, + GLuint dest_id, + GLenum internal_format, + GLenum dest_type); + + void DoCopySubTextureCHROMIUM(GLenum target, + GLuint source_id, + GLuint dest_id, + GLint xoffset, + GLint yoffset); // Wrapper for TexStorage2DEXT. void DoTexStorage2DEXT( @@ -947,6 +1006,7 @@ class GLES2DecoderImpl : public GLES2Decoder, void ProduceTextureRef(std::string func_name, TextureRef* texture_ref, GLenum target, const GLbyte* data); + void EnsureTextureForClientId(GLenum target, GLuint client_id); void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key); void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key, GLuint client_id); @@ -1152,16 +1212,25 @@ class GLES2DecoderImpl : public GLES2Decoder, GLuint client_id, GLint location, const char* name); error::Error GetAttribLocationHelper( - GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, - const std::string& name_str); + GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, + const std::string& name_str); error::Error GetUniformLocationHelper( - GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, - const std::string& name_str); + GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, + const std::string& name_str); + + error::Error GetFragDataLocationHelper( + GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, + const std::string& name_str); + + // Wrapper for glShaderSource. + void DoShaderSource( + GLuint client_id, GLsizei count, const char** data, const GLint* length); - // Helper for glShaderSource. - error::Error ShaderSourceHelper( - GLuint client_id, const char* data, uint32 data_size); + // Wrapper for glTransformFeedbackVaryings. + void DoTransformFeedbackVaryings( + GLuint client_program_id, GLsizei count, const char* const* varyings, + GLenum buffer_mode); // Clear any textures used by the current program. bool ClearUnclearedTextures(); @@ -1171,8 +1240,7 @@ class GLES2DecoderImpl : public GLES2Decoder, void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer); // overridden from GLES2Decoder - bool ClearLevel(unsigned service_id, - unsigned bind_target, + bool ClearLevel(Texture* texture, unsigned target, int level, unsigned internal_format, @@ -1267,12 +1335,6 @@ class GLES2DecoderImpl : public GLES2Decoder, void GetVertexAttribHelper( const VertexAttrib* attrib, GLenum pname, GLint* param); - // Wrapper for glCreateProgram - bool CreateProgramHelper(GLuint client_id); - - // Wrapper for glCreateShader - bool CreateShaderHelper(GLenum type, GLuint client_id); - // Wrapper for glActiveTexture void DoActiveTexture(GLenum texture_unit); @@ -1365,6 +1427,11 @@ class GLES2DecoderImpl : public GLES2Decoder, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); + // Wrapper for glFramebufferTextureLayer. + void DoFramebufferTextureLayer( + GLenum target, GLenum attachment, GLuint texture, GLint level, + GLint layer); + // Wrapper for glGenerateMipmap void DoGenerateMipmap(GLenum target); @@ -1383,6 +1450,9 @@ class GLES2DecoderImpl : public GLES2Decoder, void DoGetFramebufferAttachmentParameteriv( GLenum target, GLenum attachment, GLenum pname, GLint* params); + // Wrapper for glGetInteger64v. + void DoGetInteger64v(GLenum pname, GLint64* params); + // Wrapper for glGetIntegerv. void DoGetIntegerv(GLenum pname, GLint* params); @@ -1411,8 +1481,12 @@ class GLES2DecoderImpl : public GLES2Decoder, void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname); // Wrappers for glGetVertexAttrib. - void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params); - void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params); + template <typename T> + void DoGetVertexAttribImpl(GLuint index, GLenum pname, T* params); + void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params); + void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint* params); + void DoGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params); + void DoGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params); // Wrappers for glIsXXX functions. bool DoIsEnabled(GLenum cap); @@ -1457,6 +1531,11 @@ class GLES2DecoderImpl : public GLES2Decoder, // Wrapper for glReleaseShaderCompiler. void DoReleaseShaderCompiler() { } + // Wrappers for glSamplerParameter*v functions. + void DoSamplerParameterfv( + GLuint sampler, GLenum pname, const GLfloat* params); + void DoSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* params); + // Wrappers for glTexParameter functions. void DoTexParameterf(GLenum target, GLenum pname, GLfloat param); void DoTexParameteri(GLenum target, GLenum pname, GLint param); @@ -1488,8 +1567,9 @@ class GLES2DecoderImpl : public GLES2Decoder, GLint fake_location, GLsizei count, GLboolean transpose, const GLfloat* value); + template <typename T> bool SetVertexAttribValue( - const char* function_name, GLuint index, const GLfloat* value); + const char* function_name, GLuint index, const T* value); // Wrappers for glVertexAttrib?? void DoVertexAttrib1f(GLuint index, GLfloat v0); @@ -1497,10 +1577,15 @@ class GLES2DecoderImpl : public GLES2Decoder, void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2); void DoVertexAttrib4f( GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); - void DoVertexAttrib1fv(GLuint index, const GLfloat *v); - void DoVertexAttrib2fv(GLuint index, const GLfloat *v); - void DoVertexAttrib3fv(GLuint index, const GLfloat *v); - void DoVertexAttrib4fv(GLuint index, const GLfloat *v); + void DoVertexAttrib1fv(GLuint index, const GLfloat* v); + void DoVertexAttrib2fv(GLuint index, const GLfloat* v); + void DoVertexAttrib3fv(GLuint index, const GLfloat* v); + void DoVertexAttrib4fv(GLuint index, const GLfloat* v); + void DoVertexAttribI4i(GLuint index, GLint v0, GLint v1, GLint v2, GLint v3); + void DoVertexAttribI4iv(GLuint index, const GLint* v); + void DoVertexAttribI4ui( + GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void DoVertexAttribI4uiv(GLuint index, const GLuint* v); // Wrapper for glViewport void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height); @@ -1609,32 +1694,43 @@ class GLES2DecoderImpl : public GLES2Decoder, // Validates the program and location for a glGetUniform call and returns // a SizeResult setup to receive the result. Returns true if glGetUniform // should be called. - bool GetUniformSetup( - GLuint program, GLint fake_location, - uint32 shm_id, uint32 shm_offset, - error::Error* error, GLint* real_location, GLuint* service_id, - void** result, GLenum* result_type); - - void MaybeExitOnContextLost(); - bool WasContextLost() override; - bool WasContextLostByRobustnessExtension() override; - void LoseContext(uint32 reset_status) override; + template <class T> + bool GetUniformSetup(GLuint program, + GLint fake_location, + uint32 shm_id, + uint32 shm_offset, + error::Error* error, + GLint* real_location, + GLuint* service_id, + SizedResult<T>** result, + GLenum* result_type, + GLsizei* result_size); + + bool WasContextLost() const override; + bool WasContextLostByRobustnessExtension() const override; + void MarkContextLost(error::ContextLostReason reason) override; + bool CheckResetStatus(); #if defined(OS_MACOSX) void ReleaseIOSurfaceForTexture(GLuint texture_id); #endif bool ValidateCompressedTexDimensions( - const char* function_name, - GLint level, GLsizei width, GLsizei height, GLenum format); + const char* function_name, GLenum target, GLint level, + GLsizei width, GLsizei height, GLsizei depth, GLenum format); bool ValidateCompressedTexFuncData( - const char* function_name, - GLsizei width, GLsizei height, GLenum format, size_t size); + const char* function_name, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei size); bool ValidateCompressedTexSubDimensions( const char* function_name, - GLenum target, GLint level, GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, GLenum format, + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, Texture* texture); + bool ValidateCopyTextureCHROMIUM(const char* function_name, + GLenum target, + TextureRef* source_texture_ref, + TextureRef* dest_texture_ref, + GLenum dest_internal_format); void RenderWarning(const char* filename, int line, const std::string& msg); void PerformanceWarning( @@ -1660,6 +1756,11 @@ class GLES2DecoderImpl : public GLES2Decoder, surface_->DeferDraws(); } + bool IsRobustnessSupported() { + return has_robustness_extension_ && + context_->WasAllocatedUsingRobustnessExtension(); + } + error::Error WillAccessBoundFramebufferForDraw() { if (ShouldDeferDraws()) return error::kDeferCommandUntilLater; @@ -1796,8 +1897,8 @@ class GLES2DecoderImpl : public GLES2Decoder, error::Error current_decoder_error_; bool use_shader_translator_; - scoped_refptr<ShaderTranslator> vertex_translator_; - scoped_refptr<ShaderTranslator> fragment_translator_; + scoped_refptr<ShaderTranslatorInterface> vertex_translator_; + scoped_refptr<ShaderTranslatorInterface> fragment_translator_; DisallowedFeatures disallowed_features_; @@ -1811,7 +1912,8 @@ class GLES2DecoderImpl : public GLES2Decoder, int commands_to_process_; bool has_robustness_extension_; - GLenum reset_status_; + error::ContextLostReason context_lost_reason_; + bool context_was_lost_; bool reset_by_robustness_extension_; bool supports_post_sub_buffer_; @@ -1840,6 +1942,7 @@ class GLES2DecoderImpl : public GLES2Decoder, #endif scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_; + scoped_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_; // Cached values of the currently assigned viewport dimensions. GLsizei viewport_max_width_; @@ -1855,6 +1958,7 @@ class GLES2DecoderImpl : public GLES2Decoder, scoped_ptr<GPUTracer> gpu_tracer_; scoped_ptr<GPUStateTracer> gpu_state_tracer_; const unsigned char* cb_command_trace_category_; + const unsigned char* gpu_decoder_category_; int gpu_trace_level_; bool gpu_trace_commands_; bool gpu_debug_commands_; @@ -1866,6 +1970,8 @@ class GLES2DecoderImpl : public GLES2Decoder, GLuint validation_fbo_multisample_; GLuint validation_fbo_; + bool allow_exit_; + typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)( uint32 immediate_data_size, const void* data); @@ -2106,7 +2212,7 @@ bool BackTexture::AllocateStorage( ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D); uint32 image_size = 0; GLES2Util::ComputeImageDataSizes( - size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size, + size.width(), size.height(), 1, format, GL_UNSIGNED_BYTE, 8, &image_size, NULL, NULL); if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) { @@ -2351,7 +2457,8 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) feature_info_(group_->feature_info()), frame_number_(0), has_robustness_extension_(false), - reset_status_(GL_NO_ERROR), + context_lost_reason_(error::kUnknown), + context_was_lost_(false), reset_by_robustness_extension_(false), supports_post_sub_buffer_(false), force_webgl_glsl_validation_(false), @@ -2361,7 +2468,7 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) shader_texture_lod_explicitly_enabled_(false), compile_shader_always_succeeds_(false), lose_context_when_out_of_memory_(false), - service_logging_(CommandLine::ForCurrentProcess()->HasSwitch( + service_logging_(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableGPUServiceLoggingGPU)), viewport_max_width_(0), viewport_max_height_(0), @@ -2370,26 +2477,24 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) .texsubimage2d_faster_than_teximage2d), cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( TRACE_DISABLED_BY_DEFAULT("cb_command"))), + gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( + TRACE_DISABLED_BY_DEFAULT("gpu_decoder"))), gpu_trace_level_(2), gpu_trace_commands_(false), gpu_debug_commands_(false), validation_texture_(0), validation_fbo_multisample_(0), - validation_fbo_(0) { + validation_fbo_(0), + allow_exit_(false) { DCHECK(group); - attrib_0_value_.v[0] = 0.0f; - attrib_0_value_.v[1] = 0.0f; - attrib_0_value_.v[2] = 0.0f; - attrib_0_value_.v[3] = 1.0f; - // The shader translator is used for WebGL even when running on EGL // because additional restrictions are needed (like only enabling // GL_OES_standard_derivatives on demand). It is used for the unit // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes // the empty string to CompileShader and this is not a valid shader. if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL || - CommandLine::ForCurrentProcess()->HasSwitch( + base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableGLSLTranslator)) { use_shader_translator_ = false; } @@ -2402,41 +2507,44 @@ bool GLES2DecoderImpl::Initialize( const scoped_refptr<gfx::GLSurface>& surface, const scoped_refptr<gfx::GLContext>& context, bool offscreen, - const gfx::Size& size, + const gfx::Size& offscreen_size, const DisallowedFeatures& disallowed_features, const std::vector<int32>& attribs) { TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize"); DCHECK(context->IsCurrent(surface.get())); DCHECK(!context_.get()); + DCHECK(!offscreen || !offscreen_size.IsEmpty()); + + ContextCreationAttribHelper attrib_parser; + if (!attrib_parser.Parse(attribs)) + return false; surfaceless_ = surface->IsSurfaceless() && !offscreen; set_initialized(); - gpu_tracer_.reset(new GPUTracer(this)); gpu_state_tracer_ = GPUStateTracer::Create(&state_); - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableGPUDebugging)) { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableGPUDebugging)) { set_debug(true); } - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableGPUCommandLogging)) { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableGPUCommandLogging)) { set_log_commands(true); } - compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch( - switches::kCompileShaderAlwaysSucceeds); - + compile_shader_always_succeeds_ = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kCompileShaderAlwaysSucceeds); // Take ownership of the context and surface. The surface can be replaced with // SetSurface. context_ = context; surface_ = surface; - ContextCreationAttribHelper attrib_parser; - if (!attrib_parser.Parse(attribs)) - return false; + // Create GPU Tracer for timing values. + gpu_tracer_.reset(new GPUTracer(this)); // Save the loseContextWhenOutOfMemory context creation attribute. lose_context_when_out_of_memory_ = @@ -2460,6 +2568,12 @@ bool GLES2DecoderImpl::Initialize( } CHECK_GL_ERROR(); + if (attrib_parser.es3_context_required && + feature_info_->IsES3Capable()) { + feature_info_->EnableES3Validators(); + set_unsafe_es3_apis_enabled(true); + } + disallowed_features_ = disallowed_features; state_.attrib_values.resize(group_->max_vertex_attribs()); @@ -2526,6 +2640,9 @@ bool GLES2DecoderImpl::Initialize( glActiveTexture(GL_TEXTURE0); CHECK_GL_ERROR(); + // cache ALPHA_BITS result for re-use with clear behaviour + GLint alpha_bits = 0; + if (offscreen) { if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 && features().chromium_framebuffer_multisample) { @@ -2552,8 +2669,10 @@ bool GLES2DecoderImpl::Initialize( GL_RGBA8 : GL_RGB8; } else { offscreen_target_samples_ = 1; - offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ? - GL_RGBA : GL_RGB; + offscreen_target_color_format_ = + attrib_parser.alpha_size > 0 || workarounds().disable_gl_rgb_format + ? GL_RGBA + : GL_RGB; } // ANGLE only supports packed depth/stencil formats, so use it if it is @@ -2575,8 +2694,10 @@ bool GLES2DecoderImpl::Initialize( GL_STENCIL_INDEX8 : 0; } } else { - offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ? - GL_RGBA : GL_RGB; + offscreen_target_color_format_ = + attrib_parser.alpha_size > 0 || workarounds().disable_gl_rgb_format + ? GL_RGBA + : GL_RGB; // If depth is requested at all, use the packed depth stencil format if // it's available, as some desktop GL drivers don't support any non-packed @@ -2598,8 +2719,10 @@ bool GLES2DecoderImpl::Initialize( } } - offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ? - GL_RGBA : GL_RGB; + offscreen_saved_color_format_ = + attrib_parser.alpha_size > 0 || workarounds().disable_gl_rgb_format + ? GL_RGBA + : GL_RGB; // Create the target frame buffer. This is the one that the client renders // directly to. @@ -2636,12 +2759,15 @@ bool GLES2DecoderImpl::Initialize( // Allocate the render buffers at their initial size and check the status // of the frame buffers is okay. - if (!ResizeOffscreenFrameBuffer(size)) { + if (!ResizeOffscreenFrameBuffer(offscreen_size)) { LOG(ERROR) << "Could not allocate offscreen buffer storage."; Destroy(true); return false; } + state_.viewport_width = offscreen_size.width(); + state_.viewport_height = offscreen_size.height(); + // Allocate the offscreen saved color texture. DCHECK(offscreen_saved_color_format_); offscreen_saved_color_texture_->AllocateStorage( @@ -2669,18 +2795,42 @@ bool GLES2DecoderImpl::Initialize( // can't do anything about that. if (!surfaceless_) { - GLint v = 0; - glGetIntegerv(GL_ALPHA_BITS, &v); + GLint depth_bits = 0; + GLint stencil_bits = 0; + + bool default_fb = (GetBackbufferServiceId() == 0); + + if (feature_info_->gl_version_info().is_desktop_core_profile) { + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, + default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0, + GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits); + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, + default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits); + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, + default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits); + } else { + glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); + glGetIntegerv(GL_DEPTH_BITS, &depth_bits); + glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); + } + // This checks if the user requested RGBA and we have RGBA then RGBA. If // the user requested RGB then RGB. If the user did not specify a // preference than use whatever we were given. Same for DEPTH and STENCIL. back_buffer_color_format_ = - (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB; - glGetIntegerv(GL_DEPTH_BITS, &v); - back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0; - glGetIntegerv(GL_STENCIL_BITS, &v); - back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0; + (attrib_parser.alpha_size != 0 && alpha_bits > 0) ? GL_RGBA : GL_RGB; + back_buffer_has_depth_ = attrib_parser.depth_size != 0 && depth_bits > 0; + back_buffer_has_stencil_ = + attrib_parser.stencil_size != 0 && stencil_bits > 0; } + + state_.viewport_width = surface->GetSize().width(); + state_.viewport_height = surface->GetSize().height(); } // OpenGL ES 2.0 implicitly enables the desktop GL capability @@ -2689,7 +2839,7 @@ bool GLES2DecoderImpl::Initialize( // mailing list archives. It also implicitly enables the desktop GL // capability GL_POINT_SPRITE to provide access to the gl_PointCoord // variable in fragment shaders. - if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { + if (!feature_info_->gl_version_info().BehavesLikeGLES()) { glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_POINT_SPRITE); } @@ -2703,9 +2853,6 @@ bool GLES2DecoderImpl::Initialize( return false; } - state_.viewport_width = size.width(); - state_.viewport_height = size.height(); - GLint viewport_params[4] = { 0 }; glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params); viewport_max_width_ = viewport_params[0]; @@ -2735,8 +2882,20 @@ bool GLES2DecoderImpl::Initialize( call_gl_clear = surface_->GetHandle(); #endif if (call_gl_clear) { + // On configs where we report no alpha, if the underlying surface has + // alpha, clear the surface alpha to 1.0 to be correct on ReadPixels/etc. + bool clear_alpha = back_buffer_color_format_ == GL_RGB && alpha_bits > 0; + if (clear_alpha) { + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + } + // Clear the backbuffer. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + // Restore alpha clear value if we changed it. + if (clear_alpha) { + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } } supports_post_sub_buffer_ = surface->SupportsPostSubBuffer(); @@ -2764,6 +2923,14 @@ bool GLES2DecoderImpl::Initialize( AsyncPixelTransferManager::Create(context.get())); async_pixel_transfer_manager_->Initialize(texture_manager()); + if (workarounds().gl_clear_broken) { + DCHECK(!clear_framebuffer_blit_.get()); + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit"); + clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this)); + if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR) + return false; + } + framebuffer_manager()->AddObserver(this); return true; @@ -2771,13 +2938,102 @@ bool GLES2DecoderImpl::Initialize( Capabilities GLES2DecoderImpl::GetCapabilities() { DCHECK(initialized()); - Capabilities caps; + caps.VisitPrecisions([](GLenum shader, GLenum type, + Capabilities::ShaderPrecision* shader_precision) { + GLint range[2] = {0, 0}; + GLint precision = 0; + GetShaderPrecisionFormatImpl(shader, type, range, &precision); + shader_precision->min_range = range[0]; + shader_precision->max_range = range[1]; + shader_precision->precision = precision; + }); + DoGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, + &caps.max_combined_texture_image_units); + DoGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps.max_cube_map_texture_size); + DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, + &caps.max_fragment_uniform_vectors); + DoGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps.max_renderbuffer_size); + DoGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps.max_texture_image_units); + DoGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.max_texture_size); + DoGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.max_varying_vectors); + DoGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.max_vertex_attribs); + DoGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, + &caps.max_vertex_texture_image_units); + DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, + &caps.max_vertex_uniform_vectors); + DoGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, + &caps.num_compressed_texture_formats); + DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats); + DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM, + &caps.bind_generates_resource_chromium); + if (unsafe_es3_apis_enabled()) { + // TODO(zmo): Note that some parameter values could be more than 32-bit, + // but for now we clamp them to 32-bit max. + DoGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &caps.max_3d_texture_size); + DoGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &caps.max_array_texture_layers); + DoGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &caps.max_color_attachments); + DoGetIntegerv(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, + &caps.max_combined_fragment_uniform_components); + DoGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, + &caps.max_combined_uniform_blocks); + DoGetIntegerv(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, + &caps.max_combined_vertex_uniform_components); + DoGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps.max_draw_buffers); + DoGetIntegerv(GL_MAX_ELEMENT_INDEX, &caps.max_element_index); + DoGetIntegerv(GL_MAX_ELEMENTS_INDICES, &caps.max_elements_indices); + DoGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &caps.max_elements_vertices); + DoGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, + &caps.max_fragment_input_components); + DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, + &caps.max_fragment_uniform_blocks); + DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, + &caps.max_fragment_uniform_components); + DoGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, + &caps.max_program_texel_offset); + DoGetIntegerv(GL_MAX_SERVER_WAIT_TIMEOUT, &caps.max_server_wait_timeout); + DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, + &caps.max_transform_feedback_interleaved_components); + DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, + &caps.max_transform_feedback_separate_attribs); + DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, + &caps.max_transform_feedback_separate_components); + DoGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &caps.max_uniform_block_size); + DoGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, + &caps.max_uniform_buffer_bindings); + DoGetIntegerv(GL_MAX_VARYING_COMPONENTS, &caps.max_varying_components); + DoGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, + &caps.max_vertex_output_components); + DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, + &caps.max_vertex_uniform_blocks); + DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, + &caps.max_vertex_uniform_components); + DoGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps.min_program_texel_offset); + DoGetIntegerv(GL_NUM_EXTENSIONS, &caps.num_extensions); + DoGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, + &caps.num_program_binary_formats); + DoGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, + &caps.uniform_buffer_offset_alignment); + // TODO(zmo): once we switch to MANGLE, we should query version numbers. + caps.major_version = 3; + caps.minor_version = 0; + } + if (feature_info_->feature_flags().multisampled_render_to_texture || + feature_info_->feature_flags().chromium_framebuffer_multisample || + unsafe_es3_apis_enabled()) { + DoGetIntegerv(GL_MAX_SAMPLES, &caps.max_samples); + } caps.egl_image_external = feature_info_->feature_flags().oes_egl_image_external; + caps.texture_format_atc = + feature_info_->feature_flags().ext_texture_format_atc; caps.texture_format_bgra8888 = feature_info_->feature_flags().ext_texture_format_bgra8888; + caps.texture_format_dxt1 = + feature_info_->feature_flags().ext_texture_format_dxt1; + caps.texture_format_dxt5 = + feature_info_->feature_flags().ext_texture_format_dxt5; caps.texture_format_etc1 = feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture; caps.texture_format_etc1_npot = @@ -2801,6 +3057,7 @@ Capabilities GLES2DecoderImpl::GetCapabilities() { feature_info_->feature_flags().blend_equation_advanced; caps.blend_equation_advanced_coherent = feature_info_->feature_flags().blend_equation_advanced_coherent; + caps.texture_rg = feature_info_->feature_flags().ext_texture_rg; return caps; } @@ -2866,9 +3123,15 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() { features().nv_draw_buffers ? 1 : 0; } - ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC - : SH_GLES2_SPEC; - if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing) + ShShaderSpec shader_spec; + if (force_webgl_glsl_validation_) { + shader_spec = unsafe_es3_apis_enabled() ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC; + } else { + shader_spec = unsafe_es3_apis_enabled() ? SH_GLES3_SPEC : SH_GLES2_SPEC; + } + + if ((shader_spec == SH_WEBGL_SPEC || shader_spec == SH_WEBGL2_SPEC) && + features().enable_shader_name_hashing) resources.HashFunction = &CityHash64; else resources.HashFunction = NULL; @@ -2891,6 +3154,10 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() { if (workarounds().regenerate_struct_names) driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES; + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEmulateShaderPrecision)) + resources.WEBGL_debug_shader_precision = true; + vertex_translator_ = shader_translator_cache()->GetTranslator( GL_VERTEX_SHADER, shader_spec, @@ -2993,6 +3260,7 @@ void GLES2DecoderImpl::DeleteBuffersHelper( for (GLsizei ii = 0; ii < n; ++ii) { Buffer* buffer = GetBuffer(client_ids[ii]); if (buffer && !buffer->IsDeleted()) { + buffer->RemoveMappedRange(); state_.vertex_attrib_manager->Unbind(buffer); if (state_.bound_array_buffer.get() == buffer) { state_.bound_array_buffer = NULL; @@ -3012,11 +3280,16 @@ void GLES2DecoderImpl::DeleteFramebuffersHelper( GetFramebuffer(client_ids[ii]); if (framebuffer && !framebuffer->IsDeleted()) { if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { - framebuffer_state_.bound_draw_framebuffer = NULL; - framebuffer_state_.clear_state_dirty = true; GLenum target = supports_separate_framebuffer_binds ? GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; + + // Unbind attachments on FBO before deletion. + if (workarounds().unbind_attachments_on_bound_render_fbo_delete) + framebuffer->DoUnbindGLAttachmentsForWorkaround(target); + glBindFramebufferEXT(target, GetBackbufferServiceId()); + framebuffer_state_.bound_draw_framebuffer = NULL; + framebuffer_state_.clear_state_dirty = true; } if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) { framebuffer_state_.bound_read_framebuffer = NULL; @@ -3125,11 +3398,22 @@ bool GLES2DecoderImpl::MakeCurrent() { if (!context_.get()) return false; - if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) { - LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent."; + if (WasContextLost()) { + LOG(ERROR) << " GLES2DecoderImpl: Trying to make lost context current."; + return false; + } - MaybeExitOnContextLost(); + if (!context_->MakeCurrent(surface_.get())) { + LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent."; + MarkContextLost(error::kMakeCurrentFailed); + group_->LoseContexts(error::kUnknown); + return false; + } + if (CheckResetStatus()) { + LOG(ERROR) + << " GLES2DecoderImpl: Context reset detected after MakeCurrent."; + group_->LoseContexts(error::kUnknown); return false; } @@ -3426,7 +3710,7 @@ Logger* GLES2DecoderImpl::GetLogger() { void GLES2DecoderImpl::BeginDecoding() { gpu_tracer_->BeginDecoding(); - gpu_trace_commands_ = gpu_tracer_->IsTracing(); + gpu_trace_commands_ = gpu_tracer_->IsTracing() && *gpu_decoder_category_; gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ || (*cb_command_trace_category_ != 0); } @@ -3521,6 +3805,8 @@ void GLES2DecoderImpl::Destroy(bool have_context) { copy_texture_CHROMIUM_.reset(); } + clear_framebuffer_blit_.reset(); + if (state_.current_program.get()) { program_manager()->UnuseProgram(shader_manager(), state_.current_program.get()); @@ -3586,6 +3872,7 @@ void GLES2DecoderImpl::Destroy(bool have_context) { state_.current_program = NULL; copy_texture_CHROMIUM_.reset(); + clear_framebuffer_blit_.reset(); if (query_manager_.get()) { query_manager_->Destroy(have_context); @@ -3621,6 +3908,12 @@ void GLES2DecoderImpl::Destroy(bool have_context) { // by the context group. async_pixel_transfer_manager_.reset(); + // Destroy the GPU Tracer which may own some in process GPU Timings. + if (gpu_tracer_) { + gpu_tracer_->Destroy(have_context); + gpu_tracer_.reset(); + } + if (group_.get()) { framebuffer_manager()->RemoveObserver(this); group_->Destroy(this, have_context); @@ -3900,7 +4193,9 @@ error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands, if (DebugImpl && gpu_trace_commands_) { if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) { doing_gpu_trace = true; - gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder); + gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_decoder"), + GetCommandName(command), + kTraceDecoder); } } @@ -3973,28 +4268,6 @@ void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) { buffer_manager()->RemoveBuffer(client_id); } -bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { - if (GetProgram(client_id)) { - return false; - } - GLuint service_id = glCreateProgram(); - if (service_id != 0) { - CreateProgram(client_id, service_id); - } - return true; -} - -bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { - if (GetShader(client_id)) { - return false; - } - GLuint service_id = glCreateShader(type); - if (service_id != 0) { - CreateShader(client_id, service_id, type); - } - return true; -} - void GLES2DecoderImpl::DoFinish() { glFinish(); ProcessPendingReadPixels(); @@ -4182,9 +4455,9 @@ void GLES2DecoderImpl::ClearAllAttributes() const { glBindVertexArrayOES(0); for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) { - if (i != 0) // Never disable attribute 0 + if (i != 0) // Never disable attribute 0 glDisableVertexAttribArray(i); - if(features().angle_instanced_arrays) + if (features().angle_instanced_arrays) glVertexAttribDivisorANGLE(i, 0); } } @@ -4197,15 +4470,27 @@ void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) { state_.SetIgnoreCachedStateForTest(ignore); } +void GLES2DecoderImpl::SetAllowExit(bool allow_exit) { + allow_exit_ = allow_exit; +} + void GLES2DecoderImpl::OnFboChanged() const { if (workarounds().restore_scissor_on_fbo_change) - state_.fbo_binding_for_scissor_workaround_dirty_ = true; + state_.fbo_binding_for_scissor_workaround_dirty = true; + + if (workarounds().gl_begin_gl_end_on_fbo_change_to_backbuffer) { + GLint bound_fbo_unsigned = -1; + glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_fbo_unsigned); + GLuint bound_fbo = static_cast<GLuint>(bound_fbo_unsigned); + if (surface_ && surface_->GetBackingFrameBufferObject() == bound_fbo) + surface_->NotifyWasBound(); + } } // Called after the FBO is checked for completeness. void GLES2DecoderImpl::OnUseFramebuffer() const { - if (state_.fbo_binding_for_scissor_workaround_dirty_) { - state_.fbo_binding_for_scissor_workaround_dirty_ = false; + if (state_.fbo_binding_for_scissor_workaround_dirty) { + state_.fbo_binding_for_scissor_workaround_dirty = false; // The driver forgets the correct scissor when modifying the FBO binding. glScissor(state_.scissor_x, state_.scissor_y, @@ -4348,6 +4633,12 @@ void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) { case GL_TEXTURE_RECTANGLE_ARB: unit.bound_texture_rectangle_arb = texture_ref; break; + case GL_TEXTURE_3D: + unit.bound_texture_3d = texture_ref; + break; + case GL_TEXTURE_2D_ARRAY: + unit.bound_texture_2d_array = texture_ref; + break; default: NOTREACHED(); // Validation should prevent us getting here. break; @@ -4370,6 +4661,9 @@ void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) { void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum* attachments) { + if (workarounds().disable_discard_framebuffer) + return; + Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER); @@ -4436,7 +4730,13 @@ void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target, } ScopedRenderTo do_render(framebuffer); - glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get()); + if (feature_info_->gl_version_info().is_es3) { + glInvalidateFramebuffer( + target, numAttachments, translated_attachments.get()); + } else { + glDiscardFramebufferEXT( + target, numAttachments, translated_attachments.get()); + } } void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) { @@ -4612,23 +4912,93 @@ bool GLES2DecoderImpl::GetHelper( *num_written = 1; if (params) { GLint v = 0; - glGetIntegerv(GL_ALPHA_BITS, &v); - params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0; + if (feature_info_->gl_version_info().is_desktop_core_profile) { + Framebuffer* framebuffer = + GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); + if (framebuffer) { + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &v); + } else { + v = (back_buffer_color_format_ == GL_RGBA ? 8 : 0); + } + } else { + glGetIntegerv(GL_ALPHA_BITS, &v); + } + params[0] = + BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0; } return true; case GL_DEPTH_BITS: *num_written = 1; if (params) { GLint v = 0; - glGetIntegerv(GL_DEPTH_BITS, &v); + if (feature_info_->gl_version_info().is_desktop_core_profile) { + Framebuffer* framebuffer = + GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); + if (framebuffer) { + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &v); + } else { + v = (back_buffer_has_depth_ ? 24 : 0); + } + } else { + glGetIntegerv(GL_DEPTH_BITS, &v); + } params[0] = BoundFramebufferHasDepthAttachment() ? v : 0; } return true; + case GL_RED_BITS: + case GL_GREEN_BITS: + case GL_BLUE_BITS: + *num_written = 1; + if (params) { + GLint v = 0; + if (feature_info_->gl_version_info().is_desktop_core_profile) { + Framebuffer* framebuffer = + GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); + if (framebuffer) { + GLenum framebuffer_enum = 0; + switch (pname) { + case GL_RED_BITS: + framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE; + break; + case GL_GREEN_BITS: + framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE; + break; + case GL_BLUE_BITS: + framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE; + break; + } + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, framebuffer_enum, &v); + } else { + v = 8; + } + } else { + glGetIntegerv(pname, &v); + } + params[0] = v; + } + return true; case GL_STENCIL_BITS: *num_written = 1; if (params) { GLint v = 0; - glGetIntegerv(GL_STENCIL_BITS, &v); + if (feature_info_->gl_version_info().is_desktop_core_profile) { + Framebuffer* framebuffer = + GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); + if (framebuffer) { + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &v); + } else { + v = (back_buffer_has_stencil_ ? 8 : 0); + } + } else { + glGetIntegerv(GL_STENCIL_BITS, &v); + } params[0] = BoundFramebufferHasStencilAttachment() ? v : 0; } return true; @@ -4904,6 +5274,12 @@ void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) { } } +void GLES2DecoderImpl::DoGetInteger64v(GLenum pname, GLint64* params) { + DCHECK(params); + pname = AdjustGetPname(pname); + glGetInteger64v(pname, params); +} + void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) { DCHECK(params); GLsizei num_written; @@ -5044,8 +5420,7 @@ error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size, Shader* shader = GetShader(client_id); if (shader) { if (!shader->IsDeleted()) { - glDeleteShader(shader->service_id()); - shader_manager()->MarkAsDeleted(shader); + shader_manager()->Delete(shader); } } else { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader"); @@ -5078,6 +5453,19 @@ error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) { if (CheckBoundFramebuffersValid("glClear")) { ApplyDirtyState(); ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); + if (workarounds().gl_clear_broken) { + ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround", + GetErrorState()); + if (!BoundFramebufferHasDepthAttachment()) + mask &= ~GL_DEPTH_BUFFER_BIT; + if (!BoundFramebufferHasStencilAttachment()) + mask &= ~GL_STENCIL_BUFFER_BIT; + clear_framebuffer_blit_->ClearFramebuffer( + this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red, + state_.color_clear_green, state_.color_clear_blue, + state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear); + return error::kNoError; + } glClear(mask); } return error::kNoError; @@ -5310,6 +5698,25 @@ void GLES2DecoderImpl::DoFramebufferTexture2DCommon( OnFboChanged(); } +void GLES2DecoderImpl::DoFramebufferTextureLayer( + GLenum target, GLenum attachment, GLuint client_texture_id, + GLint level, GLint layer) { + // TODO(zmo): Unsafe ES3 API, missing states update. + GLuint service_id = 0; + TextureRef* texture_ref = NULL; + if (client_texture_id) { + texture_ref = GetTexture(client_texture_id); + if (!texture_ref) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, + "glFramebufferTextureLayer", "unknown texture_ref"); + return; + } + service_id = texture_ref->service_id(); + } + glFramebufferTextureLayer(target, attachment, service_id, level, layer); +} + void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv( GLenum target, GLenum attachment, GLenum pname, GLint* params) { Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); @@ -5405,7 +5812,7 @@ void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper( GLsizei height) { // TODO(sievers): This could be resolved at the GL binding level, but the // binding process is currently a bit too 'brute force'. - if (feature_info->feature_flags().is_angle) { + if (feature_info->gl_version_info().is_angle) { glRenderbufferStorageMultisampleANGLE( target, samples, internal_format, width, height); } else if (feature_info->feature_flags().use_core_framebuffer_multisample) { @@ -5429,7 +5836,7 @@ void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0, GLenum filter) { // TODO(sievers): This could be resolved at the GL binding level, but the // binding process is currently a bit too 'brute force'. - if (feature_info_->feature_flags().is_angle) { + if (feature_info_->gl_version_info().is_angle) { glBlitFramebufferANGLE( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) { @@ -5507,7 +5914,6 @@ void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM( GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM"); if (error == GL_NO_ERROR) { - if (workarounds().validate_multisample_buffer_allocation) { if (!VerifyMultisampleRenderbufferIntegrity( renderbuffer->service_id(), impl_format)) { @@ -5575,7 +5981,7 @@ bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity( // These formats have been selected because they are very common or are known // to be used by the WebGL backbuffer. If problems are observed with other // color formats they can be added here. - switch(format) { + switch (format) { case GL_RGB: case GL_RGB8: case GL_RGBA: @@ -5602,7 +6008,11 @@ bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity( // Texture only needs to be 1x1. glBindTexture(GL_TEXTURE_2D, validation_texture_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, + // TODO(erikchen): When Chrome on Mac is linked against an OSX 10.9+ SDK, a + // multisample will fail if the color format of the source and destination + // do not match. Here, we assume that the source is GL_RGBA, and make the + // destination GL_RGBA. http://crbug.com/484203 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_); @@ -5726,15 +6136,7 @@ void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) { } LogClientServiceForInfo(program, program_id, "glLinkProgram"); - ShaderTranslator* vertex_translator = NULL; - ShaderTranslator* fragment_translator = NULL; - if (use_shader_translator_) { - vertex_translator = vertex_translator_.get(); - fragment_translator = fragment_translator_.get(); - } if (program->Link(shader_manager(), - vertex_translator, - fragment_translator, workarounds().count_all_in_varyings_packing ? Program::kCountAll : Program::kCountOnlyStaticallyUsed, shader_cache_callback_)) { @@ -5749,7 +6151,19 @@ void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) { // LinkProgram can be very slow. Exit command processing to allow for // context preemption and GPU watchdog checks. ExitCommandProcessingEarly(); -}; +} + +void GLES2DecoderImpl::DoSamplerParameterfv( + GLuint sampler, GLenum pname, const GLfloat* params) { + DCHECK(params); + glSamplerParameterf(sampler, pname, params[0]); +} + +void GLES2DecoderImpl::DoSamplerParameteriv( + GLuint sampler, GLenum pname, const GLint* params) { + DCHECK(params); + glSamplerParameteri(sampler, pname, params[0]); +} void GLES2DecoderImpl::DoTexParameterf( GLenum target, GLenum pname, GLfloat param) { @@ -6293,12 +6707,17 @@ bool GLES2DecoderImpl::PrepareTexturesForRender() { glBindTexture( textarget, texture_manager()->black_texture_id(uniform_info->type)); - LOCAL_RENDER_WARNING( - std::string("texture bound to texture unit ") + - base::IntToString(texture_unit_index) + - " is not renderable. It maybe non-power-of-2 and have" - " incompatible texture filtering or is not" - " 'texture complete'"); + if (!texture_ref) { + LOCAL_RENDER_WARNING( + std::string("there is no texture bound to the unit ") + + base::IntToString(texture_unit_index)); + } else { + LOCAL_RENDER_WARNING( + std::string("texture bound to texture unit ") + + base::IntToString(texture_unit_index) + + " is not renderable. It maybe non-power-of-2 and have" + " incompatible texture filtering."); + } continue; } @@ -6435,7 +6854,7 @@ bool GLES2DecoderImpl::SimulateAttrib0( DCHECK(simulated); *simulated = false; - if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) + if (feature_info_->gl_version_info().BehavesLikeGLES()) return true; const VertexAttrib* attrib = @@ -6454,7 +6873,7 @@ bool GLES2DecoderImpl::SimulateAttrib0( uint32 size_needed = 0; if (num_vertices == 0 || - !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) || + !SafeMultiplyUint32(num_vertices, sizeof(Vec4f), &size_needed) || size_needed > 0x7FFFFFFFU) { LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); return false; @@ -6480,12 +6899,12 @@ bool GLES2DecoderImpl::SimulateAttrib0( const Vec4& value = state_.attrib_values[0]; if (new_buffer || (attrib_0_used && - (!attrib_0_buffer_matches_value_ || - (value.v[0] != attrib_0_value_.v[0] || - value.v[1] != attrib_0_value_.v[1] || - value.v[2] != attrib_0_value_.v[2] || - value.v[3] != attrib_0_value_.v[3])))) { - std::vector<Vec4> temp(num_vertices, value); + (!attrib_0_buffer_matches_value_ || !value.Equal(attrib_0_value_)))){ + // TODO(zmo): This is not 100% correct because we might lose data when + // casting to float type, but it is a corner case and once we migrate to + // core profiles on desktop GL, it is no longer relevant. + Vec4f fvalue(value); + std::vector<Vec4f> temp(num_vertices, fvalue); glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]); attrib_0_buffer_matches_value_ = true; attrib_0_value_ = value; @@ -6733,6 +7152,9 @@ error::Error GLES2DecoderImpl::DoDrawArrays( error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size, const void* cmd_data) { + // TODO(zmo): crbug.com/481184 + // On Desktop GL with versions lower than 4.3, we need to emulate + // GL_PRIMITIVE_RESTART_FIXED_INDEX using glPrimitiveRestartIndex(). const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data); return DoDrawArrays("glDrawArrays", false, @@ -6876,6 +7298,9 @@ error::Error GLES2DecoderImpl::DoDrawElements( error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size, const void* cmd_data) { + // TODO(zmo): crbug.com/481184 + // On Desktop GL with versions lower than 4.3, we need to emulate + // GL_PRIMITIVE_RESTART_FIXED_INDEX using glPrimitiveRestartIndex(). const gles2::cmds::DrawElements& c = *static_cast<const gles2::cmds::DrawElements*>(cmd_data); return DoDrawElements("glDrawElements", @@ -6927,35 +7352,35 @@ GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM( return max_vertex_accessed; } -// Calls glShaderSource for the various versions of the ShaderSource command. -// Assumes that data / data_size points to a piece of memory that is in range -// of whatever context it came from (shared memory, immediate memory, bucket -// memory.) -error::Error GLES2DecoderImpl::ShaderSourceHelper( - GLuint client_id, const char* data, uint32 data_size) { - std::string str(data, data + data_size); +void GLES2DecoderImpl::DoShaderSource( + GLuint client_id, GLsizei count, const char** data, const GLint* length) { + std::string str; + for (GLsizei ii = 0; ii < count; ++ii) { + if (length && length[ii] > 0) + str.append(data[ii], length[ii]); + else + str.append(data[ii]); + } Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource"); if (!shader) { - return error::kNoError; + return; } // Note: We don't actually call glShaderSource here. We wait until - // the call to glCompileShader. + // we actually compile the shader. shader->set_source(str); - return error::kNoError; } -error::Error GLES2DecoderImpl::HandleShaderSourceBucket( - uint32 immediate_data_size, - const void* cmd_data) { - const gles2::cmds::ShaderSourceBucket& c = - *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data); - Bucket* bucket = GetBucket(c.data_bucket_id); - if (!bucket || bucket->size() == 0) { - return error::kInvalidArguments; +void GLES2DecoderImpl::DoTransformFeedbackVaryings( + GLuint client_program_id, GLsizei count, const char* const* varyings, + GLenum buffer_mode) { + Program* program = GetProgramInfoNotShader( + client_program_id, "glTransformFeedbackVaryings"); + if (!program) { + return; } - return ShaderSourceHelper( - c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1), - bucket->size() - 1); + program->TransformFeedbackVaryings(count, varyings, buffer_mode); + glTransformFeedbackVaryings( + program->service_id(), count, varyings, buffer_mode); } void GLES2DecoderImpl::DoCompileShader(GLuint client_id) { @@ -6964,20 +7389,17 @@ void GLES2DecoderImpl::DoCompileShader(GLuint client_id) { if (!shader) { return; } - ShaderTranslator* translator = NULL; + + scoped_refptr<ShaderTranslatorInterface> translator; if (use_shader_translator_) { - translator = shader->shader_type() == GL_VERTEX_SHADER ? - vertex_translator_.get() : fragment_translator_.get(); + translator = shader->shader_type() == GL_VERTEX_SHADER ? + vertex_translator_ : fragment_translator_; } - shader->DoCompile( - translator, - feature_info_->feature_flags().angle_translated_shader_source ? - Shader::kANGLE : Shader::kGL); - - // CompileShader can be very slow. Exit command processing to allow for - // context preemption and GPU watchdog checks. - ExitCommandProcessingEarly(); + const Shader::TranslatedShaderSourceType source_type = + feature_info_->feature_flags().angle_translated_shader_source ? + Shader::kANGLE : Shader::kGL; + shader->RequestCompile(translator, source_type); } void GLES2DecoderImpl::DoGetShaderiv( @@ -6986,6 +7408,19 @@ void GLES2DecoderImpl::DoGetShaderiv( if (!shader) { return; } + + // Compile now for statuses that require it. + switch (pname) { + case GL_COMPILE_STATUS: + case GL_INFO_LOG_LENGTH: + case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: + shader->DoCompile(); + break; + + default: + break; + } + switch (pname) { case GL_SHADER_SOURCE_LENGTH: *params = shader->source().size(); @@ -7043,6 +7478,9 @@ error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE( return error::kNoError; } + // Make sure translator has been utilized in compile. + shader->DoCompile(); + bucket->SetFromString(shader->translated_source().c_str()); return error::kNoError; } @@ -7078,6 +7516,10 @@ error::Error GLES2DecoderImpl::HandleGetShaderInfoLog( bucket->SetFromString(""); return error::kNoError; } + + // Shader must be compiled in order to get the info log. + shader->DoCompile(); + bucket->SetFromString(shader->log_info().c_str()); return error::kNoError; } @@ -7175,7 +7617,8 @@ void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) { void GLES2DecoderImpl::GetVertexAttribHelper( const VertexAttrib* attrib, GLenum pname, GLint* params) { switch (pname) { - case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: { + case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + { Buffer* buffer = attrib->buffer(); if (buffer && !buffer->IsDeleted()) { GLuint client_id; @@ -7199,9 +7642,12 @@ void GLES2DecoderImpl::GetVertexAttribHelper( case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: *params = attrib->normalized(); break; - case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: + case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: *params = attrib->divisor(); break; + case GL_VERTEX_ATTRIB_ARRAY_INTEGER: + *params = attrib->integer(); + break; default: NOTREACHED(); break; @@ -7241,66 +7687,56 @@ void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded( texture->InitTextureMaxAnisotropyIfNeeded(target); } -void GLES2DecoderImpl::DoGetVertexAttribfv( - GLuint index, GLenum pname, GLfloat* params) { +template <typename T> +void GLES2DecoderImpl::DoGetVertexAttribImpl( + GLuint index, GLenum pname, T* params) { VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index); if (!attrib) { LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range"); + GL_INVALID_VALUE, "glGetVertexAttrib", "index out of range"); return; } switch (pname) { - case GL_CURRENT_VERTEX_ATTRIB: { - const Vec4& value = state_.attrib_values[index]; - params[0] = value.v[0]; - params[1] = value.v[1]; - params[2] = value.v[2]; - params[3] = value.v[3]; + case GL_CURRENT_VERTEX_ATTRIB: + state_.attrib_values[index].GetValues(params); break; - } default: { GLint value = 0; GetVertexAttribHelper(attrib, pname, &value); - *params = static_cast<GLfloat>(value); + *params = static_cast<T>(value); break; } } } +void GLES2DecoderImpl::DoGetVertexAttribfv( + GLuint index, GLenum pname, GLfloat* params) { + DoGetVertexAttribImpl<GLfloat>(index, pname, params); +} + void GLES2DecoderImpl::DoGetVertexAttribiv( GLuint index, GLenum pname, GLint* params) { - VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index); - if (!attrib) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range"); - return; - } - switch (pname) { - case GL_CURRENT_VERTEX_ATTRIB: { - const Vec4& value = state_.attrib_values[index]; - params[0] = static_cast<GLint>(value.v[0]); - params[1] = static_cast<GLint>(value.v[1]); - params[2] = static_cast<GLint>(value.v[2]); - params[3] = static_cast<GLint>(value.v[3]); - break; - } - default: - GetVertexAttribHelper(attrib, pname, params); - break; - } + DoGetVertexAttribImpl<GLint>(index, pname, params); +} + +void GLES2DecoderImpl::DoGetVertexAttribIiv( + GLuint index, GLenum pname, GLint* params) { + DoGetVertexAttribImpl<GLint>(index, pname, params); } +void GLES2DecoderImpl::DoGetVertexAttribIuiv( + GLuint index, GLenum pname, GLuint* params) { + DoGetVertexAttribImpl<GLuint>(index, pname, params); +} + +template <typename T> bool GLES2DecoderImpl::SetVertexAttribValue( - const char* function_name, GLuint index, const GLfloat* value) { + const char* function_name, GLuint index, const T* value) { if (index >= state_.attrib_values.size()) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range"); return false; } - Vec4& v = state_.attrib_values[index]; - v.v[0] = value[0]; - v.v[1] = value[1]; - v.v[2] = value[2]; - v.v[3] = value[3]; + state_.attrib_values[index].SetValues(value); return true; } @@ -7361,6 +7797,122 @@ void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) { } } +void GLES2DecoderImpl::DoVertexAttribI4i( + GLuint index, GLint v0, GLint v1, GLint v2, GLint v3) { + GLint v[4] = { v0, v1, v2, v3 }; + if (SetVertexAttribValue("glVertexAttribI4i", index, v)) { + glVertexAttribI4i(index, v0, v1, v2, v3); + } +} + +void GLES2DecoderImpl::DoVertexAttribI4iv(GLuint index, const GLint* v) { + if (SetVertexAttribValue("glVertexAttribI4iv", index, v)) { + glVertexAttribI4iv(index, v); + } +} + +void GLES2DecoderImpl::DoVertexAttribI4ui( + GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3) { + GLuint v[4] = { v0, v1, v2, v3 }; + if (SetVertexAttribValue("glVertexAttribI4ui", index, v)) { + glVertexAttribI4ui(index, v0, v1, v2, v3); + } +} + +void GLES2DecoderImpl::DoVertexAttribI4uiv(GLuint index, const GLuint* v) { + if (SetVertexAttribValue("glVertexAttribI4uiv", index, v)) { + glVertexAttribI4uiv(index, v); + } +} + +error::Error GLES2DecoderImpl::HandleVertexAttribIPointer( + uint32 immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::VertexAttribIPointer& c = + *static_cast<const gles2::cmds::VertexAttribIPointer*>(cmd_data); + + if (!state_.bound_array_buffer.get() || + state_.bound_array_buffer->IsDeleted()) { + if (state_.vertex_attrib_manager.get() == + state_.default_vertex_attrib_manager.get()) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glVertexAttribIPointer", "no array buffer bound"); + return error::kNoError; + } else if (c.offset != 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, + "glVertexAttribIPointer", "client side arrays are not allowed"); + return error::kNoError; + } + } + + GLuint indx = c.indx; + GLint size = c.size; + GLenum type = c.type; + GLsizei stride = c.stride; + GLsizei offset = c.offset; + const void* ptr = reinterpret_cast<const void*>(offset); + if (!validators_->vertex_attrib_i_type.IsValid(type)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribIPointer", type, "type"); + return error::kNoError; + } + if (!validators_->vertex_attrib_size.IsValid(size)) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glVertexAttribIPointer", "size GL_INVALID_VALUE"); + return error::kNoError; + } + if (indx >= group_->max_vertex_attribs()) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glVertexAttribIPointer", "index out of range"); + return error::kNoError; + } + if (stride < 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glVertexAttribIPointer", "stride < 0"); + return error::kNoError; + } + if (stride > 255) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glVertexAttribIPointer", "stride > 255"); + return error::kNoError; + } + if (offset < 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glVertexAttribIPointer", "offset < 0"); + return error::kNoError; + } + GLsizei component_size = + GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type); + // component_size must be a power of two to use & as optimized modulo. + DCHECK(GLES2Util::IsPOT(component_size)); + if (offset & (component_size - 1)) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, + "glVertexAttribIPointer", "offset not valid for type"); + return error::kNoError; + } + if (stride & (component_size - 1)) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, + "glVertexAttribIPointer", "stride not valid for type"); + return error::kNoError; + } + state_.vertex_attrib_manager + ->SetAttribInfo(indx, + state_.bound_array_buffer.get(), + size, + type, + GL_FALSE, + stride, + stride != 0 ? stride : component_size * size, + offset, + GL_TRUE); + glVertexAttribIPointer(indx, size, type, stride, ptr); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleVertexAttribPointer( uint32 immediate_data_size, const void* cmd_data) { @@ -7442,8 +7994,10 @@ error::Error GLES2DecoderImpl::HandleVertexAttribPointer( normalized, stride, stride != 0 ? stride : component_size * size, - offset); - if (type != GL_FIXED) { + offset, + GL_FALSE); + // We support GL_FIXED natively on EGL/GLES2 implementations + if (type != GL_FIXED || feature_info_->gl_version_info().is_es) { glVertexAttribPointer(indx, size, type, normalized, stride, ptr); } return error::kNoError; @@ -7487,7 +8041,7 @@ error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE( template <typename pixel_data_type> static void WriteAlphaData( - void *pixels, uint32 row_count, uint32 channel_count, + void* pixels, uint32 row_count, uint32 channel_count, uint32 alpha_channel_index, uint32 unpadded_row_size, uint32 padded_row_size, pixel_data_type alpha_value) { DCHECK_GT(channel_count, 0U); @@ -7530,7 +8084,7 @@ void GLES2DecoderImpl::FinishReadPixels( } } GLES2Util::ComputeImageDataSizes( - width, height, format, type, state_.pack_alignment, &pixels_size, + width, height, 1, format, type, state_.pack_alignment, &pixels_size, NULL, NULL); void* pixels = GetSharedMemoryAs<void*>( c.pixels_shm_id, c.pixels_shm_offset, pixels_size); @@ -7550,6 +8104,11 @@ void GLES2DecoderImpl::FinishReadPixels( } else { data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); } + if (!data) { + LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer", + "Unable to map memory for readback."); + return; + } memcpy(pixels, data, pixels_size); // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't // have to restore the state. @@ -7572,7 +8131,7 @@ void GLES2DecoderImpl::FinishReadPixels( uint32 unpadded_row_size; uint32 padded_row_size; if (!GLES2Util::ComputeImageDataSizes( - width, 2, format, type, state_.pack_alignment, &temp_size, + width, 2, 1, format, type, state_.pack_alignment, &temp_size, &unpadded_row_size, &padded_row_size)) { return; } @@ -7635,7 +8194,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size, typedef cmds::ReadPixels::Result Result; uint32 pixels_size; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, state_.pack_alignment, &pixels_size, + width, height, 1, format, type, state_.pack_alignment, &pixels_size, NULL, NULL)) { return error::kOutOfBounds; } @@ -7711,7 +8270,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size, uint32 unpadded_row_size; uint32 padded_row_size; if (!GLES2Util::ComputeImageDataSizes( - width, 2, format, type, state_.pack_alignment, &temp_size, + width, 2, 1, format, type, state_.pack_alignment, &temp_size, &unpadded_row_size, &padded_row_size)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); @@ -7721,8 +8280,8 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size, GLint dest_x_offset = std::max(-x, 0); uint32 dest_row_offset; if (!GLES2Util::ComputeImageDataSizes( - dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset, - NULL, NULL)) { + dest_x_offset, 1, 1, format, type, state_.pack_alignment, + &dest_row_offset, NULL, NULL)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); return error::kNoError; @@ -7748,10 +8307,13 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size, } } else { if (async && features().use_async_readpixels) { - GLuint buffer; + GLuint buffer = 0; glGenBuffersARB(1, &buffer); glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); - glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ); + // For ANGLE client version 2, GL_STREAM_READ is not available. + const GLenum usage_hint = feature_info_->gl_version_info().is_angle ? + GL_STATIC_DRAW : GL_STREAM_READ; + glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint); GLenum error = glGetError(); if (error == GL_NO_ERROR) { glReadPixels(x, y, width, height, format, type, 0); @@ -7767,6 +8329,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size, } else { // On error, unbind pack buffer and fall through to sync readpixels glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); + glDeleteBuffersARB(1, &buffer); } } glReadPixels(x, y, width, height, format, type, pixels); @@ -8002,6 +8565,132 @@ error::Error GLES2DecoderImpl::HandleGetUniformLocation( c.program, c.location_shm_id, c.location_shm_offset, name_str); } +error::Error GLES2DecoderImpl::HandleGetUniformIndices( + uint32 immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetUniformIndices& c = + *static_cast<const gles2::cmds::GetUniformIndices*>(cmd_data); + Bucket* bucket = GetBucket(c.names_bucket_id); + if (!bucket) { + return error::kInvalidArguments; + } + GLsizei count = 0; + std::vector<char*> names; + std::vector<GLint> len; + if (!bucket->GetAsStrings(&count, &names, &len) || count <= 0) { + return error::kInvalidArguments; + } + typedef cmds::GetUniformIndices::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.indices_shm_id, c.indices_shm_offset, + Result::ComputeSize(static_cast<size_t>(count))); + GLuint* indices = result ? result->GetData() : NULL; + if (indices == NULL) { + return error::kOutOfBounds; + } + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + Program* program = GetProgramInfoNotShader(c.program, "glGetUniformIndices"); + if (!program) { + return error::kNoError; + } + GLuint service_id = program->service_id(); + GLint link_status = GL_FALSE; + glGetProgramiv(service_id, GL_LINK_STATUS, &link_status); + if (link_status != GL_TRUE) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glGetUniformIndices", "program not linked"); + return error::kNoError; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetUniformIndices"); + glGetUniformIndices(service_id, count, &names[0], indices); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(count); + } else { + LOCAL_SET_GL_ERROR(error, "GetUniformIndices", ""); + } + return error::kNoError; +} + +error::Error GLES2DecoderImpl::GetFragDataLocationHelper( + GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, + const std::string& name_str) { + GLint* location = GetSharedMemoryAs<GLint*>( + location_shm_id, location_shm_offset, sizeof(GLint)); + if (!location) { + return error::kOutOfBounds; + } + // Require the client to init this incase the context is lost and we are no + // longer executing commands. + if (*location != -1) { + return error::kGenericError; + } + Program* program = GetProgramInfoNotShader( + client_id, "glGetFragDataLocation"); + if (!program) { + return error::kNoError; + } + *location = glGetFragDataLocation(program->service_id(), name_str.c_str()); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleGetFragDataLocation( + uint32 immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetFragDataLocation& c = + *static_cast<const gles2::cmds::GetFragDataLocation*>(cmd_data); + Bucket* bucket = GetBucket(c.name_bucket_id); + if (!bucket) { + return error::kInvalidArguments; + } + std::string name_str; + if (!bucket->GetAsString(&name_str)) { + return error::kInvalidArguments; + } + return GetFragDataLocationHelper( + c.program, c.location_shm_id, c.location_shm_offset, name_str); +} + +error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetUniformBlockIndex& c = + *static_cast<const gles2::cmds::GetUniformBlockIndex*>(cmd_data); + Bucket* bucket = GetBucket(c.name_bucket_id); + if (!bucket) { + return error::kInvalidArguments; + } + std::string name_str; + if (!bucket->GetAsString(&name_str)) { + return error::kInvalidArguments; + } + GLuint* index = GetSharedMemoryAs<GLuint*>( + c.index_shm_id, c.index_shm_offset, sizeof(GLuint)); + if (!index) { + return error::kOutOfBounds; + } + // Require the client to init this in case the context is lost and we are no + // longer executing commands. + if (*index != GL_INVALID_INDEX) { + return error::kGenericError; + } + Program* program = GetProgramInfoNotShader( + c.program, "glGetUniformBlockIndex"); + if (!program) { + return error::kNoError; + } + *index = glGetUniformBlockIndex(program->service_id(), name_str.c_str()); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size, const void* cmd_data) { const gles2::cmds::GetString& c = @@ -8011,7 +8700,8 @@ error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size, LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name"); return error::kNoError; } - const char* str = reinterpret_cast<const char*>(glGetString(name)); + + const char* str = nullptr; std::string extensions; switch (name) { case GL_VERSION: @@ -8026,6 +8716,8 @@ error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size, // They are used by WEBGL_debug_renderer_info. if (!force_webgl_glsl_validation_) str = "Chromium"; + else + str = reinterpret_cast<const char*>(glGetString(name)); break; case GL_EXTENSIONS: { @@ -8071,6 +8763,7 @@ error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size, } break; default: + str = reinterpret_cast<const char*>(glGetString(name)); break; } Bucket* bucket = CreateBucket(c.bucket_id); @@ -8106,8 +8799,7 @@ void GLES2DecoderImpl::DoBufferSubData( } bool GLES2DecoderImpl::ClearLevel( - unsigned service_id, - unsigned bind_target, + Texture* texture, unsigned target, int level, unsigned internal_format, @@ -8129,8 +8821,8 @@ bool GLES2DecoderImpl::ClearLevel( GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT; - glFramebufferTexture2DEXT( - GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level); + glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, attachment, target, + texture->service_id(), level); // ANGLE promises a depth only attachment ok. if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE) { @@ -8160,7 +8852,7 @@ bool GLES2DecoderImpl::ClearLevel( uint32 size; uint32 padded_row_size; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, state_.unpack_alignment, &size, + width, height, 1, format, type, state_.unpack_alignment, &size, NULL, &padded_row_size)) { return false; } @@ -8178,7 +8870,7 @@ bool GLES2DecoderImpl::ClearLevel( DCHECK_GT(padded_row_size, 0U); tile_height = kMaxZeroSize / padded_row_size; if (!GLES2Util::ComputeImageDataSizes( - width, tile_height, format, type, state_.unpack_alignment, &size, + width, tile_height, 1, format, type, state_.unpack_alignment, &size, NULL, NULL)) { return false; } @@ -8189,12 +8881,13 @@ bool GLES2DecoderImpl::ClearLevel( // Assumes the size has already been checked. scoped_ptr<char[]> zero(new char[size]); memset(zero.get(), 0, size); - glBindTexture(bind_target, service_id); + glBindTexture(texture->target(), texture->service_id()); + bool has_images = texture->HasImages(); GLint y = 0; while (y < height) { GLint h = y + tile_height > height ? height - y : tile_height; - if (is_texture_immutable || h != height) { + if (is_texture_immutable || h != height || has_images) { glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get()); } else { glTexImage2D( @@ -8203,9 +8896,10 @@ bool GLES2DecoderImpl::ClearLevel( } y += tile_height; } - TextureRef* texture = texture_manager()->GetTextureInfoForTarget( - &state_, bind_target); - glBindTexture(bind_target, texture ? texture->service_id() : 0); + TextureRef* bound_texture = + texture_manager()->GetTextureInfoForTarget(&state_, texture->target()); + glBindTexture(texture->target(), + bound_texture ? bound_texture->service_id() : 0); return true; } @@ -8215,6 +8909,7 @@ const int kS3TCBlockWidth = 4; const int kS3TCBlockHeight = 4; const int kS3TCDXT1BlockSize = 8; const int kS3TCDXT3AndDXT5BlockSize = 16; +const int kEACAndETC2BlockSize = 4; bool IsValidDXTSize(GLint level, GLsizei size) { return (size == 1) || @@ -8228,51 +8923,79 @@ bool IsValidPVRTCSize(GLint level, GLsizei size) { } // anonymous namespace. bool GLES2DecoderImpl::ValidateCompressedTexFuncData( - const char* function_name, - GLsizei width, GLsizei height, GLenum format, size_t size) { - unsigned int bytes_required = 0; + const char* function_name, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei size) { + base::CheckedNumeric<GLsizei> bytes_required(0); switch (format) { case GL_ATC_RGB_AMD: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_ETC1_RGB8_OES: { - int num_blocks_across = - (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; - int num_blocks_down = - (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; - int num_blocks = num_blocks_across * num_blocks_down; - bytes_required = num_blocks * kS3TCDXT1BlockSize; - break; - } + case GL_ETC1_RGB8_OES: + bytes_required = + (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; + bytes_required *= + (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; + bytes_required *= kS3TCDXT1BlockSize; + break; case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { - int num_blocks_across = - (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; - int num_blocks_down = - (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; - int num_blocks = num_blocks_across * num_blocks_down; - bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize; - break; - } + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + bytes_required = + (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; + bytes_required *= + (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; + bytes_required *= kS3TCDXT3AndDXT5BlockSize; + break; case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: - case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: { - bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8; - break; - } + case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: + bytes_required = std::max(width, 8); + bytes_required *= std::max(height, 8); + bytes_required *= 4; + bytes_required += 7; + bytes_required /= 8; + break; case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: - case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { - bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8; - break; - } + case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: + bytes_required = std::max(width, 16); + bytes_required *= std::max(height, 8); + bytes_required *= 2; + bytes_required += 7; + bytes_required /= 8; + break; + + // ES3 formats. + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + bytes_required = + (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize; + bytes_required *= + (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize; + bytes_required *= 8; + bytes_required *= depth; + break; + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + bytes_required = + (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize; + bytes_required *= + (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize; + bytes_required *= 16; + bytes_required *= depth; + break; default: LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format"); return false; } - if (size != bytes_required) { + if (!bytes_required.IsValid() || size != bytes_required.ValueOrDefault(0)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); return false; @@ -8282,13 +9005,14 @@ bool GLES2DecoderImpl::ValidateCompressedTexFuncData( } bool GLES2DecoderImpl::ValidateCompressedTexDimensions( - const char* function_name, - GLint level, GLsizei width, GLsizei height, GLenum format) { + const char* function_name, GLenum target, GLint level, + GLsizei width, GLsizei height, GLsizei depth, GLenum format) { switch (format) { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + DCHECK_EQ(1, depth); // 2D formats. if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, function_name, @@ -8296,11 +9020,11 @@ bool GLES2DecoderImpl::ValidateCompressedTexDimensions( return false; } return true; - } case GL_ATC_RGB_AMD: case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: - case GL_ETC1_RGB8_OES: { + case GL_ETC1_RGB8_OES: + DCHECK_EQ(1, depth); // 2D formats. if (width <= 0 || height <= 0) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, function_name, @@ -8308,11 +9032,11 @@ bool GLES2DecoderImpl::ValidateCompressedTexDimensions( return false; } return true; - } case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: - case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { + case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: + DCHECK_EQ(1, depth); // 2D formats. if (!IsValidPVRTCSize(level, width) || !IsValidPVRTCSize(level, height)) { LOCAL_SET_GL_ERROR( @@ -8321,7 +9045,31 @@ bool GLES2DecoderImpl::ValidateCompressedTexDimensions( return false; } return true; - } + + // ES3 formats. + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + if (width <= 0 || height <= 0 || depth <= 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, function_name, + "width, height, or depth invalid"); + return false; + } + if (target == GL_TEXTURE_3D) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, function_name, + "target invalid for format"); + return false; + } + return true; default: return false; } @@ -8329,12 +9077,12 @@ bool GLES2DecoderImpl::ValidateCompressedTexDimensions( bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( const char* function_name, - GLenum target, GLint level, GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, GLenum format, + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, Texture* texture) { - if (xoffset < 0 || yoffset < 0) { + if (xoffset < 0 || yoffset < 0 || zoffset < 0) { LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0"); + GL_INVALID_VALUE, function_name, "x/y/z offset < 0"); return false; } @@ -8353,7 +9101,8 @@ bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( } GLsizei tex_width = 0; GLsizei tex_height = 0; - if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || + if (!texture->GetLevelSize(target, level, + &tex_width, &tex_height, nullptr) || width - xoffset > tex_width || height - yoffset > tex_height) { LOCAL_SET_GL_ERROR( @@ -8361,7 +9110,7 @@ bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( return false; } return ValidateCompressedTexDimensions( - function_name, level, width, height, format); + function_name, target, level, width, height, 1, format); } case GL_ATC_RGB_AMD: case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: @@ -8389,7 +9138,8 @@ bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( } GLsizei tex_width = 0; GLsizei tex_height = 0; - if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || + if (!texture->GetLevelSize(target, level, + &tex_width, &tex_height, nullptr) || width != tex_width || height != tex_height) { LOCAL_SET_GL_ERROR( @@ -8398,8 +9148,36 @@ bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( return false; } return ValidateCompressedTexDimensions( - function_name, level, width, height, format); - } + function_name, target, level, width, height, 1, format); + } + + // ES3 formats + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + { + const int kBlockSize = 4; + GLsizei tex_width, tex_height; + if (target == GL_TEXTURE_3D || + !texture->GetLevelSize(target, level, + &tex_width, &tex_height, nullptr) || + (xoffset % kBlockSize) || (yoffset % kBlockSize) || + ((width % kBlockSize) && xoffset + width != tex_width) || + ((height % kBlockSize) && yoffset + height != tex_height)) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, function_name, + "dimensions must match existing texture level dimensions"); + return false; + } + return true; + } default: return false; } @@ -8414,7 +9192,6 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage2D( GLint border, GLsizei image_size, const void* data) { - // TODO(gman): Validate image_size is correct for width, height and format. if (!validators_->texture_target.IsValid(target)) { LOCAL_SET_GL_ERROR_INVALID_ENUM( "glCompressedTexImage2D", target, "target"); @@ -8449,10 +9226,10 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage2D( return error::kNoError; } - if (!ValidateCompressedTexDimensions( - "glCompressedTexImage2D", level, width, height, internal_format) || - !ValidateCompressedTexFuncData( - "glCompressedTexImage2D", width, height, internal_format, image_size)) { + if (!ValidateCompressedTexDimensions("glCompressedTexImage2D", target, level, + width, height, 1, internal_format) || + !ValidateCompressedTexFuncData("glCompressedTexImage2D", width, height, + 1, internal_format, image_size)) { return error::kNoError; } @@ -8592,6 +9369,249 @@ error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket( return error::kNoError; } +error::Error GLES2DecoderImpl::DoCompressedTexImage3D( + GLenum target, + GLint level, + GLenum internal_format, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei image_size, + const void* data) { + if (!validators_->texture_3_d_target.IsValid(target)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM( + "glCompressedTexImage3D", target, "target"); + return error::kNoError; + } + if (!validators_->compressed_texture_format.IsValid( + internal_format)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM( + "glCompressedTexImage3D", internal_format, "internal_format"); + return error::kNoError; + } + if (!texture_manager()->ValidForTarget(target, level, width, height, depth) || + border != 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, + "glCompressedTexImage3D", "dimensions out of range"); + return error::kNoError; + } + TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( + &state_, target); + if (!texture_ref) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, + "glCompressedTexImage3D", "unknown texture target"); + return error::kNoError; + } + Texture* texture = texture_ref->texture(); + if (texture->IsImmutable()) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, + "glCompressedTexImage3D", "texture is immutable"); + return error::kNoError; + } + + if (!ValidateCompressedTexDimensions("glCompressedTexImage3D", target, level, + width, height, depth, internal_format) || + !ValidateCompressedTexFuncData("glCompressedTexImage3D", width, height, + depth, internal_format, image_size)) { + return error::kNoError; + } + + if (!EnsureGPUMemoryAvailable(image_size)) { + LOCAL_SET_GL_ERROR( + GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory"); + return error::kNoError; + } + + if (texture->IsAttachedToFramebuffer()) { + framebuffer_state_.clear_state_dirty = true; + } + + scoped_ptr<int8[]> zero; + if (!data) { + zero.reset(new int8[image_size]); + memset(zero.get(), 0, image_size); + data = zero.get(); + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D"); + glCompressedTexImage3D(target, level, internal_format, width, height, depth, + border, image_size, data); + GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); + if (error == GL_NO_ERROR) { + texture_manager()->SetLevelInfo( + texture_ref, target, level, internal_format, + width, height, depth, border, 0, 0, true); + } + + // This may be a slow command. Exit command processing to allow for + // context preemption and GPU watchdog checks. + ExitCommandProcessingEarly(); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleCompressedTexImage3D( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + + const gles2::cmds::CompressedTexImage3D& c = + *static_cast<const gles2::cmds::CompressedTexImage3D*>(cmd_data); + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLenum internal_format = static_cast<GLenum>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLsizei depth = static_cast<GLsizei>(c.depth); + GLint border = static_cast<GLint>(c.border); + GLsizei image_size = static_cast<GLsizei>(c.imageSize); + uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); + uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); + const void* data = NULL; + if (data_shm_id != 0 || data_shm_offset != 0) { + data = GetSharedMemoryAs<const void*>( + data_shm_id, data_shm_offset, image_size); + if (!data) { + return error::kOutOfBounds; + } + } + return DoCompressedTexImage3D(target, level, internal_format, width, height, + depth, border, image_size, data); +} + +error::Error GLES2DecoderImpl::HandleCompressedTexImage3DBucket( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + + const gles2::cmds::CompressedTexImage3DBucket& c = + *static_cast<const gles2::cmds::CompressedTexImage3DBucket*>(cmd_data); + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLenum internal_format = static_cast<GLenum>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLsizei depth = static_cast<GLsizei>(c.depth); + GLint border = static_cast<GLint>(c.border); + Bucket* bucket = GetBucket(c.bucket_id); + if (!bucket) { + return error::kInvalidArguments; + } + uint32 data_size = bucket->size(); + GLsizei imageSize = data_size; + const void* data = bucket->GetData(0, data_size); + if (!data) { + return error::kInvalidArguments; + } + return DoCompressedTexImage3D(target, level, internal_format, width, height, + depth, border, imageSize, data); +} + +void GLES2DecoderImpl::DoCompressedTexSubImage3D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, + GLsizei image_size, const void* data) { + if (!validators_->texture_3_d_target.IsValid(target)) { + LOCAL_SET_GL_ERROR( + GL_INVALID_ENUM, "glCompressedTexSubImage3D", "target"); + return; + } + if (!validators_->compressed_texture_format.IsValid(format)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM( + "glCompressedTexSubImage3D", format, "format"); + return; + } + if (width < 0 || height < 0 || depth < 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glCompressedTexSubImage3D", "size < 0"); + return; + } + if (image_size < 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glCompressedTexSubImage3D", "imageSize < 0"); + return; + } + TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( + &state_, target); + if (!texture_ref) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", + "unknown texture for target"); + return; + } + Texture* texture = texture_ref->texture(); + GLenum type = 0, internal_format = 0; + if (!texture->GetLevelType(target, level, &type, &internal_format)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", + "level does not exist"); + return; + } + if (internal_format != format) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", + "format does not match internal format"); + return; + } + if (!texture->ValidForTexture(target, level, xoffset, yoffset, zoffset, + width, height, depth, type)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedTexSubImage3D", + "bad dimensions"); + return; + } + if (!ValidateCompressedTexFuncData("glCompressedTexSubImage3D", + width, height, depth, format, + image_size) || + !ValidateCompressedTexSubDimensions("glCompressedTexSubImage3D", + target, level, xoffset, yoffset, + zoffset, width, height, depth, + format, texture)) { + return; + } + + // Note: There is no need to deal with texture cleared tracking here + // because the validation above means you can only get here if the level + // is already a matching compressed format and in that case + // CompressedTexImage3D already cleared the texture. + glCompressedTexSubImage3D( + target, level, xoffset, yoffset, zoffset, width, height, depth, format, + image_size, data); + + // This may be a slow command. Exit command processing to allow for + // context preemption and GPU watchdog checks. + ExitCommandProcessingEarly(); +} + +error::Error GLES2DecoderImpl::HandleCompressedTexSubImage3DBucket( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::CompressedTexSubImage3DBucket& c = + *static_cast<const gles2::cmds::CompressedTexSubImage3DBucket*>(cmd_data); + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + GLint zoffset = static_cast<GLint>(c.zoffset); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLsizei depth = static_cast<GLsizei>(c.depth); + GLenum format = static_cast<GLenum>(c.format); + Bucket* bucket = GetBucket(c.bucket_id); + if (!bucket) { + return error::kInvalidArguments; + } + uint32 data_size = bucket->size(); + GLsizei image_size = data_size; + const void* data = bucket->GetData(0, data_size); + if (!data) { + return error::kInvalidArguments; + } + DoCompressedTexSubImage3D( + target, level, xoffset, yoffset, zoffset, width, height, depth, format, + image_size, data); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size, const void* cmd_data) { const gles2::cmds::TexImage2D& c = @@ -8614,8 +9634,8 @@ error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size, uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); uint32 pixels_size; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, - NULL)) { + width, height, 1, format, type, state_.unpack_alignment, &pixels_size, + NULL, NULL)) { return error::kOutOfBounds; } const void* pixels = NULL; @@ -8627,6 +9647,15 @@ error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size, } } + // For testing only. Allows us to stress the ability to respond to OOM errors. + if (workarounds().simulate_out_of_memory_on_large_textures && + (width * height >= 4096 * 4096)) { + LOCAL_SET_GL_ERROR( + GL_OUT_OF_MEMORY, + "glTexImage2D", "synthetic out of memory"); + return error::kNoError; + } + TextureManager::DoTextImage2DArguments args = { target, level, internal_format, width, height, border, format, type, pixels, pixels_size}; @@ -8639,6 +9668,51 @@ error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandleTexImage3D(uint32 immediate_data_size, + const void* cmd_data) { + // TODO(zmo): Unsafe ES3 API. + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + + const gles2::cmds::TexImage3D& c = + *static_cast<const gles2::cmds::TexImage3D*>(cmd_data); + TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage3D", + "widthXheight", c.width * c.height, "depth", c.depth); + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLenum internal_format = static_cast<GLenum>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLsizei depth = static_cast<GLsizei>(c.depth); + GLint border = static_cast<GLint>(c.border); + GLenum format = static_cast<GLenum>(c.format); + GLenum type = static_cast<GLenum>(c.type); + uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); + uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); + uint32 pixels_size; + if (!GLES2Util::ComputeImageDataSizes( + width, height, depth, format, type, state_.unpack_alignment, &pixels_size, + NULL, NULL)) { + return error::kOutOfBounds; + } + const void* pixels = NULL; + if (pixels_shm_id != 0 || pixels_shm_offset != 0) { + pixels = GetSharedMemoryAs<const void*>( + pixels_shm_id, pixels_shm_offset, pixels_size); + if (!pixels) { + return error::kOutOfBounds; + } + } + + glTexImage3D(target, level, internal_format, width, height, depth, border, + format, type, pixels); + + // This may be a slow command. Exit command processing to allow for + // context preemption and GPU watchdog checks. + ExitCommandProcessingEarly(); + return error::kNoError; +} + void GLES2DecoderImpl::DoCompressedTexSubImage2D( GLenum target, GLint level, @@ -8672,18 +9746,18 @@ void GLES2DecoderImpl::DoCompressedTexSubImage2D( "glCompressedTexSubImage2D", "format does not match internal format."); return; } - if (!texture->ValidForTexture( - target, level, xoffset, yoffset, width, height, type)) { + if (!texture->ValidForTexture(target, level, xoffset, yoffset, 0, width, + height, 1, type)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions."); return; } - if (!ValidateCompressedTexFuncData( - "glCompressedTexSubImage2D", width, height, format, image_size) || - !ValidateCompressedTexSubDimensions( - "glCompressedTexSubImage2D", - target, level, xoffset, yoffset, width, height, format, texture)) { + if (!ValidateCompressedTexFuncData("glCompressedTexSubImage2D", + width, height, 1, format, image_size) || + !ValidateCompressedTexSubDimensions("glCompressedTexSubImage2D", + target, level, xoffset, yoffset, 0, + width, height, 1, format, texture)) { return; } @@ -8773,8 +9847,8 @@ void GLES2DecoderImpl::DoCopyTexImage2D( uint32 estimated_size = 0; if (!GLES2Util::ComputeImageDataSizes( - width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment, - &estimated_size, NULL, NULL)) { + width, height, 1, internal_format, GL_UNSIGNED_BYTE, + state_.unpack_alignment, &estimated_size, NULL, NULL)) { LOCAL_SET_GL_ERROR( GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large"); return; @@ -8821,10 +9895,8 @@ void GLES2DecoderImpl::DoCopyTexImage2D( copyWidth != width || copyHeight != height) { // some part was clipped so clear the texture. - if (!ClearLevel( - texture->service_id(), texture->target(), - target, level, internal_format, internal_format, GL_UNSIGNED_BYTE, - width, height, texture->IsImmutable())) { + if (!ClearLevel(texture, target, level, internal_format, internal_format, + GL_UNSIGNED_BYTE, width, height, texture->IsImmutable())) { LOCAL_SET_GL_ERROR( GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); return; @@ -8879,7 +9951,7 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D( GLenum format = 0; if (!texture->GetLevelType(target, level, &type, &format) || !texture->ValidForTexture( - target, level, xoffset, yoffset, width, height, type)) { + target, level, xoffset, yoffset, 0, width, height, 1, type)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions."); return; @@ -8934,10 +10006,17 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D( Clip(x, width, size.width(), ©X, ©Width); Clip(y, height, size.height(), ©Y, ©Height); - if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) { - LOCAL_SET_GL_ERROR( - GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big"); - return; + if (xoffset != 0 || yoffset != 0 || width != size.width() || + height != size.height()) { + if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, + level)) { + LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", + "dimensions too big"); + return; + } + } else { + // Write all pixels in below. + texture_manager()->SetLevelCleared(texture_ref, target, level, true); } if (copyX != x || @@ -8947,7 +10026,7 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D( // some part was clipped so clear the sub rect. uint32 pixels_size = 0; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, state_.unpack_alignment, &pixels_size, + width, height, 1, format, type, state_.unpack_alignment, &pixels_size, NULL, NULL)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large"); @@ -9035,7 +10114,7 @@ bool GLES2DecoderImpl::ValidateTexSubImage2D( return false; } if (!texture->ValidForTexture( - target, level, xoffset, yoffset, width, height, type)) { + target, level, xoffset, yoffset, 0, width, height, 1, type)) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions."); return false; } @@ -9073,7 +10152,8 @@ error::Error GLES2DecoderImpl::DoTexSubImage2D( Texture* texture = texture_ref->texture(); GLsizei tex_width = 0; GLsizei tex_height = 0; - bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height); + bool ok = texture->GetLevelSize( + target, level, &tex_width, &tex_height, nullptr); DCHECK(ok); if (xoffset != 0 || yoffset != 0 || width != tex_width || height != tex_height) { @@ -9090,7 +10170,8 @@ error::Error GLES2DecoderImpl::DoTexSubImage2D( } if (!texture_state_.texsubimage2d_faster_than_teximage2d && - !texture->IsImmutable()) { + !texture->IsImmutable() && + !texture->HasImages()) { ScopedTextureUploadTimer timer(&texture_state_); GLenum internal_format; GLenum tex_type; @@ -9132,7 +10213,7 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size, GLenum type = static_cast<GLenum>(c.type); uint32 data_size; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, state_.unpack_alignment, &data_size, + width, height, 1, format, type, state_.unpack_alignment, &data_size, NULL, NULL)) { return error::kOutOfBounds; } @@ -9142,6 +10223,39 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size, target, level, xoffset, yoffset, width, height, format, type, pixels); } +error::Error GLES2DecoderImpl::HandleTexSubImage3D(uint32 immediate_data_size, + const void* cmd_data) { + // TODO(zmo): Unsafe ES3 API. + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + + const gles2::cmds::TexSubImage3D& c = + *static_cast<const gles2::cmds::TexSubImage3D*>(cmd_data); + TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage3D", + "widthXheight", c.width * c.height, "depth", c.depth); + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + GLint zoffset = static_cast<GLint>(c.zoffset); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLsizei depth = static_cast<GLsizei>(c.depth); + GLenum format = static_cast<GLenum>(c.format); + GLenum type = static_cast<GLenum>(c.type); + uint32 data_size; + if (!GLES2Util::ComputeImageDataSizes( + width, height, depth, format, type, state_.unpack_alignment, &data_size, + NULL, NULL)) { + return error::kOutOfBounds; + } + const void* pixels = GetSharedMemoryAs<const void*>( + c.pixels_shm_id, c.pixels_shm_offset, data_size); + glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, + depth, format, type, pixels); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv( uint32 immediate_data_size, const void* cmd_data) { @@ -9175,21 +10289,28 @@ error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv( return error::kNoError; } -bool GLES2DecoderImpl::GetUniformSetup( - GLuint program_id, GLint fake_location, - uint32 shm_id, uint32 shm_offset, - error::Error* error, GLint* real_location, - GLuint* service_id, void** result_pointer, GLenum* result_type) { +template <class T> +bool GLES2DecoderImpl::GetUniformSetup(GLuint program_id, + GLint fake_location, + uint32 shm_id, + uint32 shm_offset, + error::Error* error, + GLint* real_location, + GLuint* service_id, + SizedResult<T>** result_pointer, + GLenum* result_type, + GLsizei* result_size) { DCHECK(error); DCHECK(service_id); DCHECK(result_pointer); DCHECK(result_type); + DCHECK(result_size); DCHECK(real_location); *error = error::kNoError; // Make sure we have enough room for the result on failure. - SizedResult<GLint>* result; - result = GetSharedMemoryAs<SizedResult<GLint>*>( - shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0)); + SizedResult<T>* result; + result = GetSharedMemoryAs<SizedResult<T>*>( + shm_id, shm_offset, SizedResult<T>::ComputeSize(0)); if (!result) { *error = error::kOutOfBounds; return false; @@ -9219,18 +10340,19 @@ bool GLES2DecoderImpl::GetUniformSetup( return false; } GLenum type = uniform_info->type; - GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type); - if (size == 0) { + uint32 num_elements = GLES2Util::GetElementCountForUniformType(type); + if (num_elements == 0) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type"); return false; } - result = GetSharedMemoryAs<SizedResult<GLint>*>( - shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size)); + result = GetSharedMemoryAs<SizedResult<T>*>( + shm_id, shm_offset, SizedResult<T>::ComputeSize(num_elements)); if (!result) { *error = error::kOutOfBounds; return false; } - result->size = size; + result->SetNumResults(num_elements); + *result_size = num_elements * sizeof(T); *result_type = type; return true; } @@ -9243,15 +10365,41 @@ error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size, GLint fake_location = c.location; GLuint service_id; GLenum result_type; + GLsizei result_size; GLint real_location = -1; Error error; - void* result; - if (GetUniformSetup( - program, fake_location, c.params_shm_id, c.params_shm_offset, - &error, &real_location, &service_id, &result, &result_type)) { + cmds::GetUniformiv::Result* result; + if (GetUniformSetup<GLint>(program, fake_location, c.params_shm_id, + c.params_shm_offset, &error, &real_location, + &service_id, &result, &result_type, + &result_size)) { glGetUniformiv( - service_id, real_location, - static_cast<cmds::GetUniformiv::Result*>(result)->GetData()); + service_id, real_location, result->GetData()); + } + return error; +} + +error::Error GLES2DecoderImpl::HandleGetUniformuiv(uint32 immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + + const gles2::cmds::GetUniformuiv& c = + *static_cast<const gles2::cmds::GetUniformuiv*>(cmd_data); + GLuint program = c.program; + GLint fake_location = c.location; + GLuint service_id; + GLenum result_type; + GLsizei result_size; + GLint real_location = -1; + Error error; + cmds::GetUniformuiv::Result* result; + if (GetUniformSetup<GLuint>(program, fake_location, c.params_shm_id, + c.params_shm_offset, &error, &real_location, + &service_id, &result, &result_type, + &result_size)) { + glGetUniformuiv( + service_id, real_location, result->GetData()); } return error; } @@ -9265,16 +10413,16 @@ error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size, GLuint service_id; GLint real_location = -1; Error error; - typedef cmds::GetUniformfv::Result Result; - Result* result; + cmds::GetUniformfv::Result* result; GLenum result_type; - if (GetUniformSetup( - program, fake_location, c.params_shm_id, c.params_shm_offset, - &error, &real_location, &service_id, - reinterpret_cast<void**>(&result), &result_type)) { + GLsizei result_size; + if (GetUniformSetup<GLfloat>(program, fake_location, c.params_shm_id, + c.params_shm_offset, &error, &real_location, + &service_id, &result, &result_type, + &result_size)) { if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 || result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) { - GLsizei num_values = result->GetNumResults(); + GLsizei num_values = result_size / sizeof(GLfloat); scoped_ptr<GLint[]> temp(new GLint[num_values]); glGetUniformiv(service_id, real_location, temp.get()); GLfloat* dst = result->GetData(); @@ -9404,6 +10552,165 @@ error::Error GLES2DecoderImpl::HandleGetActiveUniform( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockiv( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetActiveUniformBlockiv& c = + *static_cast<const gles2::cmds::GetActiveUniformBlockiv*>(cmd_data); + GLuint program_id = c.program; + GLuint index = static_cast<GLuint>(c.index); + GLenum pname = static_cast<GLenum>(c.pname); + Program* program = GetProgramInfoNotShader( + program_id, "glGetActiveUniformBlockiv"); + if (!program) { + return error::kNoError; + } + GLuint service_id = program->service_id(); + GLint link_status = GL_FALSE; + glGetProgramiv(service_id, GL_LINK_STATUS, &link_status); + if (link_status != GL_TRUE) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glGetActiveActiveUniformBlockiv", "program not linked"); + return error::kNoError; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformBlockiv"); + GLsizei num_values = 1; + if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) { + GLint num = 0; + glGetActiveUniformBlockiv( + service_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &num); + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + // Assume this will the same error if calling with pname. + LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", ""); + return error::kNoError; + } + num_values = static_cast<GLsizei>(num); + } + typedef cmds::GetActiveUniformBlockiv::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); + GLint* params = result ? result->GetData() : NULL; + if (params == NULL) { + return error::kOutOfBounds; + } + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + glGetActiveUniformBlockiv(service_id, index, pname, params); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(num_values); + } else { + LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", ""); + } + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockName( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetActiveUniformBlockName& c = + *static_cast<const gles2::cmds::GetActiveUniformBlockName*>(cmd_data); + GLuint program_id = c.program; + GLuint index = c.index; + uint32 name_bucket_id = c.name_bucket_id; + typedef cmds::GetActiveUniformBlockName::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result)); + if (!result) { + return error::kOutOfBounds; + } + // Check that the client initialized the result. + if (*result != 0) { + return error::kInvalidArguments; + } + Program* program = GetProgramInfoNotShader( + program_id, "glGetActiveUniformBlockName"); + if (!program) { + return error::kNoError; + } + GLuint service_id = program->service_id(); + GLint link_status = GL_FALSE; + glGetProgramiv(service_id, GL_LINK_STATUS, &link_status); + if (link_status != GL_TRUE) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glGetActiveActiveUniformBlockName", "program not linked"); + return error::kNoError; + } + GLint max_length = 0; + glGetProgramiv( + service_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_length); + // Increase one so &buffer[0] is always valid. + GLsizei buf_size = static_cast<GLsizei>(max_length) + 1; + std::vector<char> buffer(buf_size); + GLsizei length = 0; + glGetActiveUniformBlockName( + service_id, index, buf_size, &length, &buffer[0]); + if (length == 0) { + *result = 0; + return error::kNoError; + } + *result = 1; + Bucket* bucket = CreateBucket(name_bucket_id); + DCHECK_GT(buf_size, length); + DCHECK_EQ(0, buffer[length]); + bucket->SetFromString(&buffer[0]); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleGetActiveUniformsiv( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetActiveUniformsiv& c = + *static_cast<const gles2::cmds::GetActiveUniformsiv*>(cmd_data); + GLuint program_id = c.program; + GLenum pname = static_cast<GLenum>(c.pname); + Bucket* bucket = GetBucket(c.indices_bucket_id); + if (!bucket) { + return error::kInvalidArguments; + } + GLsizei count = static_cast<GLsizei>(bucket->size() / sizeof(GLuint)); + const GLuint* indices = bucket->GetDataAs<const GLuint*>(0, bucket->size()); + typedef cmds::GetActiveUniformsiv::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.params_shm_id, c.params_shm_offset, Result::ComputeSize(count)); + GLint* params = result ? result->GetData() : NULL; + if (params == NULL) { + return error::kOutOfBounds; + } + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + Program* program = GetProgramInfoNotShader( + program_id, "glGetActiveUniformsiv"); + if (!program) { + return error::kNoError; + } + GLuint service_id = program->service_id(); + GLint link_status = GL_FALSE; + glGetProgramiv(service_id, GL_LINK_STATUS, &link_status); + if (link_status != GL_TRUE) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glGetActiveUniformsiv", "program not linked"); + return error::kNoError; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformsiv"); + glGetActiveUniformsiv(service_id, count, indices, pname, params); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(count); + } else { + LOCAL_SET_GL_ERROR(error, "GetActiveUniformsiv", ""); + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size, const void* cmd_data) { const gles2::cmds::GetActiveAttrib& c = @@ -9500,6 +10807,9 @@ void GLES2DecoderImpl::DoSwapBuffers() { TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame"); } + ScopedGPUTrace scoped_gpu_trace(gpu_tracer_.get(), kTraceDecoder, + "gpu_toplevel", "SwapBuffer"); + bool is_tracing; TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"), &is_tracing); @@ -9535,7 +10845,8 @@ void GLES2DecoderImpl::DoSwapBuffers() { GL_FRAMEBUFFER_COMPLETE) { LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " << "because offscreen saved FBO was incomplete."; - LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB); + MarkContextLost(error::kUnknown); + group_->LoseContexts(error::kUnknown); return; } @@ -9586,13 +10897,16 @@ void GLES2DecoderImpl::DoSwapBuffers() { // Ensure the side effects of the copy are visible to the parent // context. There is no need to do this for ANGLE because it uses a // single D3D device for all contexts. - if (!feature_info_->feature_flags().is_angle) + if (!feature_info_->gl_version_info().is_angle) glFlush(); } } else { if (!surface_->SwapBuffers()) { LOG(ERROR) << "Context lost because SwapBuffers failed."; - LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB); + if (!CheckResetStatus()) { + MarkContextLost(error::kUnknown); + group_->LoseContexts(error::kUnknown); + } } } @@ -9601,6 +10915,10 @@ void GLES2DecoderImpl::DoSwapBuffers() { ExitCommandProcessingEarly(); } +void GLES2DecoderImpl::DoSwapInterval(int interval) { + context_->SetSwapInterval(interval); +} + error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM( uint32 immediate_data_size, const void* cmd_data) { @@ -9629,7 +10947,7 @@ error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM( if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) { buffer_manager()->set_allow_buffers_on_multiple_targets(true); } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) { - buffer_manager()->set_allow_buffers_on_multiple_targets(true); + buffer_manager()->set_allow_fixed_attribs(true); // TODO(gman): decide how to remove the need for this const_cast. // I could make validators_ non const but that seems bad as this is the only // place it is needed. I could make some special friend class of validators @@ -9712,108 +11030,148 @@ error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM( return error::kNoError; } -error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM( +error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM( uint32 immediate_data_size, const void* cmd_data) { - const gles2::cmds::GetMultipleIntegervCHROMIUM& c = - *static_cast<const gles2::cmds::GetMultipleIntegervCHROMIUM*>(cmd_data); - GLuint count = c.count; - uint32 pnames_size; - if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) { - return error::kOutOfBounds; - } - const GLenum* pnames = GetSharedMemoryAs<const GLenum*>( - c.pnames_shm_id, c.pnames_shm_offset, pnames_size); - if (pnames == NULL) { - return error::kOutOfBounds; - } - - // We have to copy them since we use them twice so the client - // can't change them between the time we validate them and the time we use - // them. - scoped_ptr<GLenum[]> enums(new GLenum[count]); - memcpy(enums.get(), pnames, pnames_size); - - // Count up the space needed for the result. - uint32 num_results = 0; - for (GLuint ii = 0; ii < count; ++ii) { - uint32 num = util_.GLGetNumValuesReturned(enums[ii]); - if (num == 0) { - LOCAL_SET_GL_ERROR_INVALID_ENUM( - "glGetMultipleCHROMIUM", enums[ii], "pname"); - return error::kNoError; - } - // Num will never be more than 4. - DCHECK_LE(num, 4u); - if (!SafeAddUint32(num_results, num, &num_results)) { - return error::kOutOfBounds; - } + const gles2::cmds::GetProgramInfoCHROMIUM& c = + *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data); + GLuint program_id = static_cast<GLuint>(c.program); + uint32 bucket_id = c.bucket_id; + Bucket* bucket = CreateBucket(bucket_id); + bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail. + Program* program = NULL; + program = GetProgram(program_id); + if (!program || !program->IsValid()) { + return error::kNoError; } + program->GetProgramInfo(program_manager(), bucket); + return error::kNoError; +} - uint32 result_size = 0; - if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) { - return error::kOutOfBounds; +error::Error GLES2DecoderImpl::HandleGetUniformBlocksCHROMIUM( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetUniformBlocksCHROMIUM& c = + *static_cast<const gles2::cmds::GetUniformBlocksCHROMIUM*>(cmd_data); + GLuint program_id = static_cast<GLuint>(c.program); + uint32 bucket_id = c.bucket_id; + Bucket* bucket = CreateBucket(bucket_id); + bucket->SetSize(sizeof(UniformBlocksHeader)); // in case we fail. + Program* program = NULL; + program = GetProgram(program_id); + if (!program || !program->IsValid()) { + return error::kNoError; } + program->GetUniformBlocks(bucket); + return error::kNoError; +} - if (result_size != static_cast<uint32>(c.size)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, - "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE"); +error::Error GLES2DecoderImpl::HandleGetUniformsES3CHROMIUM( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetUniformsES3CHROMIUM& c = + *static_cast<const gles2::cmds::GetUniformsES3CHROMIUM*>(cmd_data); + GLuint program_id = static_cast<GLuint>(c.program); + uint32 bucket_id = c.bucket_id; + Bucket* bucket = CreateBucket(bucket_id); + bucket->SetSize(sizeof(UniformsES3Header)); // in case we fail. + Program* program = NULL; + program = GetProgram(program_id); + if (!program || !program->IsValid()) { return error::kNoError; } + program->GetUniformsES3(bucket); + return error::kNoError; +} - GLint* results = GetSharedMemoryAs<GLint*>( - c.results_shm_id, c.results_shm_offset, result_size); - if (results == NULL) { +error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVarying( + uint32 immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetTransformFeedbackVarying& c = + *static_cast<const gles2::cmds::GetTransformFeedbackVarying*>(cmd_data); + GLuint program_id = c.program; + GLuint index = c.index; + uint32 name_bucket_id = c.name_bucket_id; + typedef cmds::GetTransformFeedbackVarying::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result)); + if (!result) { return error::kOutOfBounds; } - - // Check the results have been cleared in case the context was lost. - for (uint32 ii = 0; ii < num_results; ++ii) { - if (results[ii]) { - return error::kInvalidArguments; - } + // Check that the client initialized the result. + if (result->success != 0) { + return error::kInvalidArguments; } - - // Get each result. - GLint* start = results; - for (GLuint ii = 0; ii < count; ++ii) { - GLsizei num_written = 0; - if (!state_.GetStateAsGLint(enums[ii], results, &num_written) && - !GetHelper(enums[ii], results, &num_written)) { - DoGetIntegerv(enums[ii], results); - } - results += num_written; + Program* program = GetProgramInfoNotShader( + program_id, "glGetTransformFeedbackVarying"); + if (!program) { + return error::kNoError; } - - // Just to verify. Should this be a DCHECK? - if (static_cast<uint32>(results - start) != num_results) { - return error::kOutOfBounds; + GLuint service_id = program->service_id(); + GLint link_status = GL_FALSE; + glGetProgramiv(service_id, GL_LINK_STATUS, &link_status); + if (link_status != GL_TRUE) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glGetTransformFeedbackVarying", "program not linked"); + return error::kNoError; } - + GLint max_length = 0; + glGetProgramiv( + service_id, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_length); + max_length = std::max(1, max_length); + std::vector<char> buffer(max_length); + GLsizei length = 0; + GLsizei size = 0; + GLenum type = 0; + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTransformFeedbackVarying"); + glGetTransformFeedbackVarying( + service_id, index, max_length, &length, &size, &type, &buffer[0]); + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + LOCAL_SET_GL_ERROR(error, "glGetTransformFeedbackVarying", ""); + return error::kNoError; + } + result->success = 1; // true. + result->size = static_cast<int32_t>(size); + result->type = static_cast<uint32_t>(type); + Bucket* bucket = CreateBucket(name_bucket_id); + DCHECK(length >= 0 && length < max_length); + buffer[length] = '\0'; // Just to be safe. + bucket->SetFromString(&buffer[0]); return error::kNoError; } -error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM( - uint32 immediate_data_size, - const void* cmd_data) { - const gles2::cmds::GetProgramInfoCHROMIUM& c = - *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data); +error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVaryingsCHROMIUM( + uint32 immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM& c = + *static_cast<const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM*>( + cmd_data); GLuint program_id = static_cast<GLuint>(c.program); uint32 bucket_id = c.bucket_id; Bucket* bucket = CreateBucket(bucket_id); - bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail. + bucket->SetSize(sizeof(TransformFeedbackVaryingsHeader)); // in case we fail. Program* program = NULL; program = GetProgram(program_id); if (!program || !program->IsValid()) { return error::kNoError; } - program->GetProgramInfo(program_manager(), bucket); + program->GetTransformFeedbackVaryings(bucket); return error::kNoError; } error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() { - switch (reset_status_) { + return context_lost_reason_; +} + +error::ContextLostReason GLES2DecoderImpl::GetContextLostReasonFromResetStatus( + GLenum reset_status) const { + switch (reset_status) { case GL_NO_ERROR: // TODO(kbr): improve the precision of the error code in this case. // Consider delegating to context for error code if MakeCurrent fails. @@ -9830,72 +11188,72 @@ error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() { return error::kUnknown; } -void GLES2DecoderImpl::MaybeExitOnContextLost() { - // Some D3D drivers cannot recover from device lost in the GPU process - // sandbox. Allow a new GPU process to launch. - if (workarounds().exit_on_context_lost) { - LOG(ERROR) << "Exiting GPU process because some drivers cannot reset" - << " a D3D device in the Chrome GPU process sandbox."; -#if defined(OS_WIN) - base::win::SetShouldCrashOnProcessDetach(false); -#endif - exit(0); - } +bool GLES2DecoderImpl::WasContextLost() const { + return context_was_lost_; } -bool GLES2DecoderImpl::WasContextLost() { - if (reset_status_ != GL_NO_ERROR) { - MaybeExitOnContextLost(); - return true; - } - if (context_->WasAllocatedUsingRobustnessExtension()) { - GLenum status = GL_NO_ERROR; - if (has_robustness_extension_) - status = glGetGraphicsResetStatusARB(); - if (status != GL_NO_ERROR) { - // The graphics card was reset. Signal a lost context to the application. - reset_status_ = status; - reset_by_robustness_extension_ = true; - LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen") - << " context lost via ARB/EXT_robustness. Reset status = " - << GLES2Util::GetStringEnum(status); - MaybeExitOnContextLost(); - return true; - } - } - return false; -} - -bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() { +bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() const { return WasContextLost() && reset_by_robustness_extension_; } -void GLES2DecoderImpl::LoseContext(uint32 reset_status) { - // Only loses the context once. - if (reset_status_ != GL_NO_ERROR) { +void GLES2DecoderImpl::MarkContextLost(error::ContextLostReason reason) { + // Only lose the context once. + if (WasContextLost()) return; + + // Don't make GL calls in here, the context might not be current. + context_lost_reason_ = reason; + current_decoder_error_ = error::kLostContext; + context_was_lost_ = true; + + // Work around issues with recovery by allowing a new GPU process to launch. + if (workarounds().exit_on_context_lost && allow_exit_) { + LOG(ERROR) << "Exiting GPU process because some drivers cannot recover" + << " from problems."; +#if defined(OS_WIN) + base::win::SetShouldCrashOnProcessDetach(false); +#endif + exit(0); } +} - if (workarounds().use_virtualized_gl_contexts) { - // If the context is virtual, the real context being guilty does not ensure - // that the virtual context is guilty. - if (reset_status == GL_GUILTY_CONTEXT_RESET_ARB) { - reset_status = GL_UNKNOWN_CONTEXT_RESET_ARB; - } - } else if (reset_status == GL_UNKNOWN_CONTEXT_RESET_ARB && - has_robustness_extension_) { +bool GLES2DecoderImpl::CheckResetStatus() { + DCHECK(!WasContextLost()); + DCHECK(context_->IsCurrent(NULL)); + + if (IsRobustnessSupported()) { // If the reason for the call was a GL error, we can try to determine the // reset status more accurately. GLenum driver_status = glGetGraphicsResetStatusARB(); - if (driver_status == GL_GUILTY_CONTEXT_RESET_ARB || - driver_status == GL_INNOCENT_CONTEXT_RESET_ARB) { - reset_status = driver_status; + if (driver_status == GL_NO_ERROR) + return false; + + LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen") + << " context lost via ARB/EXT_robustness. Reset status = " + << GLES2Util::GetStringEnum(driver_status); + + // Don't pretend we know which client was responsible. + if (workarounds().use_virtualized_gl_contexts) + driver_status = GL_UNKNOWN_CONTEXT_RESET_ARB; + + switch (driver_status) { + case GL_GUILTY_CONTEXT_RESET_ARB: + MarkContextLost(error::kGuilty); + break; + case GL_INNOCENT_CONTEXT_RESET_ARB: + MarkContextLost(error::kInnocent); + break; + case GL_UNKNOWN_CONTEXT_RESET_ARB: + MarkContextLost(error::kUnknown); + break; + default: + NOTREACHED(); + return false; } + reset_by_robustness_extension_ = true; + return true; } - - // Marks this context as lost. - reset_status_ = reset_status; - current_decoder_error_ = error::kLostContext; + return false; } error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM( @@ -10336,40 +11694,78 @@ static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) { } } -void GLES2DecoderImpl::DoCopyTextureCHROMIUM( - GLenum target, GLuint source_id, GLuint dest_id, GLint level, - GLenum internal_format, GLenum dest_type) { - TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM"); - - TextureRef* dest_texture_ref = GetTexture(dest_id); - TextureRef* source_texture_ref = GetTexture(source_id); - +bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUM( + const char* function_name, + GLenum target, + TextureRef* source_texture_ref, + TextureRef* dest_texture_ref, + GLenum dest_internal_format) { if (!source_texture_ref || !dest_texture_ref) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id"); - return; + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown texture id"); + return false; } if (GL_TEXTURE_2D != target) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target"); - return; + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, + "invalid texture target"); + return false; } Texture* source_texture = source_texture_ref->texture(); Texture* dest_texture = dest_texture_ref->texture(); + if (source_texture == dest_texture) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, + "source and destination textures are the same"); + return false; + } + if (dest_texture->target() != GL_TEXTURE_2D || (source_texture->target() != GL_TEXTURE_2D && source_texture->target() != GL_TEXTURE_RECTANGLE_ARB && source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, - "glCopyTextureCHROMIUM", + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid texture target binding"); - return; + return false; } - int source_width, source_height, dest_width, dest_height; + GLenum source_type = 0; + GLenum source_internal_format = 0; + source_texture->GetLevelType(source_texture->target(), 0, &source_type, + &source_internal_format); + + // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA, + // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not + // renderable on some platforms. + bool valid_dest_format = dest_internal_format == GL_RGB || + dest_internal_format == GL_RGBA || + dest_internal_format == GL_BGRA_EXT; + bool valid_source_format = source_internal_format == GL_ALPHA || + source_internal_format == GL_RGB || + source_internal_format == GL_RGBA || + source_internal_format == GL_LUMINANCE || + source_internal_format == GL_LUMINANCE_ALPHA || + source_internal_format == GL_BGRA_EXT; + if (!valid_source_format || !valid_dest_format) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, + "invalid internal format"); + return false; + } + return true; +} +void GLES2DecoderImpl::DoCopyTextureCHROMIUM(GLenum target, + GLuint source_id, + GLuint dest_id, + GLenum internal_format, + GLenum dest_type) { + TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM"); + + TextureRef* source_texture_ref = GetTexture(source_id); + TextureRef* dest_texture_ref = GetTexture(dest_id); + Texture* source_texture = source_texture_ref->texture(); + Texture* dest_texture = dest_texture_ref->texture(); + int source_width = 0; + int source_height = 0; gfx::GLImage* image = source_texture->GetLevelImage(source_texture->target(), 0); if (image) { @@ -10383,8 +11779,8 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( return; } } else { - if (!source_texture->GetLevelSize( - source_texture->target(), 0, &source_width, &source_height)) { + if (!source_texture->GetLevelSize(source_texture->target(), 0, + &source_width, &source_height, nullptr)) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyTextureChromium", "source texture has no level 0"); @@ -10392,43 +11788,36 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( } // Check that this type of texture is allowed. - if (!texture_manager()->ValidForTarget( - source_texture->target(), level, source_width, source_height, 1)) { + if (!texture_manager()->ValidForTarget(source_texture->target(), 0, + source_width, source_height, 1)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions"); return; } } - // Clear the source texture if necessary. - if (!texture_manager()->ClearTextureLevel( - this, source_texture_ref, source_texture->target(), 0)) { - LOCAL_SET_GL_ERROR( - GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big"); - return; - } - GLenum source_type = 0; GLenum source_internal_format = 0; source_texture->GetLevelType( source_texture->target(), 0, &source_type, &source_internal_format); - // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA, - // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not - // renderable on some platforms. - bool valid_dest_format = internal_format == GL_RGB || - internal_format == GL_RGBA || - internal_format == GL_BGRA_EXT; - bool valid_source_format = source_internal_format == GL_ALPHA || - source_internal_format == GL_RGB || - source_internal_format == GL_RGBA || - source_internal_format == GL_LUMINANCE || - source_internal_format == GL_LUMINANCE_ALPHA || - source_internal_format == GL_BGRA_EXT; - if (!valid_source_format || !valid_dest_format) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, - "glCopyTextureCHROMIUM", - "invalid internal format"); + if (dest_texture->IsImmutable()) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyTextureCHROMIUM", + "texture is immutable"); + return; + } + + if (!ValidateCopyTextureCHROMIUM("glCopyTextureCHROMIUM", target, + source_texture_ref, dest_texture_ref, + internal_format)) { + return; + } + + // Clear the source texture if necessary. + if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, + source_texture->target(), 0)) { + LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", + "dimensions too big"); return; } @@ -10445,11 +11834,13 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( GLenum dest_type_previous = dest_type; GLenum dest_internal_format = internal_format; + int dest_width = 0; + int dest_height = 0; bool dest_level_defined = dest_texture->GetLevelSize( - GL_TEXTURE_2D, level, &dest_width, &dest_height); + GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr); if (dest_level_defined) { - dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous, + dest_texture->GetLevelType(GL_TEXTURE_2D, 0, &dest_type_previous, &dest_internal_format); } @@ -10461,9 +11852,8 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( // Ensure that the glTexImage2D succeeds. LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM"); glBindTexture(GL_TEXTURE_2D, dest_texture->service_id()); - glTexImage2D( - GL_TEXTURE_2D, level, internal_format, source_width, source_height, - 0, internal_format, dest_type, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, internal_format, source_width, source_height, + 0, internal_format, dest_type, NULL); GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM"); if (error != GL_NO_ERROR) { RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D); @@ -10471,11 +11861,11 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( } texture_manager()->SetLevelInfo( - dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width, + dest_texture_ref, GL_TEXTURE_2D, 0, internal_format, source_width, source_height, 1, 0, internal_format, dest_type, true); } else { - texture_manager()->SetLevelCleared( - dest_texture_ref, GL_TEXTURE_2D, level, true); + texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0, + true); } ScopedModifyPixels modify(dest_texture_ref); @@ -10483,7 +11873,7 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( // Try using GLImage::CopyTexImage when possible. bool unpack_premultiply_alpha_change = unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_; - if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) { + if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change) { glBindTexture(GL_TEXTURE_2D, dest_texture->service_id()); if (image->CopyTexImage(GL_TEXTURE_2D)) return; @@ -10495,36 +11885,159 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( // before presenting. if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { // TODO(hkuang): get the StreamTexture transform matrix in GPU process - // instead of using default matrix crbug.com/226218. - const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f}; + // instead of using kIdentityMatrix crbug.com/226218. copy_texture_CHROMIUM_->DoCopyTextureWithTransform( - this, - source_texture->target(), - source_texture->service_id(), - dest_texture->service_id(), - level, - source_width, - source_height, - unpack_flip_y_, - unpack_premultiply_alpha_, - unpack_unpremultiply_alpha_, - default_matrix); + this, source_texture->target(), source_texture->service_id(), + dest_texture->service_id(), source_width, source_height, unpack_flip_y_, + unpack_premultiply_alpha_, unpack_unpremultiply_alpha_, + kIdentityMatrix); + } else { + copy_texture_CHROMIUM_->DoCopyTexture( + this, source_texture->target(), source_texture->service_id(), + source_internal_format, dest_texture->service_id(), internal_format, + source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_, + unpack_unpremultiply_alpha_); + } + + DoDidUseTexImageIfNeeded(source_texture, source_texture->target()); +} + +void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(GLenum target, + GLuint source_id, + GLuint dest_id, + GLint xoffset, + GLint yoffset) { + TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM"); + + TextureRef* source_texture_ref = GetTexture(source_id); + TextureRef* dest_texture_ref = GetTexture(dest_id); + Texture* source_texture = source_texture_ref->texture(); + Texture* dest_texture = dest_texture_ref->texture(); + int source_width = 0; + int source_height = 0; + gfx::GLImage* image = + source_texture->GetLevelImage(source_texture->target(), 0); + if (image) { + gfx::Size size = image->GetSize(); + source_width = size.width(); + source_height = size.height(); + if (source_width <= 0 || source_height <= 0) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM", + "invalid image size"); + return; + } } else { - copy_texture_CHROMIUM_->DoCopyTexture(this, - source_texture->target(), - source_texture->service_id(), - source_internal_format, - dest_texture->service_id(), - level, - internal_format, - source_width, - source_height, - unpack_flip_y_, - unpack_premultiply_alpha_, - unpack_unpremultiply_alpha_); + if (!source_texture->GetLevelSize(source_texture->target(), 0, + &source_width, &source_height, nullptr)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM", + "source texture has no level 0"); + return; + } + + // Check that this type of texture is allowed. + if (!texture_manager()->ValidForTarget(source_texture->target(), 0, + source_width, source_height, 1)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM", + "source texture bad dimensions"); + return; + } + } + + GLenum source_type = 0; + GLenum source_internal_format = 0; + source_texture->GetLevelType(source_texture->target(), 0, &source_type, + &source_internal_format); + GLenum dest_type = 0; + GLenum dest_internal_format = 0; + bool dest_level_defined = dest_texture->GetLevelType( + dest_texture->target(), 0, &dest_type, &dest_internal_format); + if (!dest_level_defined) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopySubTextureCHROMIUM", + "destination texture is not defined"); + return; + } + if (!dest_texture->ValidForTexture(dest_texture->target(), 0, xoffset, + yoffset, 0, source_width, source_height, + 1, dest_type)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM", + "destination texture bad dimensions."); + return; + } + + if (!ValidateCopyTextureCHROMIUM("glCopySubTextureCHROMIUM", target, + source_texture_ref, dest_texture_ref, + dest_internal_format)) { + return; + } + + // Clear the source texture if necessary. + if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, + source_texture->target(), 0)) { + LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM", + "source texture dimensions too big"); + return; + } + + // Defer initializing the CopyTextureCHROMIUMResourceManager until it is + // needed because it takes 10s of milliseconds to initialize. + if (!copy_texture_CHROMIUM_.get()) { + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopySubTextureCHROMIUM"); + copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); + copy_texture_CHROMIUM_->Initialize(this); + RestoreCurrentFramebufferBindings(); + if (LOCAL_PEEK_GL_ERROR("glCopySubTextureCHROMIUM") != GL_NO_ERROR) + return; + } + + int dest_width = 0; + int dest_height = 0; + bool ok = dest_texture->GetLevelSize( + GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr); + DCHECK(ok); + if (xoffset != 0 || yoffset != 0 || source_width != dest_width || + source_height != dest_height) { + if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target, + 0)) { + LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM", + "destination texture dimensions too big"); + return; + } + } else { + texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0, + true); + } + + ScopedModifyPixels modify(dest_texture_ref); + + // Try using GLImage::CopyTexSubImage when possible. + bool unpack_premultiply_alpha_change = + unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_; + if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && + !xoffset && !yoffset) { + glBindTexture(GL_TEXTURE_2D, dest_texture->service_id()); + if (image->CopyTexImage(GL_TEXTURE_2D)) + return; + } + + DoWillUseTexImageIfNeeded(source_texture, source_texture->target()); + + // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix + // before presenting. + if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { + // TODO(hkuang): get the StreamTexture transform matrix in GPU process + // instead of using kIdentityMatrix crbug.com/226218. + copy_texture_CHROMIUM_->DoCopySubTextureWithTransform( + this, source_texture->target(), source_texture->service_id(), + dest_texture->service_id(), xoffset, yoffset, dest_width, dest_height, + source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_, + unpack_unpremultiply_alpha_, kIdentityMatrix); + } else { + copy_texture_CHROMIUM_->DoCopySubTexture( + this, source_texture->target(), source_texture->service_id(), + source_internal_format, dest_texture->service_id(), + dest_internal_format, xoffset, yoffset, dest_width, dest_height, + source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_, + unpack_unpremultiply_alpha_); } DoDidUseTexImageIfNeeded(source_texture, source_texture->target()); @@ -10618,7 +12131,7 @@ void GLES2DecoderImpl::DoTexStorage2DEXT( for (int ii = 0; ii < levels; ++ii) { uint32 level_size = 0; if (!GLES2Util::ComputeImageDataSizes( - level_width, level_height, format, type, state_.unpack_alignment, + level_width, level_height, 1, format, type, state_.unpack_alignment, &estimated_size, NULL, NULL) || !SafeAddUint32(estimated_size, level_size, &estimated_size)) { LOCAL_SET_GL_ERROR( @@ -10772,6 +12285,24 @@ void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target, } } +void GLES2DecoderImpl::EnsureTextureForClientId( + GLenum target, + GLuint client_id) { + TextureRef* texture_ref = GetTexture(client_id); + if (!texture_ref) { + GLuint service_id; + glGenTextures(1, &service_id); + DCHECK_NE(0u, service_id); + texture_ref = CreateTexture(client_id, service_id); + texture_manager()->SetTarget(texture_ref, target); + glBindTexture(target, service_id); + RestoreCurrentTextureBindings(&state_, target); + } +} + +// If CreateAndConsumeTexture fails we still need to ensure that the client_id +// provided is associated with a service_id/TextureRef for consistency, even if +// the resulting texture is incomplete. error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate( uint32_t immediate_data_size, const void* cmd_data) { @@ -10814,6 +12345,8 @@ void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target, TextureRef* texture_ref = GetTexture(client_id); if (texture_ref) { + // No need to call EnsureTextureForClientId here, the client_id already has + // an associated texture. LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, "glCreateAndConsumeTextureCHROMIUM", "client id already in use"); @@ -10821,12 +12354,15 @@ void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target, } Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox); if (!texture) { + EnsureTextureForClientId(target, client_id); LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name"); return; } + if (texture->target() != target) { + EnsureTextureForClientId(target, client_id); LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, "glCreateAndConsumeTextureCHROMIUM", "invalid target"); @@ -10919,7 +12455,8 @@ void GLES2DecoderImpl::DoPushGroupMarkerEXT( } std::string name = length ? std::string(marker, length) : std::string(marker); debug_marker_manager_.PushGroup(name); - gpu_tracer_->Begin(name, kTraceGroupMarker); + gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_group_marker"), name, + kTraceGroupMarker); } void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) { @@ -11018,16 +12555,21 @@ error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM( const void* cmd_data) { const gles2::cmds::TraceBeginCHROMIUM& c = *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data); - Bucket* bucket = GetBucket(c.bucket_id); - if (!bucket || bucket->size() == 0) { + Bucket* category_bucket = GetBucket(c.category_bucket_id); + Bucket* name_bucket = GetBucket(c.name_bucket_id); + if (!category_bucket || category_bucket->size() == 0 || + !name_bucket || name_bucket->size() == 0) { return error::kInvalidArguments; } - std::string command_name; - if (!bucket->GetAsString(&command_name)) { + + std::string category_name; + std::string trace_name; + if (!category_bucket->GetAsString(&category_name) || + !name_bucket->GetAsString(&trace_name)) { return error::kInvalidArguments; } - TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this); - if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) { + + if (!gpu_tracer_->Begin(category_name, trace_name, kTraceCHROMIUM)) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, "glTraceBeginCHROMIUM", "unable to create begin trace"); @@ -11037,14 +12579,11 @@ error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM( } void GLES2DecoderImpl::DoTraceEndCHROMIUM() { - if (gpu_tracer_->CurrentName().empty()) { - LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glTraceEndCHROMIUM", "no trace begin found"); + if (!gpu_tracer_->End(kTraceCHROMIUM)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glTraceEndCHROMIUM", "no trace begin found"); return; } - TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this); - gpu_tracer_->End(kTraceCHROMIUM); } void GLES2DecoderImpl::DoDrawBuffersEXT( @@ -11090,9 +12629,9 @@ void GLES2DecoderImpl::DoDrawBuffersEXT( } void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) { - group_->LoseContexts(other); - reset_status_ = current; - current_decoder_error_ = error::kLostContext; + MarkContextLost(GetContextLostReasonFromResetStatus(current)); + group_->LoseContexts(GetContextLostReasonFromResetStatus(other)); + reset_by_robustness_extension_ = true; } void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode, @@ -11126,10 +12665,6 @@ void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) { return; } - static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f}; - GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM ? state_.projection_matrix : state_.modelview_matrix; @@ -11230,8 +12765,8 @@ error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( // TODO(epenner): Move this and copies of this memory validation // into ValidateTexImage2D step. if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, - NULL)) { + width, height, 1, format, type, state_.unpack_alignment, &pixels_size, + NULL, NULL)) { return error::kOutOfBounds; } const void* pixels = NULL; @@ -11335,7 +12870,7 @@ error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( // into ValidateTexSubImage2D step. uint32 data_size; if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, state_.unpack_alignment, &data_size, + width, height, 1, format, type, state_.unpack_alignment, &data_size, NULL, NULL)) { return error::kOutOfBounds; } @@ -11386,10 +12921,10 @@ error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( // (the texture should have been async defined). AsyncTexImage2DParams define_params = {target, level, 0, 0, 0, 0, 0, 0}; - texture->GetLevelSize(target, level, &define_params.width, - &define_params.height); - texture->GetLevelType(target, level, &define_params.type, - &define_params.internal_format); + texture->GetLevelSize( + target, level, &define_params.width, &define_params.height, nullptr); + texture->GetLevelType( + target, level, &define_params.type, &define_params.internal_format); // Set up the async state if needed, and make the texture // immutable so the async state stays valid. delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate( @@ -11445,19 +12980,210 @@ error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleUniformBlockBinding( + uint32_t immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::UniformBlockBinding& c = + *static_cast<const gles2::cmds::UniformBlockBinding*>(cmd_data); + GLuint client_id = c.program; + GLuint index = static_cast<GLuint>(c.index); + GLuint binding = static_cast<GLuint>(c.binding); + Program* program = GetProgramInfoNotShader( + client_id, "glUniformBlockBinding"); + if (!program) { + return error::kNoError; + } + GLuint service_id = program->service_id(); + glUniformBlockBinding(service_id, index, binding); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleClientWaitSync( + uint32_t immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::ClientWaitSync& c = + *static_cast<const gles2::cmds::ClientWaitSync*>(cmd_data); + GLuint sync = static_cast<GLuint>(c.sync); + GLbitfield flags = static_cast<GLbitfield>(c.flags); + GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1); + typedef cmds::ClientWaitSync::Result Result; + Result* result_dst = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + if (!result_dst) { + return error::kOutOfBounds; + } + if (*result_dst != GL_WAIT_FAILED) { + return error::kInvalidArguments; + } + GLsync service_sync = 0; + if (!group_->GetSyncServiceId(sync, &service_sync)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "ClientWaitSync", "invalid sync"); + return error::kNoError; + } + *result_dst = glClientWaitSync(service_sync, flags, timeout); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleWaitSync( + uint32_t immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::WaitSync& c = + *static_cast<const gles2::cmds::WaitSync*>(cmd_data); + GLuint sync = static_cast<GLuint>(c.sync); + GLbitfield flags = static_cast<GLbitfield>(c.flags); + GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1); + GLsync service_sync = 0; + if (!group_->GetSyncServiceId(sync, &service_sync)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "WaitSync", "invalid sync"); + return error::kNoError; + } + glWaitSync(service_sync, flags, timeout); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleMapBufferRange( + uint32_t immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) { + return error::kUnknownCommand; + } + const gles2::cmds::MapBufferRange& c = + *static_cast<const gles2::cmds::MapBufferRange*>(cmd_data); + GLenum target = static_cast<GLenum>(c.target); + GLbitfield access = static_cast<GLbitfield>(c.access); + GLintptr offset = static_cast<GLintptr>(c.offset); + GLsizeiptr size = static_cast<GLsizeiptr>(c.size); + + typedef cmds::MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result)); + if (!result) { + return error::kOutOfBounds; + } + if (*result != 0) { + *result = 0; + return error::kInvalidArguments; + } + int8_t* mem = + GetSharedMemoryAs<int8_t*>(c.data_shm_id, c.data_shm_offset, size); + if (!mem) { + return error::kOutOfBounds; + } + + GLbitfield mask = GL_MAP_INVALIDATE_BUFFER_BIT; + if ((access & mask) == mask) { + // TODO(zmo): To be on the safe side, always map + // GL_MAP_INVALIDATE_BUFFER_BIT to GL_MAP_INVALIDATE_RANGE_BIT. + access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT); + access = (access | GL_MAP_INVALIDATE_RANGE_BIT); + } + // TODO(zmo): Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of + // undefined behaviors. + mask = GL_MAP_READ_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + if ((access & mask) == mask) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "MapBufferRange", + "incompatible access bits"); + return error::kNoError; + } + access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT); + if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT && + (access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { + access = (access | GL_MAP_READ_BIT); + } + void* ptr = glMapBufferRange(target, offset, size, access); + if (ptr == nullptr) { + return error::kNoError; + } + Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); + DCHECK(buffer); + buffer->SetMappedRange(offset, size, access, ptr, + GetSharedMemoryBuffer(c.data_shm_id)); + if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { + memcpy(mem, ptr, size); + } + *result = 1; + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleUnmapBuffer( + uint32_t immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) { + return error::kUnknownCommand; + } + const gles2::cmds::UnmapBuffer& c = + *static_cast<const gles2::cmds::UnmapBuffer*>(cmd_data); + GLenum target = static_cast<GLenum>(c.target); + + Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); + if (!buffer) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", "no buffer bound"); + return error::kNoError; + } + const Buffer::MappedRange* mapped_range = buffer->GetMappedRange(); + if (!mapped_range) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", + "buffer is unmapped"); + return error::kNoError; + } + if ((mapped_range->access & GL_MAP_WRITE_BIT) == 0 || + (mapped_range->access & GL_MAP_FLUSH_EXPLICIT_BIT) == + GL_MAP_FLUSH_EXPLICIT_BIT) { + // If we don't need to write back, or explict flush is required, no copying + // back is needed. + } else { + void* mem = mapped_range->GetShmPointer(); + if (!mem) { + return error::kOutOfBounds; + } + DCHECK(mapped_range->pointer); + memcpy(mapped_range->pointer, mem, mapped_range->size); + } + buffer->RemoveMappedRange(); + GLboolean rt = glUnmapBuffer(target); + if (rt == GL_FALSE) { + // At this point, we have already done the necessary validation, so + // GL_FALSE indicates data corruption. + // TODO(zmo): We could redo the map / copy data / unmap to recover, but + // the second unmap could still return GL_FALSE. For now, we simply lose + // the contexts in the share group. + LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE"; + // Need to lose current context before broadcasting! + MarkContextLost(error::kGuilty); + group_->LoseContexts(error::kInnocent); + return error::kLostContext; + } + return error::kNoError; +} + void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer( TextureRef* texture_ref) { Texture* texture = texture_ref->texture(); DoDidUseTexImageIfNeeded(texture, texture->target()); } +// Note that GL_LOST_CONTEXT is specific to GLES. +// For desktop GL we have to query the reset status proactively. void GLES2DecoderImpl::OnContextLostError() { - group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB); + if (!WasContextLost()) { + // Need to lose current context before broadcasting! + CheckResetStatus(); + group_->LoseContexts(error::kUnknown); + reset_by_robustness_extension_ = true; + } } void GLES2DecoderImpl::OnOutOfMemoryError() { - if (lose_context_when_out_of_memory_) { - group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB); + if (lose_context_when_out_of_memory_ && !WasContextLost()) { + error::ContextLostReason other = error::kOutOfMemory; + if (CheckResetStatus()) { + other = error::kUnknown; + } else { + // Need to lose current context before broadcasting! + MarkContextLost(error::kOutOfMemory); + } + group_->LoseContexts(other); } } diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h index 63618c2a2da..3fc86237978 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -16,7 +16,7 @@ #include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/service/common_decoder.h" #include "gpu/command_buffer/service/logger.h" -#include "ui/gfx/size.h" +#include "ui/gfx/geometry/size.h" #include "ui/gl/gl_context.h" namespace gfx { @@ -38,7 +38,9 @@ class GLES2Util; class ImageManager; class Logger; class QueryManager; +class Texture; class VertexArrayManager; +class ValuebufferManager; struct ContextState; struct DisallowedFeatures { @@ -78,6 +80,14 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, initialized_ = true; } + bool unsafe_es3_apis_enabled() const { + return unsafe_es3_apis_enabled_; + } + + void set_unsafe_es3_apis_enabled(bool enabled) { + unsafe_es3_apis_enabled_ = enabled; + } + bool debug() const { return debug_; } @@ -105,13 +115,13 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, // offscreen: whether to make the context offscreen or not. When FBO 0 is // bound, offscreen contexts render to an internal buffer, onscreen ones // to the surface. - // size: the size if the GL context is offscreen. + // offscreen_size: the size if the GL context is offscreen. // Returns: // true if successful. virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface, const scoped_refptr<gfx::GLContext>& context, bool offscreen, - const gfx::Size& size, + const gfx::Size& offscreen_size, const DisallowedFeatures& disallowed_features, const std::vector<int32>& attribs) = 0; @@ -161,6 +171,10 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, virtual void SetIgnoreCachedStateForTest(bool ignore) = 0; + // Allow the decoder to exit the current process. + // Defaults to |false|. + virtual void SetAllowExit(bool allow_exit) = 0; + // Gets the QueryManager for this context. virtual QueryManager* GetQueryManager() = 0; @@ -170,6 +184,9 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, // Gets the ImageManager for this context. virtual ImageManager* GetImageManager() = 0; + // Gets the ValuebufferManager for this context. + virtual ValuebufferManager* GetValuebufferManager() = 0; + // Process any pending queries. Returns false if there are no pending queries. virtual bool ProcessPendingQueries(bool did_finish) = 0; @@ -200,8 +217,7 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, // Clears a level of a texture // Returns false if a GL error should be generated. virtual bool ClearLevel( - unsigned service_id, - unsigned bind_target, + Texture* texture, unsigned target, int level, unsigned internal_format, @@ -229,13 +245,13 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, // Returns true if the context was lost either by GL_ARB_robustness, forced // context loss or command buffer parse error. - virtual bool WasContextLost() = 0; + virtual bool WasContextLost() const = 0; // Returns true if the context was lost specifically by GL_ARB_robustness. - virtual bool WasContextLostByRobustnessExtension() = 0; + virtual bool WasContextLostByRobustnessExtension() const = 0; // Lose this context. - virtual void LoseContext(uint32 reset_status) = 0; + virtual void MarkContextLost(error::ContextLostReason reason) = 0; virtual Logger* GetLogger() = 0; @@ -251,6 +267,7 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, bool initialized_; bool debug_; bool log_commands_; + bool unsafe_es3_apis_enabled_; DISALLOW_COPY_AND_ASSIGN(GLES2Decoder); }; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index ee3bba56d16..46cb85edc31 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -48,6 +48,58 @@ error::Error GLES2DecoderImpl::HandleBindBuffer(uint32_t immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandleBindBufferBase( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::BindBufferBase& c = + *static_cast<const gles2::cmds::BindBufferBase*>(cmd_data); + (void)c; + GLenum target = static_cast<GLenum>(c.target); + GLuint index = static_cast<GLuint>(c.index); + GLuint buffer = c.buffer; + if (!group_->GetBufferServiceId(buffer, &buffer)) { + if (!group_->bind_generates_resource()) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindBufferBase", + "invalid buffer id"); + return error::kNoError; + } + GLuint client_id = buffer; + glGenBuffersARB(1, &buffer); + CreateBuffer(client_id, buffer); + } + glBindBufferBase(target, index, buffer); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleBindBufferRange( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::BindBufferRange& c = + *static_cast<const gles2::cmds::BindBufferRange*>(cmd_data); + (void)c; + GLenum target = static_cast<GLenum>(c.target); + GLuint index = static_cast<GLuint>(c.index); + GLuint buffer = c.buffer; + GLintptr offset = static_cast<GLintptr>(c.offset); + GLsizeiptr size = static_cast<GLsizeiptr>(c.size); + if (!group_->GetBufferServiceId(buffer, &buffer)) { + if (!group_->bind_generates_resource()) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindBufferRange", + "invalid buffer id"); + return error::kNoError; + } + GLuint client_id = buffer; + glGenBuffersARB(1, &buffer); + CreateBuffer(client_id, buffer); + } + glBindBufferRange(target, index, buffer, offset, size); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleBindFramebuffer( uint32_t immediate_data_size, const void* cmd_data) { @@ -80,6 +132,24 @@ error::Error GLES2DecoderImpl::HandleBindRenderbuffer( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleBindSampler(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::BindSampler& c = + *static_cast<const gles2::cmds::BindSampler*>(cmd_data); + (void)c; + GLuint unit = static_cast<GLuint>(c.unit); + GLuint sampler = c.sampler; + if (!group_->GetSamplerServiceId(sampler, &sampler)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindSampler", + "invalid sampler id"); + return error::kNoError; + } + glBindSampler(unit, sampler); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleBindTexture(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::BindTexture& c = @@ -95,6 +165,26 @@ error::Error GLES2DecoderImpl::HandleBindTexture(uint32_t immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandleBindTransformFeedback( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::BindTransformFeedback& c = + *static_cast<const gles2::cmds::BindTransformFeedback*>(cmd_data); + (void)c; + GLenum target = static_cast<GLenum>(c.target); + GLuint transformfeedback = c.transformfeedback; + if (!group_->GetTransformFeedbackServiceId(transformfeedback, + &transformfeedback)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindTransformFeedback", + "invalid transformfeedback id"); + return error::kNoError; + } + glBindTransformFeedback(target, transformfeedback); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleBlendColor(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::BlendColor& c = @@ -290,6 +380,99 @@ error::Error GLES2DecoderImpl::HandleClear(uint32_t immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandleClearBufferfi(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::ClearBufferfi& c = + *static_cast<const gles2::cmds::ClearBufferfi*>(cmd_data); + (void)c; + GLenum buffer = static_cast<GLenum>(c.buffer); + GLint drawbuffers = static_cast<GLint>(c.drawbuffers); + GLfloat depth = static_cast<GLfloat>(c.depth); + GLint stencil = static_cast<GLint>(c.stencil); + glClearBufferfi(buffer, drawbuffers, depth, stencil); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleClearBufferfvImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::ClearBufferfvImmediate& c = + *static_cast<const gles2::cmds::ClearBufferfvImmediate*>(cmd_data); + (void)c; + GLenum buffer = static_cast<GLenum>(c.buffer); + GLint drawbuffers = static_cast<GLint>(c.drawbuffers); + uint32_t data_size; + if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLfloat* value = + GetImmediateDataAs<const GLfloat*>(c, data_size, immediate_data_size); + if (value == NULL) { + return error::kOutOfBounds; + } + glClearBufferfv(buffer, drawbuffers, value); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleClearBufferivImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::ClearBufferivImmediate& c = + *static_cast<const gles2::cmds::ClearBufferivImmediate*>(cmd_data); + (void)c; + GLenum buffer = static_cast<GLenum>(c.buffer); + GLint drawbuffers = static_cast<GLint>(c.drawbuffers); + uint32_t data_size; + if (!ComputeDataSize(1, sizeof(GLint), 4, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLint* value = + GetImmediateDataAs<const GLint*>(c, data_size, immediate_data_size); + if (value == NULL) { + return error::kOutOfBounds; + } + glClearBufferiv(buffer, drawbuffers, value); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleClearBufferuivImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::ClearBufferuivImmediate& c = + *static_cast<const gles2::cmds::ClearBufferuivImmediate*>(cmd_data); + (void)c; + GLenum buffer = static_cast<GLenum>(c.buffer); + GLint drawbuffers = static_cast<GLint>(c.drawbuffers); + uint32_t data_size; + if (!ComputeDataSize(1, sizeof(GLuint), 4, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLuint* value = + GetImmediateDataAs<const GLuint*>(c, data_size, immediate_data_size); + if (value == NULL) { + return error::kOutOfBounds; + } + glClearBufferuiv(buffer, drawbuffers, value); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleClearColor(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::ClearColor& c = @@ -416,6 +599,52 @@ error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2D( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleCompressedTexSubImage3D( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::CompressedTexSubImage3D& c = + *static_cast<const gles2::cmds::CompressedTexSubImage3D*>(cmd_data); + (void)c; + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + GLint zoffset = static_cast<GLint>(c.zoffset); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLsizei depth = static_cast<GLsizei>(c.depth); + GLenum format = static_cast<GLenum>(c.format); + GLsizei imageSize = static_cast<GLsizei>(c.imageSize); + uint32_t data_size = imageSize; + const void* data = GetSharedMemoryAs<const void*>( + c.data_shm_id, c.data_shm_offset, data_size); + if (data == NULL) { + return error::kOutOfBounds; + } + DoCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, + height, depth, format, imageSize, data); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleCopyBufferSubData( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::CopyBufferSubData& c = + *static_cast<const gles2::cmds::CopyBufferSubData*>(cmd_data); + (void)c; + GLenum readtarget = static_cast<GLenum>(c.readtarget); + GLenum writetarget = static_cast<GLenum>(c.writetarget); + GLintptr readoffset = static_cast<GLintptr>(c.readoffset); + GLintptr writeoffset = static_cast<GLintptr>(c.writeoffset); + GLsizeiptr size = static_cast<GLsizeiptr>(c.size); + glCopyBufferSubData(readtarget, writetarget, readoffset, writeoffset, size); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleCopyTexImage2D( uint32_t immediate_data_size, const void* cmd_data) { @@ -489,15 +718,45 @@ error::Error GLES2DecoderImpl::HandleCopyTexSubImage2D( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleCopyTexSubImage3D( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::CopyTexSubImage3D& c = + *static_cast<const gles2::cmds::CopyTexSubImage3D*>(cmd_data); + (void)c; + error::Error error; + error = WillAccessBoundFramebufferForRead(); + if (error != error::kNoError) + return error; + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + GLint zoffset = static_cast<GLint>(c.zoffset); + GLint x = static_cast<GLint>(c.x); + GLint y = static_cast<GLint>(c.y); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, + height); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleCreateProgram(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::CreateProgram& c = *static_cast<const gles2::cmds::CreateProgram*>(cmd_data); (void)c; uint32_t client_id = c.client_id; - if (!CreateProgramHelper(client_id)) { + if (GetProgram(client_id)) { return error::kInvalidArguments; } + GLuint service_id = glCreateProgram(); + if (service_id) { + CreateProgram(client_id, service_id); + } return error::kNoError; } @@ -512,9 +771,13 @@ error::Error GLES2DecoderImpl::HandleCreateShader(uint32_t immediate_data_size, return error::kNoError; } uint32_t client_id = c.client_id; - if (!CreateShaderHelper(type, client_id)) { + if (GetShader(client_id)) { return error::kInvalidArguments; } + GLuint service_id = glCreateShader(type); + if (service_id) { + CreateShader(client_id, service_id, type); + } return error::kNoError; } @@ -595,6 +858,52 @@ error::Error GLES2DecoderImpl::HandleDeleteRenderbuffersImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleDeleteSamplersImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::DeleteSamplersImmediate& c = + *static_cast<const gles2::cmds::DeleteSamplersImmediate*>(cmd_data); + (void)c; + GLsizei n = static_cast<GLsizei>(c.n); + uint32_t data_size; + if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { + return error::kOutOfBounds; + } + const GLuint* samplers = + GetImmediateDataAs<const GLuint*>(c, data_size, immediate_data_size); + if (samplers == NULL) { + return error::kOutOfBounds; + } + for (GLsizei ii = 0; ii < n; ++ii) { + GLuint service_id = 0; + if (group_->GetSamplerServiceId(samplers[ii], &service_id)) { + glDeleteSamplers(1, &service_id); + group_->RemoveSamplerId(samplers[ii]); + } + } + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleDeleteSync(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::DeleteSync& c = + *static_cast<const gles2::cmds::DeleteSync*>(cmd_data); + (void)c; + GLuint sync = c.sync; + GLsync service_id = 0; + if (group_->GetSyncServiceId(sync, &service_id)) { + glDeleteSync(service_id); + group_->RemoveSyncId(sync); + } else { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteSync", "unknown sync"); + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleDeleteTexturesImmediate( uint32_t immediate_data_size, const void* cmd_data) { @@ -615,6 +924,35 @@ error::Error GLES2DecoderImpl::HandleDeleteTexturesImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleDeleteTransformFeedbacksImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::DeleteTransformFeedbacksImmediate& c = + *static_cast<const gles2::cmds::DeleteTransformFeedbacksImmediate*>( + cmd_data); + (void)c; + GLsizei n = static_cast<GLsizei>(c.n); + uint32_t data_size; + if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { + return error::kOutOfBounds; + } + const GLuint* ids = + GetImmediateDataAs<const GLuint*>(c, data_size, immediate_data_size); + if (ids == NULL) { + return error::kOutOfBounds; + } + for (GLsizei ii = 0; ii < n; ++ii) { + GLuint service_id = 0; + if (group_->GetTransformFeedbackServiceId(ids[ii], &service_id)) { + glDeleteTransformFeedbacks(1, &service_id); + group_->RemoveTransformFeedbackId(ids[ii]); + } + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleDepthFunc(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::DepthFunc& c = @@ -717,6 +1055,27 @@ error::Error GLES2DecoderImpl::HandleEnableVertexAttribArray( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleFenceSync(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::FenceSync& c = + *static_cast<const gles2::cmds::FenceSync*>(cmd_data); + (void)c; + GLenum condition = static_cast<GLenum>(c.condition); + GLbitfield flags = static_cast<GLbitfield>(c.flags); + uint32_t client_id = c.client_id; + GLsync service_id = 0; + if (group_->GetSyncServiceId(client_id, &service_id)) { + return error::kInvalidArguments; + } + service_id = glFenceSync(condition, flags); + if (service_id) { + group_->AddSyncId(client_id, service_id); + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleFinish(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::Finish& c = @@ -798,6 +1157,23 @@ error::Error GLES2DecoderImpl::HandleFramebufferTexture2D( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleFramebufferTextureLayer( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::FramebufferTextureLayer& c = + *static_cast<const gles2::cmds::FramebufferTextureLayer*>(cmd_data); + (void)c; + GLenum target = static_cast<GLenum>(c.target); + GLenum attachment = static_cast<GLenum>(c.attachment); + GLuint texture = c.texture; + GLint level = static_cast<GLint>(c.level); + GLint layer = static_cast<GLint>(c.layer); + DoFramebufferTextureLayer(target, attachment, texture, level, layer); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleFrontFace(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::FrontFace& c = @@ -896,6 +1272,37 @@ error::Error GLES2DecoderImpl::HandleGenRenderbuffersImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleGenSamplersImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GenSamplersImmediate& c = + *static_cast<const gles2::cmds::GenSamplersImmediate*>(cmd_data); + (void)c; + GLsizei n = static_cast<GLsizei>(c.n); + uint32_t data_size; + if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { + return error::kOutOfBounds; + } + GLuint* samplers = + GetImmediateDataAs<GLuint*>(c, data_size, immediate_data_size); + if (samplers == NULL) { + return error::kOutOfBounds; + } + for (GLsizei ii = 0; ii < n; ++ii) { + if (group_->GetSamplerServiceId(samplers[ii], NULL)) { + return error::kInvalidArguments; + } + } + scoped_ptr<GLuint[]> service_ids(new GLuint[n]); + glGenSamplers(n, service_ids.get()); + for (GLsizei ii = 0; ii < n; ++ii) { + group_->AddSamplerId(samplers[ii], service_ids[ii]); + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGenTexturesImmediate( uint32_t immediate_data_size, const void* cmd_data) { @@ -918,6 +1325,37 @@ error::Error GLES2DecoderImpl::HandleGenTexturesImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleGenTransformFeedbacksImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GenTransformFeedbacksImmediate& c = + *static_cast<const gles2::cmds::GenTransformFeedbacksImmediate*>( + cmd_data); + (void)c; + GLsizei n = static_cast<GLsizei>(c.n); + uint32_t data_size; + if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { + return error::kOutOfBounds; + } + GLuint* ids = GetImmediateDataAs<GLuint*>(c, data_size, immediate_data_size); + if (ids == NULL) { + return error::kOutOfBounds; + } + for (GLsizei ii = 0; ii < n; ++ii) { + if (group_->GetTransformFeedbackServiceId(ids[ii], NULL)) { + return error::kInvalidArguments; + } + } + scoped_ptr<GLuint[]> service_ids(new GLuint[n]); + glGenTransformFeedbacks(n, service_ids.get()); + for (GLsizei ii = 0; ii < n; ++ii) { + group_->AddTransformFeedbackId(ids[ii], service_ids[ii]); + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetBooleanv(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::GetBooleanv& c = @@ -1083,6 +1521,105 @@ error::Error GLES2DecoderImpl::HandleGetFramebufferAttachmentParameteriv( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleGetInteger64v(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetInteger64v& c = + *static_cast<const gles2::cmds::GetInteger64v*>(cmd_data); + (void)c; + GLenum pname = static_cast<GLenum>(c.pname); + typedef cmds::GetInteger64v::Result Result; + GLsizei num_values = 0; + GetNumValuesReturnedForGLGet(pname, &num_values); + Result* result = GetSharedMemoryAs<Result*>( + c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); + GLint64* params = result ? result->GetData() : NULL; + if (params == NULL) { + return error::kOutOfBounds; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetInteger64v"); + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + DoGetInteger64v(pname, params); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(num_values); + } else { + LOCAL_SET_GL_ERROR(error, "GetInteger64v", ""); + } + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleGetIntegeri_v(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetIntegeri_v& c = + *static_cast<const gles2::cmds::GetIntegeri_v*>(cmd_data); + (void)c; + GLenum pname = static_cast<GLenum>(c.pname); + GLuint index = static_cast<GLuint>(c.index); + typedef cmds::GetIntegeri_v::Result Result; + GLsizei num_values = 0; + GetNumValuesReturnedForGLGet(pname, &num_values); + Result* result = GetSharedMemoryAs<Result*>(c.data_shm_id, c.data_shm_offset, + Result::ComputeSize(num_values)); + GLint* data = result ? result->GetData() : NULL; + if (data == NULL) { + return error::kOutOfBounds; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetIntegeri_v"); + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + glGetIntegeri_v(pname, index, data); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(num_values); + } else { + LOCAL_SET_GL_ERROR(error, "GetIntegeri_v", ""); + } + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleGetInteger64i_v( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetInteger64i_v& c = + *static_cast<const gles2::cmds::GetInteger64i_v*>(cmd_data); + (void)c; + GLenum pname = static_cast<GLenum>(c.pname); + GLuint index = static_cast<GLuint>(c.index); + typedef cmds::GetInteger64i_v::Result Result; + GLsizei num_values = 0; + GetNumValuesReturnedForGLGet(pname, &num_values); + Result* result = GetSharedMemoryAs<Result*>(c.data_shm_id, c.data_shm_offset, + Result::ComputeSize(num_values)); + GLint64* data = result ? result->GetData() : NULL; + if (data == NULL) { + return error::kOutOfBounds; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetInteger64i_v"); + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + glGetInteger64i_v(pname, index, data); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(num_values); + } else { + LOCAL_SET_GL_ERROR(error, "GetInteger64i_v", ""); + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetIntegerv(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::GetIntegerv& c = @@ -1117,6 +1654,42 @@ error::Error GLES2DecoderImpl::HandleGetIntegerv(uint32_t immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandleGetInternalformativ( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetInternalformativ& c = + *static_cast<const gles2::cmds::GetInternalformativ*>(cmd_data); + (void)c; + GLenum target = static_cast<GLenum>(c.target); + GLenum format = static_cast<GLenum>(c.format); + GLenum pname = static_cast<GLenum>(c.pname); + GLsizei bufSize = static_cast<GLsizei>(c.bufSize); + typedef cmds::GetInternalformativ::Result Result; + GLsizei num_values = 0; + GetNumValuesReturnedForGLGet(pname, &num_values); + Result* result = GetSharedMemoryAs<Result*>( + c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); + GLint* params = result ? result->GetData() : NULL; + if (params == NULL) { + return error::kOutOfBounds; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetInternalformativ"); + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + glGetInternalformativ(target, format, pname, bufSize, params); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(num_values); + } else { + LOCAL_SET_GL_ERROR(error, "GetInternalformativ", ""); + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetProgramiv(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::GetProgramiv& c = @@ -1194,6 +1767,84 @@ error::Error GLES2DecoderImpl::HandleGetRenderbufferParameteriv( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleGetSamplerParameterfv( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetSamplerParameterfv& c = + *static_cast<const gles2::cmds::GetSamplerParameterfv*>(cmd_data); + (void)c; + GLuint sampler = c.sampler; + GLenum pname = static_cast<GLenum>(c.pname); + typedef cmds::GetSamplerParameterfv::Result Result; + GLsizei num_values = 0; + GetNumValuesReturnedForGLGet(pname, &num_values); + Result* result = GetSharedMemoryAs<Result*>( + c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); + GLfloat* params = result ? result->GetData() : NULL; + if (params == NULL) { + return error::kOutOfBounds; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetSamplerParameterfv"); + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + if (!group_->GetSamplerServiceId(sampler, &sampler)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetSamplerParameterfv", + "invalid sampler id"); + return error::kNoError; + } + glGetSamplerParameterfv(sampler, pname, params); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(num_values); + } else { + LOCAL_SET_GL_ERROR(error, "GetSamplerParameterfv", ""); + } + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleGetSamplerParameteriv( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetSamplerParameteriv& c = + *static_cast<const gles2::cmds::GetSamplerParameteriv*>(cmd_data); + (void)c; + GLuint sampler = c.sampler; + GLenum pname = static_cast<GLenum>(c.pname); + typedef cmds::GetSamplerParameteriv::Result Result; + GLsizei num_values = 0; + GetNumValuesReturnedForGLGet(pname, &num_values); + Result* result = GetSharedMemoryAs<Result*>( + c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); + GLint* params = result ? result->GetData() : NULL; + if (params == NULL) { + return error::kOutOfBounds; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetSamplerParameteriv"); + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + if (!group_->GetSamplerServiceId(sampler, &sampler)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetSamplerParameteriv", + "invalid sampler id"); + return error::kNoError; + } + glGetSamplerParameteriv(sampler, pname, params); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(num_values); + } else { + LOCAL_SET_GL_ERROR(error, "GetSamplerParameteriv", ""); + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetShaderiv(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::GetShaderiv& c = @@ -1229,6 +1880,44 @@ error::Error GLES2DecoderImpl::HandleGetShaderiv(uint32_t immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandleGetSynciv(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetSynciv& c = + *static_cast<const gles2::cmds::GetSynciv*>(cmd_data); + (void)c; + GLuint sync = static_cast<GLuint>(c.sync); + GLenum pname = static_cast<GLenum>(c.pname); + typedef cmds::GetSynciv::Result Result; + GLsizei num_values = 0; + GetNumValuesReturnedForGLGet(pname, &num_values); + Result* result = GetSharedMemoryAs<Result*>( + c.values_shm_id, c.values_shm_offset, Result::ComputeSize(num_values)); + GLint* values = result ? result->GetData() : NULL; + if (values == NULL) { + return error::kOutOfBounds; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetSynciv"); + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + GLsync service_sync = 0; + if (!group_->GetSyncServiceId(sync, &service_sync)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetSynciv", "invalid sync id"); + return error::kNoError; + } + glGetSynciv(service_sync, pname, num_values, nullptr, values); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(num_values); + } else { + LOCAL_SET_GL_ERROR(error, "GetSynciv", ""); + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetTexParameterfv( uint32_t immediate_data_size, const void* cmd_data) { @@ -1381,6 +2070,74 @@ error::Error GLES2DecoderImpl::HandleGetVertexAttribiv( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleGetVertexAttribIiv( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetVertexAttribIiv& c = + *static_cast<const gles2::cmds::GetVertexAttribIiv*>(cmd_data); + (void)c; + GLuint index = static_cast<GLuint>(c.index); + GLenum pname = static_cast<GLenum>(c.pname); + typedef cmds::GetVertexAttribIiv::Result Result; + GLsizei num_values = 0; + GetNumValuesReturnedForGLGet(pname, &num_values); + Result* result = GetSharedMemoryAs<Result*>( + c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); + GLint* params = result ? result->GetData() : NULL; + if (params == NULL) { + return error::kOutOfBounds; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetVertexAttribIiv"); + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + DoGetVertexAttribIiv(index, pname, params); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(num_values); + } else { + LOCAL_SET_GL_ERROR(error, "GetVertexAttribIiv", ""); + } + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleGetVertexAttribIuiv( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::GetVertexAttribIuiv& c = + *static_cast<const gles2::cmds::GetVertexAttribIuiv*>(cmd_data); + (void)c; + GLuint index = static_cast<GLuint>(c.index); + GLenum pname = static_cast<GLenum>(c.pname); + typedef cmds::GetVertexAttribIuiv::Result Result; + GLsizei num_values = 0; + GetNumValuesReturnedForGLGet(pname, &num_values); + Result* result = GetSharedMemoryAs<Result*>( + c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); + GLuint* params = result ? result->GetData() : NULL; + if (params == NULL) { + return error::kOutOfBounds; + } + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetVertexAttribIuiv"); + // Check that the client initialized the result. + if (result->size != 0) { + return error::kInvalidArguments; + } + DoGetVertexAttribIuiv(index, pname, params); + GLenum error = glGetError(); + if (error == GL_NO_ERROR) { + result->SetNumResults(num_values); + } else { + LOCAL_SET_GL_ERROR(error, "GetVertexAttribIuiv", ""); + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleHint(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::Hint& c = *static_cast<const gles2::cmds::Hint*>(cmd_data); @@ -1414,6 +2171,64 @@ error::Error GLES2DecoderImpl::HandleHint(uint32_t immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandleInvalidateFramebufferImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::InvalidateFramebufferImmediate& c = + *static_cast<const gles2::cmds::InvalidateFramebufferImmediate*>( + cmd_data); + (void)c; + GLenum target = static_cast<GLenum>(c.target); + GLsizei count = static_cast<GLsizei>(c.count); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLenum* attachments = + GetImmediateDataAs<const GLenum*>(c, data_size, immediate_data_size); + if (attachments == NULL) { + return error::kOutOfBounds; + } + glInvalidateFramebuffer(target, count, attachments); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleInvalidateSubFramebufferImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::InvalidateSubFramebufferImmediate& c = + *static_cast<const gles2::cmds::InvalidateSubFramebufferImmediate*>( + cmd_data); + (void)c; + GLenum target = static_cast<GLenum>(c.target); + GLsizei count = static_cast<GLsizei>(c.count); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLenum* attachments = + GetImmediateDataAs<const GLenum*>(c, data_size, immediate_data_size); + GLint x = static_cast<GLint>(c.x); + GLint y = static_cast<GLint>(c.y); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + if (attachments == NULL) { + return error::kOutOfBounds; + } + glInvalidateSubFramebuffer(target, count, attachments, x, y, width, height); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleIsBuffer(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::IsBuffer& c = @@ -1499,6 +2314,25 @@ error::Error GLES2DecoderImpl::HandleIsRenderbuffer( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleIsSampler(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::IsSampler& c = + *static_cast<const gles2::cmds::IsSampler*>(cmd_data); + (void)c; + GLuint sampler = c.sampler; + typedef cmds::IsSampler::Result Result; + Result* result_dst = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + if (!result_dst) { + return error::kOutOfBounds; + } + GLuint service_sampler = 0; + *result_dst = group_->GetSamplerServiceId(sampler, &service_sampler); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleIsShader(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::IsShader& c = @@ -1515,6 +2349,25 @@ error::Error GLES2DecoderImpl::HandleIsShader(uint32_t immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandleIsSync(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::IsSync& c = + *static_cast<const gles2::cmds::IsSync*>(cmd_data); + (void)c; + GLuint sync = c.sync; + typedef cmds::IsSync::Result Result; + Result* result_dst = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + if (!result_dst) { + return error::kOutOfBounds; + } + GLsync service_sync = 0; + *result_dst = group_->GetSyncServiceId(sync, &service_sync); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleIsTexture(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::IsTexture& c = @@ -1531,13 +2384,34 @@ error::Error GLES2DecoderImpl::HandleIsTexture(uint32_t immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandleIsTransformFeedback( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::IsTransformFeedback& c = + *static_cast<const gles2::cmds::IsTransformFeedback*>(cmd_data); + (void)c; + GLuint transformfeedback = c.transformfeedback; + typedef cmds::IsTransformFeedback::Result Result; + Result* result_dst = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + if (!result_dst) { + return error::kOutOfBounds; + } + GLuint service_transformfeedback = 0; + *result_dst = group_->GetTransformFeedbackServiceId( + transformfeedback, &service_transformfeedback); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleLineWidth(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::LineWidth& c = *static_cast<const gles2::cmds::LineWidth*>(cmd_data); (void)c; GLfloat width = static_cast<GLfloat>(c.width); - if (width <= 0.0f || base::IsNaN(width)) { + if (width <= 0.0f || std::isnan(width)) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "LineWidth", "width out of range"); return error::kNoError; } @@ -1558,6 +2432,18 @@ error::Error GLES2DecoderImpl::HandleLinkProgram(uint32_t immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandlePauseTransformFeedback( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::PauseTransformFeedback& c = + *static_cast<const gles2::cmds::PauseTransformFeedback*>(cmd_data); + (void)c; + glPauseTransformFeedback(); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandlePolygonOffset(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::PolygonOffset& c = @@ -1574,6 +2460,18 @@ error::Error GLES2DecoderImpl::HandlePolygonOffset(uint32_t immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandleReadBuffer(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::ReadBuffer& c = + *static_cast<const gles2::cmds::ReadBuffer*>(cmd_data); + (void)c; + GLenum src = static_cast<GLenum>(c.src); + glReadBuffer(src); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleReleaseShaderCompiler( uint32_t immediate_data_size, const void* cmd_data) { @@ -1615,6 +2513,18 @@ error::Error GLES2DecoderImpl::HandleRenderbufferStorage( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleResumeTransformFeedback( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::ResumeTransformFeedback& c = + *static_cast<const gles2::cmds::ResumeTransformFeedback*>(cmd_data); + (void)c; + glResumeTransformFeedback(); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleSampleCoverage( uint32_t immediate_data_size, const void* cmd_data) { @@ -1627,6 +2537,99 @@ error::Error GLES2DecoderImpl::HandleSampleCoverage( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleSamplerParameterf( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::SamplerParameterf& c = + *static_cast<const gles2::cmds::SamplerParameterf*>(cmd_data); + (void)c; + GLuint sampler = c.sampler; + GLenum pname = static_cast<GLenum>(c.pname); + GLfloat param = static_cast<GLfloat>(c.param); + if (!group_->GetSamplerServiceId(sampler, &sampler)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSamplerParameterf", + "invalid sampler id"); + return error::kNoError; + } + glSamplerParameterf(sampler, pname, param); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleSamplerParameterfvImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::SamplerParameterfvImmediate& c = + *static_cast<const gles2::cmds::SamplerParameterfvImmediate*>(cmd_data); + (void)c; + GLuint sampler = c.sampler; + GLenum pname = static_cast<GLenum>(c.pname); + uint32_t data_size; + if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLfloat* params = + GetImmediateDataAs<const GLfloat*>(c, data_size, immediate_data_size); + if (params == NULL) { + return error::kOutOfBounds; + } + group_->GetSamplerServiceId(sampler, &sampler); + DoSamplerParameterfv(sampler, pname, params); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleSamplerParameteri( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::SamplerParameteri& c = + *static_cast<const gles2::cmds::SamplerParameteri*>(cmd_data); + (void)c; + GLuint sampler = c.sampler; + GLenum pname = static_cast<GLenum>(c.pname); + GLint param = static_cast<GLint>(c.param); + if (!group_->GetSamplerServiceId(sampler, &sampler)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSamplerParameteri", + "invalid sampler id"); + return error::kNoError; + } + glSamplerParameteri(sampler, pname, param); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleSamplerParameterivImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::SamplerParameterivImmediate& c = + *static_cast<const gles2::cmds::SamplerParameterivImmediate*>(cmd_data); + (void)c; + GLuint sampler = c.sampler; + GLenum pname = static_cast<GLenum>(c.pname); + uint32_t data_size; + if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLint* params = + GetImmediateDataAs<const GLint*>(c, data_size, immediate_data_size); + if (params == NULL) { + return error::kOutOfBounds; + } + DoSamplerParameteriv(sampler, pname, params); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleScissor(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::Scissor& c = @@ -1655,6 +2658,33 @@ error::Error GLES2DecoderImpl::HandleScissor(uint32_t immediate_data_size, return error::kNoError; } +error::Error GLES2DecoderImpl::HandleShaderSourceBucket( + uint32_t immediate_data_size, + const void* cmd_data) { + const gles2::cmds::ShaderSourceBucket& c = + *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data); + (void)c; + GLuint shader = static_cast<GLuint>(c.shader); + + Bucket* bucket = GetBucket(c.str_bucket_id); + if (!bucket) { + return error::kInvalidArguments; + } + GLsizei count = 0; + std::vector<char*> strs; + std::vector<GLint> len; + if (!bucket->GetAsStrings(&count, &strs, &len)) { + return error::kInvalidArguments; + } + const char** str = + strs.size() > 0 ? const_cast<const char**>(&strs[0]) : NULL; + const GLint* length = + len.size() > 0 ? const_cast<const GLint*>(&len[0]) : NULL; + (void)length; + DoShaderSource(shader, count, str, length); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleStencilFunc(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::StencilFunc& c = @@ -1966,6 +2996,54 @@ error::Error GLES2DecoderImpl::HandleTexParameterivImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleTexStorage3D(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::TexStorage3D& c = + *static_cast<const gles2::cmds::TexStorage3D*>(cmd_data); + (void)c; + GLenum target = static_cast<GLenum>(c.target); + GLsizei levels = static_cast<GLsizei>(c.levels); + GLenum internalFormat = static_cast<GLenum>(c.internalFormat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLsizei depth = static_cast<GLsizei>(c.depth); + glTexStorage3D(target, levels, internalFormat, width, height, depth); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleTransformFeedbackVaryingsBucket( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::TransformFeedbackVaryingsBucket& c = + *static_cast<const gles2::cmds::TransformFeedbackVaryingsBucket*>( + cmd_data); + (void)c; + GLuint program = static_cast<GLuint>(c.program); + + Bucket* bucket = GetBucket(c.varyings_bucket_id); + if (!bucket) { + return error::kInvalidArguments; + } + GLsizei count = 0; + std::vector<char*> strs; + std::vector<GLint> len; + if (!bucket->GetAsStrings(&count, &strs, &len)) { + return error::kInvalidArguments; + } + const char** varyings = + strs.size() > 0 ? const_cast<const char**>(&strs[0]) : NULL; + const GLint* length = + len.size() > 0 ? const_cast<const GLint*>(&len[0]) : NULL; + (void)length; + GLenum buffermode = static_cast<GLenum>(c.buffermode); + DoTransformFeedbackVaryings(program, count, varyings, buffermode); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleUniform1f(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::Uniform1f& c = @@ -2039,6 +3117,48 @@ error::Error GLES2DecoderImpl::HandleUniform1ivImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleUniform1ui(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::Uniform1ui& c = + *static_cast<const gles2::cmds::Uniform1ui*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLuint x = static_cast<GLuint>(c.x); + GLuint temp[1] = { + x, + }; + glUniform1uiv(location, 1, &temp[0]); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleUniform1uivImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::Uniform1uivImmediate& c = + *static_cast<const gles2::cmds::Uniform1uivImmediate*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLuint), 1, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLuint* v = + GetImmediateDataAs<const GLuint*>(c, data_size, immediate_data_size); + if (v == NULL) { + return error::kOutOfBounds; + } + glUniform1uiv(location, count, v); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleUniform2f(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::Uniform2f& c = @@ -2117,6 +3237,49 @@ error::Error GLES2DecoderImpl::HandleUniform2ivImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleUniform2ui(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::Uniform2ui& c = + *static_cast<const gles2::cmds::Uniform2ui*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLuint x = static_cast<GLuint>(c.x); + GLuint y = static_cast<GLuint>(c.y); + GLuint temp[2] = { + x, y, + }; + glUniform2uiv(location, 1, &temp[0]); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleUniform2uivImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::Uniform2uivImmediate& c = + *static_cast<const gles2::cmds::Uniform2uivImmediate*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLuint), 2, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLuint* v = + GetImmediateDataAs<const GLuint*>(c, data_size, immediate_data_size); + if (v == NULL) { + return error::kOutOfBounds; + } + glUniform2uiv(location, count, v); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleUniform3f(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::Uniform3f& c = @@ -2197,6 +3360,50 @@ error::Error GLES2DecoderImpl::HandleUniform3ivImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleUniform3ui(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::Uniform3ui& c = + *static_cast<const gles2::cmds::Uniform3ui*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLuint x = static_cast<GLuint>(c.x); + GLuint y = static_cast<GLuint>(c.y); + GLuint z = static_cast<GLuint>(c.z); + GLuint temp[3] = { + x, y, z, + }; + glUniform3uiv(location, 1, &temp[0]); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleUniform3uivImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::Uniform3uivImmediate& c = + *static_cast<const gles2::cmds::Uniform3uivImmediate*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLuint), 3, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLuint* v = + GetImmediateDataAs<const GLuint*>(c, data_size, immediate_data_size); + if (v == NULL) { + return error::kOutOfBounds; + } + glUniform3uiv(location, count, v); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleUniform4f(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::Uniform4f& c = @@ -2279,6 +3486,51 @@ error::Error GLES2DecoderImpl::HandleUniform4ivImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleUniform4ui(uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::Uniform4ui& c = + *static_cast<const gles2::cmds::Uniform4ui*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLuint x = static_cast<GLuint>(c.x); + GLuint y = static_cast<GLuint>(c.y); + GLuint z = static_cast<GLuint>(c.z); + GLuint w = static_cast<GLuint>(c.w); + GLuint temp[4] = { + x, y, z, w, + }; + glUniform4uiv(location, 1, &temp[0]); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleUniform4uivImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::Uniform4uivImmediate& c = + *static_cast<const gles2::cmds::Uniform4uivImmediate*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLuint), 4, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLuint* v = + GetImmediateDataAs<const GLuint*>(c, data_size, immediate_data_size); + if (v == NULL) { + return error::kOutOfBounds; + } + glUniform4uiv(location, count, v); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleUniformMatrix2fvImmediate( uint32_t immediate_data_size, const void* cmd_data) { @@ -2304,6 +3556,60 @@ error::Error GLES2DecoderImpl::HandleUniformMatrix2fvImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleUniformMatrix2x3fvImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::UniformMatrix2x3fvImmediate& c = + *static_cast<const gles2::cmds::UniformMatrix2x3fvImmediate*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLfloat), 6, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLfloat* value = + GetImmediateDataAs<const GLfloat*>(c, data_size, immediate_data_size); + if (value == NULL) { + return error::kOutOfBounds; + } + glUniformMatrix2x3fv(location, count, transpose, value); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleUniformMatrix2x4fvImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::UniformMatrix2x4fvImmediate& c = + *static_cast<const gles2::cmds::UniformMatrix2x4fvImmediate*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLfloat), 8, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLfloat* value = + GetImmediateDataAs<const GLfloat*>(c, data_size, immediate_data_size); + if (value == NULL) { + return error::kOutOfBounds; + } + glUniformMatrix2x4fv(location, count, transpose, value); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleUniformMatrix3fvImmediate( uint32_t immediate_data_size, const void* cmd_data) { @@ -2329,6 +3635,60 @@ error::Error GLES2DecoderImpl::HandleUniformMatrix3fvImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleUniformMatrix3x2fvImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::UniformMatrix3x2fvImmediate& c = + *static_cast<const gles2::cmds::UniformMatrix3x2fvImmediate*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLfloat), 6, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLfloat* value = + GetImmediateDataAs<const GLfloat*>(c, data_size, immediate_data_size); + if (value == NULL) { + return error::kOutOfBounds; + } + glUniformMatrix3x2fv(location, count, transpose, value); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleUniformMatrix3x4fvImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::UniformMatrix3x4fvImmediate& c = + *static_cast<const gles2::cmds::UniformMatrix3x4fvImmediate*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLfloat), 12, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLfloat* value = + GetImmediateDataAs<const GLfloat*>(c, data_size, immediate_data_size); + if (value == NULL) { + return error::kOutOfBounds; + } + glUniformMatrix3x4fv(location, count, transpose, value); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleUniformMatrix4fvImmediate( uint32_t immediate_data_size, const void* cmd_data) { @@ -2354,6 +3714,60 @@ error::Error GLES2DecoderImpl::HandleUniformMatrix4fvImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleUniformMatrix4x2fvImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::UniformMatrix4x2fvImmediate& c = + *static_cast<const gles2::cmds::UniformMatrix4x2fvImmediate*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLfloat), 8, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLfloat* value = + GetImmediateDataAs<const GLfloat*>(c, data_size, immediate_data_size); + if (value == NULL) { + return error::kOutOfBounds; + } + glUniformMatrix4x2fv(location, count, transpose, value); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleUniformMatrix4x3fvImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::UniformMatrix4x3fvImmediate& c = + *static_cast<const gles2::cmds::UniformMatrix4x3fvImmediate*>(cmd_data); + (void)c; + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + uint32_t data_size; + if (!ComputeDataSize(count, sizeof(GLfloat), 12, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLfloat* value = + GetImmediateDataAs<const GLfloat*>(c, data_size, immediate_data_size); + if (value == NULL) { + return error::kOutOfBounds; + } + glUniformMatrix4x3fv(location, count, transpose, value); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleUseProgram(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::UseProgram& c = @@ -2521,6 +3935,90 @@ error::Error GLES2DecoderImpl::HandleVertexAttrib4fvImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleVertexAttribI4i( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::VertexAttribI4i& c = + *static_cast<const gles2::cmds::VertexAttribI4i*>(cmd_data); + (void)c; + GLuint indx = static_cast<GLuint>(c.indx); + GLint x = static_cast<GLint>(c.x); + GLint y = static_cast<GLint>(c.y); + GLint z = static_cast<GLint>(c.z); + GLint w = static_cast<GLint>(c.w); + DoVertexAttribI4i(indx, x, y, z, w); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleVertexAttribI4ivImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::VertexAttribI4ivImmediate& c = + *static_cast<const gles2::cmds::VertexAttribI4ivImmediate*>(cmd_data); + (void)c; + GLuint indx = static_cast<GLuint>(c.indx); + uint32_t data_size; + if (!ComputeDataSize(1, sizeof(GLint), 4, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLint* values = + GetImmediateDataAs<const GLint*>(c, data_size, immediate_data_size); + if (values == NULL) { + return error::kOutOfBounds; + } + DoVertexAttribI4iv(indx, values); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleVertexAttribI4ui( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::VertexAttribI4ui& c = + *static_cast<const gles2::cmds::VertexAttribI4ui*>(cmd_data); + (void)c; + GLuint indx = static_cast<GLuint>(c.indx); + GLuint x = static_cast<GLuint>(c.x); + GLuint y = static_cast<GLuint>(c.y); + GLuint z = static_cast<GLuint>(c.z); + GLuint w = static_cast<GLuint>(c.w); + DoVertexAttribI4ui(indx, x, y, z, w); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleVertexAttribI4uivImmediate( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::VertexAttribI4uivImmediate& c = + *static_cast<const gles2::cmds::VertexAttribI4uivImmediate*>(cmd_data); + (void)c; + GLuint indx = static_cast<GLuint>(c.indx); + uint32_t data_size; + if (!ComputeDataSize(1, sizeof(GLuint), 4, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLuint* values = + GetImmediateDataAs<const GLuint*>(c, data_size, immediate_data_size); + if (values == NULL) { + return error::kOutOfBounds; + } + DoVertexAttribI4uiv(indx, values); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleViewport(uint32_t immediate_data_size, const void* cmd_data) { const gles2::cmds::Viewport& c = @@ -2804,6 +4302,31 @@ error::Error GLES2DecoderImpl::HandleDeleteQueriesEXTImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleBeginTransformFeedback( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::BeginTransformFeedback& c = + *static_cast<const gles2::cmds::BeginTransformFeedback*>(cmd_data); + (void)c; + GLenum primitivemode = static_cast<GLenum>(c.primitivemode); + glBeginTransformFeedback(primitivemode); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleEndTransformFeedback( + uint32_t immediate_data_size, + const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) + return error::kUnknownCommand; + const gles2::cmds::EndTransformFeedback& c = + *static_cast<const gles2::cmds::EndTransformFeedback*>(cmd_data); + (void)c; + glEndTransformFeedback(); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleInsertEventMarkerEXT( uint32_t immediate_data_size, const void* cmd_data) { @@ -3003,7 +4526,6 @@ error::Error GLES2DecoderImpl::HandleCopyTextureCHROMIUM( GLenum target = static_cast<GLenum>(c.target); GLenum source_id = static_cast<GLenum>(c.source_id); GLenum dest_id = static_cast<GLenum>(c.dest_id); - GLint level = static_cast<GLint>(c.level); GLint internalformat = static_cast<GLint>(c.internalformat); GLenum dest_type = static_cast<GLenum>(c.dest_type); if (!validators_->texture_internal_format.IsValid(internalformat)) { @@ -3016,8 +4538,22 @@ error::Error GLES2DecoderImpl::HandleCopyTextureCHROMIUM( "dest_type"); return error::kNoError; } - DoCopyTextureCHROMIUM(target, source_id, dest_id, level, internalformat, - dest_type); + DoCopyTextureCHROMIUM(target, source_id, dest_id, internalformat, dest_type); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleCopySubTextureCHROMIUM( + uint32_t immediate_data_size, + const void* cmd_data) { + const gles2::cmds::CopySubTextureCHROMIUM& c = + *static_cast<const gles2::cmds::CopySubTextureCHROMIUM*>(cmd_data); + (void)c; + GLenum target = static_cast<GLenum>(c.target); + GLenum source_id = static_cast<GLenum>(c.source_id); + GLenum dest_id = static_cast<GLenum>(c.dest_id); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + DoCopySubTextureCHROMIUM(target, source_id, dest_id, xoffset, yoffset); return error::kNoError; } @@ -3377,6 +4913,16 @@ error::Error GLES2DecoderImpl::HandleDrawBuffersEXTImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleSwapInterval(uint32_t immediate_data_size, + const void* cmd_data) { + const gles2::cmds::SwapInterval& c = + *static_cast<const gles2::cmds::SwapInterval*>(cmd_data); + (void)c; + GLint interval = static_cast<GLint>(c.interval); + DoSwapInterval(interval); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleMatrixLoadfCHROMIUMImmediate( uint32_t immediate_data_size, const void* cmd_data) { @@ -3521,6 +5067,22 @@ bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) { framebuffer_state_.clear_state_dirty = true; } return false; + case GL_RASTERIZER_DISCARD: + state_.enable_flags.rasterizer_discard = enabled; + if (state_.enable_flags.cached_rasterizer_discard != enabled || + state_.ignore_cached_state) { + state_.enable_flags.cached_rasterizer_discard = enabled; + return true; + } + return false; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + state_.enable_flags.primitive_restart_fixed_index = enabled; + if (state_.enable_flags.cached_primitive_restart_fixed_index != enabled || + state_.ignore_cached_state) { + state_.enable_flags.cached_primitive_restart_fixed_index = enabled; + return true; + } + return false; default: NOTREACHED(); return false; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index d855c87483b..1e5357dae48 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h @@ -9,11 +9,11 @@ #include <vector> +#include "base/callback_forward.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" -#include "base/callback_forward.h" #include "testing/gmock/include/gmock/gmock.h" -#include "ui/gfx/size.h" +#include "ui/gfx/geometry/size.h" namespace gfx { class GLContext; @@ -78,6 +78,7 @@ class MockGLES2Decoder : public GLES2Decoder { MOCK_METHOD0(GetQueryManager, gpu::gles2::QueryManager*()); MOCK_METHOD0(GetVertexArrayManager, gpu::gles2::VertexArrayManager*()); MOCK_METHOD0(GetImageManager, gpu::gles2::ImageManager*()); + MOCK_METHOD0(GetValuebufferManager, gpu::gles2::ValuebufferManager*()); MOCK_METHOD1( SetResizeCallback, void(const base::Callback<void(gfx::Size, float)>&)); MOCK_METHOD0(GetAsyncPixelTransferDelegate, @@ -88,6 +89,7 @@ class MockGLES2Decoder : public GLES2Decoder { MOCK_METHOD1(SetAsyncPixelTransferManagerForTest, void(AsyncPixelTransferManager*)); MOCK_METHOD1(SetIgnoreCachedStateForTest, void(bool ignore)); + MOCK_METHOD1(SetAllowExit, void(bool allow)); MOCK_METHOD3(DoCommand, error::Error(unsigned int command, unsigned int arg_count, const void* cmd_data)); @@ -100,9 +102,8 @@ class MockGLES2Decoder : public GLES2Decoder { uint32* service_texture_id)); MOCK_METHOD0(GetContextLostReason, error::ContextLostReason()); MOCK_CONST_METHOD1(GetCommandName, const char*(unsigned int command_id)); - MOCK_METHOD10(ClearLevel, bool( - unsigned service_id, - unsigned bind_target, + MOCK_METHOD9(ClearLevel, bool( + Texture* texture, unsigned target, int level, unsigned internal_format, @@ -124,9 +125,9 @@ class MockGLES2Decoder : public GLES2Decoder { MOCK_METHOD0(GetTotalTextureUploadTime, base::TimeDelta()); MOCK_METHOD0(GetTotalProcessingCommandsTime, base::TimeDelta()); MOCK_METHOD1(AddProcessingCommandsTime, void(base::TimeDelta)); - MOCK_METHOD0(WasContextLost, bool()); - MOCK_METHOD0(WasContextLostByRobustnessExtension, bool()); - MOCK_METHOD1(LoseContext, void(uint32 reset_status)); + MOCK_CONST_METHOD0(WasContextLost, bool()); + MOCK_CONST_METHOD0(WasContextLostByRobustnessExtension, bool()); + MOCK_METHOD1(MarkContextLost, void(gpu::error::ContextLostReason reason)); DISALLOW_COPY_AND_ASSIGN(MockGLES2Decoder); }; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 43f86063962..1dd2fdc2874 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -16,12 +16,12 @@ #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/gl_surface_mock.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" -#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/program_manager.h" #include "gpu/command_buffer/service/test_helper.h" +#include "gpu/config/gpu_switches.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_mock.h" @@ -57,12 +57,11 @@ using namespace cmds; void GLES2DecoderRGBBackbufferTest::SetUp() { // Test codepath with workaround clear_alpha_in_readpixels because // ReadPixelsEmulator emulates the incorrect driver behavior. - CommandLine command_line(0, NULL); + base::CommandLine command_line(0, NULL); command_line.AppendSwitchASCII( switches::kGpuDriverBugWorkarounds, base::IntToString(gpu::CLEAR_ALPHA_IN_READPIXELS)); InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoderWithCommandLine(init, &command_line); SetupDefaultProgram(); @@ -91,6 +90,23 @@ void GLES2DecoderManualInitTest::EnableDisableTest(GLenum cap, } } +void GLES3DecoderTest::SetUp() { + base::CommandLine command_line(0, NULL); + command_line.AppendSwitch(switches::kEnableUnsafeES3APIs); + InitState init; + init.gl_version = "OpenGL ES 3.0"; + init.bind_generates_resource = true; + InitDecoderWithCommandLine(init, &command_line); +} + + +TEST_P(GLES3DecoderTest, Basic) { + // Make sure the setup is correct for ES3. + EXPECT_TRUE(decoder_->unsafe_es3_apis_enabled()); + EXPECT_TRUE(feature_info()->validators()->texture_bind_target.IsValid( + GL_TEXTURE_3D)); +} + TEST_P(GLES2DecoderTest, GetIntegervCached) { struct TestInfo { GLenum pname; @@ -266,157 +282,117 @@ TEST_P(GLES2DecoderTest, IsTexture) { EXPECT_FALSE(DoIsTexture(client_texture_id_)); } -TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMValidArgs) { - const GLsizei kCount = 3; - GLenum* pnames = GetSharedMemoryAs<GLenum*>(); - pnames[0] = GL_DEPTH_WRITEMASK; - pnames[1] = GL_COLOR_WRITEMASK; - pnames[2] = GL_STENCIL_WRITEMASK; - GLint* results = - GetSharedMemoryAsWithOffset<GLint*>(sizeof(*pnames) * kCount); - - GLsizei num_results = 0; - for (GLsizei ii = 0; ii < kCount; ++ii) { - num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]); - } - const GLsizei result_size = num_results * sizeof(*results); - memset(results, 0, result_size); - - const GLint kSentinel = 0x12345678; - results[num_results] = kSentinel; - - GetMultipleIntegervCHROMIUM cmd; - cmd.Init(kSharedMemoryId, - kSharedMemoryOffset, - kCount, - kSharedMemoryId, - kSharedMemoryOffset + sizeof(*pnames) * kCount, - result_size); - +TEST_P(GLES2DecoderTest, ClientWaitSyncValid) { + typedef cmds::ClientWaitSync::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmds::ClientWaitSync cmd; + uint32_t v32_0 = 0, v32_1 = 0; + GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1); + cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1, + shared_memory_id_, shared_memory_offset_); + EXPECT_CALL(*gl_, + ClientWaitSync(reinterpret_cast<GLsync>(kServiceSyncId), + GL_SYNC_FLUSH_COMMANDS_BIT, 0)) + .WillOnce(Return(GL_CONDITION_SATISFIED)) + .RetiresOnSaturation(); + *result = GL_WAIT_FAILED; + decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), *result); EXPECT_EQ(GL_NO_ERROR, GetGLError()); - EXPECT_EQ(1, results[0]); // Depth writemask - EXPECT_EQ(1, results[1]); // color writemask red - EXPECT_EQ(1, results[2]); // color writemask green - EXPECT_EQ(1, results[3]); // color writemask blue - EXPECT_EQ(1, results[4]); // color writemask alpha - EXPECT_EQ(-1, results[5]); // stencil writemask alpha - EXPECT_EQ(kSentinel, results[num_results]); // End of results + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } -TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMInvalidArgs) { - const GLsizei kCount = 3; - // Offset the pnames because GLGetError will use the first uint32. - const uint32 kPnameOffset = sizeof(uint32); - const uint32 kResultsOffset = kPnameOffset + sizeof(GLint) * kCount; - GLenum* pnames = GetSharedMemoryAsWithOffset<GLenum*>(kPnameOffset); - pnames[0] = GL_DEPTH_WRITEMASK; - pnames[1] = GL_COLOR_WRITEMASK; - pnames[2] = GL_STENCIL_WRITEMASK; - GLint* results = GetSharedMemoryAsWithOffset<GLint*>(kResultsOffset); - - GLsizei num_results = 0; - for (GLsizei ii = 0; ii < kCount; ++ii) { - num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]); - } - const GLsizei result_size = num_results * sizeof(*results); - memset(results, 0, result_size); - - const GLint kSentinel = 0x12345678; - results[num_results] = kSentinel; - - GetMultipleIntegervCHROMIUM cmd; - // Check bad pnames pointer. - cmd.Init(kInvalidSharedMemoryId, - kSharedMemoryOffset + kPnameOffset, - kCount, - kSharedMemoryId, - kSharedMemoryOffset + kResultsOffset, - result_size); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - // Check bad pnames pointer. - cmd.Init(kSharedMemoryId, - kInvalidSharedMemoryOffset, - kCount, - kSharedMemoryId, - kSharedMemoryOffset + kResultsOffset, - result_size); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - // Check bad count. - cmd.Init(kSharedMemoryId, - kSharedMemoryOffset + kPnameOffset, - static_cast<GLuint>(-1), - kSharedMemoryId, - kSharedMemoryOffset + kResultsOffset, - result_size); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - // Check bad results pointer. - cmd.Init(kSharedMemoryId, - kSharedMemoryOffset + kPnameOffset, - kCount, - kInvalidSharedMemoryId, - kSharedMemoryOffset + kResultsOffset, - result_size); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - // Check bad results pointer. - cmd.Init(kSharedMemoryId, - kSharedMemoryOffset + kPnameOffset, - kCount, - kSharedMemoryId, - kInvalidSharedMemoryOffset, - result_size); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - // Check bad size. - cmd.Init(kSharedMemoryId, - kSharedMemoryOffset + kPnameOffset, - kCount, - kSharedMemoryId, - kSharedMemoryOffset + kResultsOffset, - result_size + 1); +TEST_P(GLES2DecoderTest, ClientWaitSyncNonZeroTimeoutValid) { + typedef cmds::ClientWaitSync::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmds::ClientWaitSync cmd; + const GLuint64 kTimeout = 0xABCDEF0123456789; + uint32_t v32_0 = 0, v32_1 = 0; + GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1); + cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1, + shared_memory_id_, shared_memory_offset_); + EXPECT_CALL(*gl_, + ClientWaitSync(reinterpret_cast<GLsync>(kServiceSyncId), + GL_SYNC_FLUSH_COMMANDS_BIT, kTimeout)) + .WillOnce(Return(GL_CONDITION_SATISFIED)) + .RetiresOnSaturation(); + *result = GL_WAIT_FAILED; + decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); - // Check bad size. - cmd.Init(kSharedMemoryId, - kSharedMemoryOffset + kPnameOffset, - kCount, - kSharedMemoryId, - kSharedMemoryOffset + kResultsOffset, - result_size - 1); + EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), *result); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest, ClientWaitSyncInvalidSyncFails) { + typedef cmds::ClientWaitSync::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmds::ClientWaitSync cmd; + uint32_t v32_0 = 0, v32_1 = 0; + GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1); + decoder_->set_unsafe_es3_apis_enabled(true); + cmd.Init(kInvalidClientId, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1, + shared_memory_id_, shared_memory_offset_); + *result = GL_WAIT_FAILED; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(static_cast<GLenum>(GL_WAIT_FAILED), *result); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); - // Check bad enum. - cmd.Init(kSharedMemoryId, - kSharedMemoryOffset + kPnameOffset, - kCount, - kSharedMemoryId, - kSharedMemoryOffset + kResultsOffset, - result_size); - GLenum temp = pnames[2]; - pnames[2] = GL_TRUE; +} + +TEST_P(GLES2DecoderTest, ClientWaitSyncResultNotInitFails) { + typedef cmds::ClientWaitSync::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmds::ClientWaitSync cmd; + uint32_t v32_0 = 0, v32_1 = 0; + GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1); + decoder_->set_unsafe_es3_apis_enabled(true); + cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1, + shared_memory_id_, shared_memory_offset_); + *result = 1; // Any value other than GL_WAIT_FAILED + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest, ClientWaitSyncBadSharedMemoryFails) { + typedef cmds::ClientWaitSync::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmds::ClientWaitSync cmd; + uint32_t v32_0 = 0, v32_1 = 0; + GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1); + decoder_->set_unsafe_es3_apis_enabled(true); + *result = GL_WAIT_FAILED; + cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1, + kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + + *result = GL_WAIT_FAILED; + cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1, + shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest, WaitSyncValidArgs) { + const GLuint64 kTimeout = GL_TIMEOUT_IGNORED; + EXPECT_CALL(*gl_, WaitSync(reinterpret_cast<GLsync>(kServiceSyncId), + 0, kTimeout)) + .Times(1) + .RetiresOnSaturation(); + + uint32_t v32_0 = 0, v32_1 = 0; + GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1); + cmds::WaitSync cmd; + cmd.Init(client_sync_id_, 0, v32_0, v32_1); + decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); - pnames[2] = temp; - // Check results area has not been cleared by client. - results[1] = 1; - EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd)); - // Check buffer is what we expect - EXPECT_EQ(0, results[0]); - EXPECT_EQ(1, results[1]); - EXPECT_EQ(0, results[2]); - EXPECT_EQ(0, results[3]); - EXPECT_EQ(0, results[4]); - EXPECT_EQ(0, results[5]); - EXPECT_EQ(kSentinel, results[num_results]); // End of results + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } TEST_P(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); BindTexture cmd1; @@ -484,10 +460,10 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) { GenHelper<GenQueriesEXTImmediate>(kNewClientId); // Test valid parameters work. - EXPECT_CALL(*gl_, GenQueriesARB(1, _)) + EXPECT_CALL(*gl_, GenQueries(1, _)) .WillOnce(SetArgumentPointee<1>(kNewServiceId)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId)) + EXPECT_CALL(*gl_, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId)) .Times(1) .RetiresOnSaturation(); @@ -527,7 +503,7 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) { EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); // Test end succeeds - EXPECT_CALL(*gl_, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT)) + EXPECT_CALL(*gl_, EndQuery(GL_ANY_SAMPLES_PASSED_EXT)) .Times(1) .RetiresOnSaturation(); end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1); @@ -535,7 +511,7 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); EXPECT_TRUE(query->pending()); - EXPECT_CALL(*gl_, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation(); + EXPECT_CALL(*gl_, DeleteQueries(1, _)).Times(1).RetiresOnSaturation(); } struct QueryType { @@ -575,10 +551,10 @@ static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test, test->GenHelper<GenQueriesEXTImmediate>(client_id); if (query_type.is_gl) { - EXPECT_CALL(*gl, GenQueriesARB(1, _)) + EXPECT_CALL(*gl, GenQueries(1, _)) .WillOnce(SetArgumentPointee<1>(service_id)) .RetiresOnSaturation(); - EXPECT_CALL(*gl, BeginQueryARB(query_type.type, service_id)) + EXPECT_CALL(*gl, BeginQuery(query_type.type, service_id)) .Times(1) .RetiresOnSaturation(); } @@ -588,7 +564,7 @@ static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test, error::Error error1 = test->ExecuteCmd(begin_cmd); if (query_type.is_gl) { - EXPECT_CALL(*gl, EndQueryARB(query_type.type)) + EXPECT_CALL(*gl, EndQuery(query_type.type)) .Times(1) .RetiresOnSaturation(); } @@ -603,7 +579,7 @@ static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test, EXPECT_CALL(*gl, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)) .WillOnce(Return(kGlSync)) .RetiresOnSaturation(); -#if DCHECK_IS_ON +#if DCHECK_IS_ON() EXPECT_CALL(*gl, IsSync(kGlSync)) .WillOnce(Return(GL_TRUE)) .RetiresOnSaturation(); @@ -616,15 +592,15 @@ static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test, if (query_type.is_gl) { EXPECT_CALL( - *gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + *gl, GetQueryObjectuiv(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) .WillOnce(SetArgumentPointee<2>(1)) .RetiresOnSaturation(); - EXPECT_CALL(*gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_EXT, _)) + EXPECT_CALL(*gl, GetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, _)) .WillOnce(SetArgumentPointee<2>(1)) .RetiresOnSaturation(); } if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) { -#if DCHECK_IS_ON +#if DCHECK_IS_ON() EXPECT_CALL(*gl, IsSync(kGlSync)) .WillOnce(Return(GL_TRUE)) .RetiresOnSaturation(); @@ -642,10 +618,10 @@ static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test, !process_success); if (query_type.is_gl) { - EXPECT_CALL(*gl, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation(); + EXPECT_CALL(*gl, DeleteQueries(1, _)).Times(1).RetiresOnSaturation(); } if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) { -#if DCHECK_IS_ON +#if DCHECK_IS_ON() EXPECT_CALL(*gl, IsSync(kGlSync)) .WillOnce(Return(GL_TRUE)) .RetiresOnSaturation(); @@ -777,7 +753,7 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) { EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)) .WillOnce(Return(kGlSync)) .RetiresOnSaturation(); -#if DCHECK_IS_ON +#if DCHECK_IS_ON() EXPECT_CALL(*gl_, IsSync(kGlSync)) .WillOnce(Return(GL_TRUE)) .RetiresOnSaturation(); @@ -789,7 +765,7 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); EXPECT_TRUE(query->pending()); -#if DCHECK_IS_ON +#if DCHECK_IS_ON() EXPECT_CALL(*gl_, IsSync(kGlSync)) .WillOnce(Return(GL_TRUE)) .RetiresOnSaturation(); @@ -802,7 +778,7 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) { EXPECT_TRUE(process_success); EXPECT_TRUE(query->pending()); -#if DCHECK_IS_ON +#if DCHECK_IS_ON() EXPECT_CALL(*gl_, IsSync(kGlSync)) .WillOnce(Return(GL_TRUE)) .RetiresOnSaturation(); @@ -814,10 +790,8 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) { EXPECT_TRUE(process_success); EXPECT_FALSE(query->pending()); - QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_); - EXPECT_EQ(static_cast<GLenum>(0), static_cast<GLenum>(sync->result)); -#if DCHECK_IS_ON +#if DCHECK_IS_ON() EXPECT_CALL(*gl_, IsSync(kGlSync)) .WillOnce(Return(GL_TRUE)) .RetiresOnSaturation(); @@ -854,7 +828,6 @@ TEST_P(GLES2DecoderTest, IsEnabledReturnsCachedValue) { TEST_P(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) { InitState init; init.extensions = "GL_ARB_texture_rectangle"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); @@ -930,7 +903,6 @@ TEST_P(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) { new SizeOnlyMemoryTracker(); set_memory_tracker(memory_tracker.get()); InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); // Expect that initial size - size is 0. @@ -943,7 +915,6 @@ TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) { new SizeOnlyMemoryTracker(); set_memory_tracker(memory_tracker.get()); InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); @@ -1000,7 +971,6 @@ TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) { new SizeOnlyMemoryTracker(); set_memory_tracker(memory_tracker.get()); InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); @@ -1027,7 +997,6 @@ TEST_P(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) { new SizeOnlyMemoryTracker(); set_memory_tracker(memory_tracker.get()); InitState init; - init.gl_version = "3.0"; init.has_alpha = true; init.request_alpha = true; init.bind_generates_resource = true; @@ -1064,7 +1033,6 @@ TEST_P(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) { new SizeOnlyMemoryTracker(); set_memory_tracker(memory_tracker.get()); InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); DoBindRenderbuffer( @@ -1100,7 +1068,6 @@ TEST_P(GLES2DecoderManualInitTest, MemoryTrackerBufferData) { new SizeOnlyMemoryTracker(); set_memory_tracker(memory_tracker.get()); InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); @@ -1139,7 +1106,6 @@ TEST_P(GLES2DecoderManualInitTest, ImmutableCopyTexImage2D) { const GLint kBorder = 0; InitState init; init.extensions = "GL_EXT_texture_storage"; - init.gl_version = "3.0"; init.has_alpha = true; init.request_alpha = true; init.bind_generates_resource = true; @@ -1176,17 +1142,30 @@ TEST_P(GLES2DecoderManualInitTest, ImmutableCopyTexImage2D) { EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } -TEST_P(GLES2DecoderTest, LoseContextCHROMIUMValidArgs) { - EXPECT_CALL(*mock_decoder_, LoseContext(GL_GUILTY_CONTEXT_RESET_ARB)) +TEST_P(GLES2DecoderTest, LoseContextCHROMIUMGuilty) { + EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kInnocent)) .Times(1); cmds::LoseContextCHROMIUM cmd; - cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_GUILTY_CONTEXT_RESET_ARB); + cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension()); +} + +TEST_P(GLES2DecoderTest, LoseContextCHROMIUMUnkown) { + EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)) + .Times(1); + cmds::LoseContextCHROMIUM cmd; + cmd.Init(GL_UNKNOWN_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB); + EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension()); } TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs0_0) { - EXPECT_CALL(*mock_decoder_, LoseContext(_)) + EXPECT_CALL(*mock_decoder_, MarkContextLost(_)) .Times(0); cmds::LoseContextCHROMIUM cmd; cmd.Init(GL_NONE, GL_GUILTY_CONTEXT_RESET_ARB); @@ -1195,7 +1174,7 @@ TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs0_0) { } TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs1_0) { - EXPECT_CALL(*mock_decoder_, LoseContext(_)) + EXPECT_CALL(*mock_decoder_, MarkContextLost(_)) .Times(0); cmds::LoseContextCHROMIUM cmd; cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_NONE); @@ -1313,5 +1292,7 @@ INSTANTIATE_TEST_CASE_P(Service, INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderDoCommandsTest, ::testing::Bool()); +INSTANTIATE_TEST_CASE_P(Service, GLES3DecoderTest, ::testing::Bool()); + } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h index 0ea7d4ba854..a57903c5e33 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h @@ -74,6 +74,14 @@ class GLES2DecoderManualInitTest : public GLES2DecoderWithShaderTest { void EnableDisableTest(GLenum cap, bool enable, bool expect_set); }; +class GLES3DecoderTest : public GLES2DecoderTest { + public: + GLES3DecoderTest() {} + + // Override default setup so ES3 capabilities are enabled by default. + void SetUp() override; +}; + } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h index 0aca4df3fa3..16204238d7b 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h @@ -12,7 +12,7 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_0_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_0_AUTOGEN_H_ -void GLES2DecoderTestBase::SetupInitCapabilitiesExpectations() { +void GLES2DecoderTestBase::SetupInitCapabilitiesExpectations(bool es3_capable) { ExpectEnableDisable(GL_BLEND, false); ExpectEnableDisable(GL_CULL_FACE, false); ExpectEnableDisable(GL_DEPTH_TEST, false); @@ -22,6 +22,10 @@ void GLES2DecoderTestBase::SetupInitCapabilitiesExpectations() { ExpectEnableDisable(GL_SAMPLE_COVERAGE, false); ExpectEnableDisable(GL_SCISSOR_TEST, false); ExpectEnableDisable(GL_STENCIL_TEST, false); + if (es3_capable) { + ExpectEnableDisable(GL_RASTERIZER_DISCARD, false); + ExpectEnableDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX, false); + } } void GLES2DecoderTestBase::SetupInitStateExpectations() { diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc index 912e9085fa8..3fb52f9bc13 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc @@ -161,14 +161,6 @@ void GLES2DecoderTestBase::SpecializedSetup< }; template <> -void GLES2DecoderTestBase::SpecializedSetup< - cmds::GetRenderbufferParameteriv, 0>( - bool /* valid */) { - DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_, - kServiceRenderbufferId); -}; - -template <> void GLES2DecoderTestBase::SpecializedSetup<cmds::GetProgramiv, 0>( bool valid) { if (valid) { @@ -248,57 +240,10 @@ void GLES2DecoderTestBase::SpecializedSetup<cmds::GetProgramInfoLog, 0>( attach_cmd.Init(client_program_id_, kClientFragmentShaderId); EXPECT_EQ(error::kNoError, ExecuteCmd(attach_cmd)); - program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + program->Link(NULL, Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)); }; -template <> -void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribfv, 0>( - bool valid) { - DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); - DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0); - if (valid) { - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - } -}; - -template <> -void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribiv, 0>( - bool valid) { - DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); - DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0); - if (valid) { - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - } -}; - -template <> -void GLES2DecoderTestBase::SpecializedSetup<cmds::RenderbufferStorage, 0>( - bool valid) { - DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_, - kServiceRenderbufferId); - if (valid) { - EnsureRenderbufferBound(false); - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - RenderbufferStorageEXT(GL_RENDERBUFFER, _, 3, 4)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - } -} - - #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h" } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h index 6fe923c1190..7881a55c8aa 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h @@ -54,6 +54,64 @@ TEST_P(GLES2DecoderTest1, BindBufferInvalidArgs0_0) { EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } +TEST_P(GLES2DecoderTest1, BindBufferBaseValidArgs) { + EXPECT_CALL( + *gl_, BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kServiceBufferId)); + SpecializedSetup<cmds::BindBufferBase, 0>(true); + cmds::BindBufferBase cmd; + cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, client_buffer_id_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest1, BindBufferBaseValidArgsNewId) { + EXPECT_CALL(*gl_, + BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewServiceId)); + EXPECT_CALL(*gl_, GenBuffersARB(1, _)) + .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + SpecializedSetup<cmds::BindBufferBase, 0>(true); + cmds::BindBufferBase cmd; + cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewClientId); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_TRUE(GetBuffer(kNewClientId) != NULL); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest1, BindBufferRangeValidArgs) { + EXPECT_CALL(*gl_, BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 2, + kServiceBufferId, 4, 4)); + SpecializedSetup<cmds::BindBufferRange, 0>(true); + cmds::BindBufferRange cmd; + cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, client_buffer_id_, 4, 4); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest1, BindBufferRangeValidArgsNewId) { + EXPECT_CALL(*gl_, BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 2, + kNewServiceId, 4, 4)); + EXPECT_CALL(*gl_, GenBuffersARB(1, _)) + .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + SpecializedSetup<cmds::BindBufferRange, 0>(true); + cmds::BindBufferRange cmd; + cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewClientId, 4, 4); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_TRUE(GetBuffer(kNewClientId) != NULL); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest1, BindFramebufferValidArgs) { EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER, kServiceFramebufferId)); SpecializedSetup<cmds::BindFramebuffer, 0>(true); @@ -79,16 +137,7 @@ TEST_P(GLES2DecoderTest1, BindFramebufferInvalidArgs0_0) { EXPECT_CALL(*gl_, BindFramebufferEXT(_, _)).Times(0); SpecializedSetup<cmds::BindFramebuffer, 0>(false); cmds::BindFramebuffer cmd; - cmd.Init(GL_DRAW_FRAMEBUFFER, client_framebuffer_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, BindFramebufferInvalidArgs0_1) { - EXPECT_CALL(*gl_, BindFramebufferEXT(_, _)).Times(0); - SpecializedSetup<cmds::BindFramebuffer, 0>(false); - cmds::BindFramebuffer cmd; - cmd.Init(GL_READ_FRAMEBUFFER, client_framebuffer_id_); + cmd.Init(GL_RENDERBUFFER, client_framebuffer_id_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -124,6 +173,18 @@ TEST_P(GLES2DecoderTest1, BindRenderbufferInvalidArgs0_0) { EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } +TEST_P(GLES2DecoderTest1, BindSamplerValidArgs) { + EXPECT_CALL(*gl_, BindSampler(1, kServiceSamplerId)); + SpecializedSetup<cmds::BindSampler, 0>(true); + cmds::BindSampler cmd; + cmd.Init(1, client_sampler_id_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest1, BindTextureValidArgs) { EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId)); SpecializedSetup<cmds::BindTexture, 0>(true); @@ -163,6 +224,19 @@ TEST_P(GLES2DecoderTest1, BindTextureInvalidArgs0_1) { EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } +TEST_P(GLES2DecoderTest1, BindTransformFeedbackValidArgs) { + EXPECT_CALL(*gl_, BindTransformFeedback(GL_TRANSFORM_FEEDBACK, + kServiceTransformFeedbackId)); + SpecializedSetup<cmds::BindTransformFeedback, 0>(true); + cmds::BindTransformFeedback cmd; + cmd.Init(GL_TRANSFORM_FEEDBACK, client_transformfeedback_id_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest1, BlendColorValidArgs) { EXPECT_CALL(*gl_, BlendColor(1, 2, 3, 4)); SpecializedSetup<cmds::BlendColor, 0>(true); @@ -185,16 +259,7 @@ TEST_P(GLES2DecoderTest1, BlendEquationInvalidArgs0_0) { EXPECT_CALL(*gl_, BlendEquation(_)).Times(0); SpecializedSetup<cmds::BlendEquation, 0>(false); cmds::BlendEquation cmd; - cmd.Init(GL_MIN); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, BlendEquationInvalidArgs0_1) { - EXPECT_CALL(*gl_, BlendEquation(_)).Times(0); - SpecializedSetup<cmds::BlendEquation, 0>(false); - cmds::BlendEquation cmd; - cmd.Init(GL_MAX); + cmd.Init(GL_NONE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -212,16 +277,7 @@ TEST_P(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs0_0) { EXPECT_CALL(*gl_, BlendEquationSeparate(_, _)).Times(0); SpecializedSetup<cmds::BlendEquationSeparate, 0>(false); cmds::BlendEquationSeparate cmd; - cmd.Init(GL_MIN, GL_FUNC_ADD); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs0_1) { - EXPECT_CALL(*gl_, BlendEquationSeparate(_, _)).Times(0); - SpecializedSetup<cmds::BlendEquationSeparate, 0>(false); - cmds::BlendEquationSeparate cmd; - cmd.Init(GL_MAX, GL_FUNC_ADD); + cmd.Init(GL_NONE, GL_FUNC_ADD); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -230,16 +286,7 @@ TEST_P(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs1_0) { EXPECT_CALL(*gl_, BlendEquationSeparate(_, _)).Times(0); SpecializedSetup<cmds::BlendEquationSeparate, 0>(false); cmds::BlendEquationSeparate cmd; - cmd.Init(GL_FUNC_SUBTRACT, GL_MIN); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs1_1) { - EXPECT_CALL(*gl_, BlendEquationSeparate(_, _)).Times(0); - SpecializedSetup<cmds::BlendEquationSeparate, 0>(false); - cmds::BlendEquationSeparate cmd; - cmd.Init(GL_FUNC_SUBTRACT, GL_MAX); + cmd.Init(GL_FUNC_SUBTRACT, GL_NONE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -278,16 +325,7 @@ TEST_P(GLES2DecoderTest1, CheckFramebufferStatusInvalidArgs0_0) { EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(_)).Times(0); SpecializedSetup<cmds::CheckFramebufferStatus, 0>(false); cmds::CheckFramebufferStatus cmd; - cmd.Init(GL_DRAW_FRAMEBUFFER, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, CheckFramebufferStatusInvalidArgs0_1) { - EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(_)).Times(0); - SpecializedSetup<cmds::CheckFramebufferStatus, 0>(false); - cmds::CheckFramebufferStatus cmd; - cmd.Init(GL_READ_FRAMEBUFFER, shared_memory_id_, shared_memory_offset_); + cmd.Init(GL_RENDERBUFFER, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -311,6 +349,72 @@ TEST_P(GLES2DecoderTest1, ClearValidArgs) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +TEST_P(GLES2DecoderTest1, ClearBufferfiValidArgs) { + EXPECT_CALL(*gl_, ClearBufferfi(GL_COLOR, 2, 3, 4)); + SpecializedSetup<cmds::ClearBufferfi, 0>(true); + cmds::ClearBufferfi cmd; + cmd.Init(GL_COLOR, 2, 3, 4); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest1, ClearBufferfvImmediateValidArgs) { + cmds::ClearBufferfvImmediate& cmd = + *GetImmediateAs<cmds::ClearBufferfvImmediate>(); + SpecializedSetup<cmds::ClearBufferfvImmediate, 0>(true); + GLfloat temp[4] = { + 0, + }; + cmd.Init(GL_COLOR, 2, &temp[0]); + EXPECT_CALL(*gl_, + ClearBufferfv(GL_COLOR, 2, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest1, ClearBufferivImmediateValidArgs) { + cmds::ClearBufferivImmediate& cmd = + *GetImmediateAs<cmds::ClearBufferivImmediate>(); + SpecializedSetup<cmds::ClearBufferivImmediate, 0>(true); + GLint temp[4] = { + 0, + }; + cmd.Init(GL_COLOR, 2, &temp[0]); + EXPECT_CALL(*gl_, ClearBufferiv( + GL_COLOR, 2, + reinterpret_cast<GLint*>(ImmediateDataAddress(&cmd)))); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest1, ClearBufferuivImmediateValidArgs) { + cmds::ClearBufferuivImmediate& cmd = + *GetImmediateAs<cmds::ClearBufferuivImmediate>(); + SpecializedSetup<cmds::ClearBufferuivImmediate, 0>(true); + GLuint temp[4] = { + 0, + }; + cmd.Init(GL_COLOR, 2, &temp[0]); + EXPECT_CALL(*gl_, ClearBufferuiv( + GL_COLOR, 2, + reinterpret_cast<GLuint*>(ImmediateDataAddress(&cmd)))); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + TEST_P(GLES2DecoderTest1, ClearColorValidArgs) { EXPECT_CALL(*gl_, ClearColor(1, 2, 3, 4)); SpecializedSetup<cmds::ClearColor, 0>(true); @@ -337,6 +441,7 @@ TEST_P(GLES2DecoderTest1, ClearStencilValidArgs) { EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +// TODO(gman): ClientWaitSync TEST_P(GLES2DecoderTest1, ColorMaskValidArgs) { SpecializedSetup<cmds::ColorMask, 0>(true); @@ -352,6 +457,24 @@ TEST_P(GLES2DecoderTest1, ColorMaskValidArgs) { // TODO(gman): CompressedTexSubImage2DBucket // TODO(gman): CompressedTexSubImage2D +// TODO(gman): CompressedTexImage3DBucket +// TODO(gman): CompressedTexImage3D + +// TODO(gman): CompressedTexSubImage3DBucket +// TODO(gman): CompressedTexSubImage3D + +TEST_P(GLES2DecoderTest1, CopyBufferSubDataValidArgs) { + EXPECT_CALL(*gl_, + CopyBufferSubData(GL_ARRAY_BUFFER, GL_ARRAY_BUFFER, 3, 4, 5)); + SpecializedSetup<cmds::CopyBufferSubData, 0>(true); + cmds::CopyBufferSubData cmd; + cmd.Init(GL_ARRAY_BUFFER, GL_ARRAY_BUFFER, 3, 4, 5); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} // TODO(gman): CopyTexImage2D TEST_P(GLES2DecoderTest1, CopyTexSubImage2DValidArgs) { @@ -390,6 +513,18 @@ TEST_P(GLES2DecoderTest1, CopyTexSubImage2DInvalidArgs7_0) { EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); } +TEST_P(GLES2DecoderTest1, CopyTexSubImage3DValidArgs) { + EXPECT_CALL(*gl_, CopyTexSubImage3D(GL_TEXTURE_3D, 2, 3, 4, 5, 6, 7, 8, 9)); + SpecializedSetup<cmds::CopyTexSubImage3D, 0>(true); + cmds::CopyTexSubImage3D cmd; + cmd.Init(GL_TEXTURE_3D, 2, 3, 4, 5, 6, 7, 8, 9); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest1, CreateProgramValidArgs) { EXPECT_CALL(*gl_, CreateProgram()).WillOnce(Return(kNewServiceId)); SpecializedSetup<cmds::CreateProgram, 0>(true); @@ -397,7 +532,7 @@ TEST_P(GLES2DecoderTest1, CreateProgramValidArgs) { cmd.Init(kNewClientId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); - EXPECT_TRUE(GetProgram(kNewClientId) != NULL); + EXPECT_TRUE(GetProgram(kNewClientId)); } TEST_P(GLES2DecoderTest1, CreateShaderValidArgs) { @@ -408,7 +543,7 @@ TEST_P(GLES2DecoderTest1, CreateShaderValidArgs) { cmd.Init(GL_VERTEX_SHADER, kNewClientId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); - EXPECT_TRUE(GetShader(kNewClientId) != NULL); + EXPECT_TRUE(GetShader(kNewClientId)); } TEST_P(GLES2DecoderTest1, CreateShaderInvalidArgs0_0) { @@ -503,6 +638,46 @@ TEST_P(GLES2DecoderTest1, DeleteRenderbuffersImmediateInvalidArgs) { EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); } +TEST_P(GLES2DecoderTest1, DeleteSamplersImmediateValidArgs) { + EXPECT_CALL(*gl_, DeleteSamplers(1, Pointee(kServiceSamplerId))).Times(1); + cmds::DeleteSamplersImmediate& cmd = + *GetImmediateAs<cmds::DeleteSamplersImmediate>(); + SpecializedSetup<cmds::DeleteSamplersImmediate, 0>(true); + cmd.Init(1, &client_sampler_id_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, + ExecuteImmediateCmd(cmd, sizeof(client_sampler_id_))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_FALSE(GetSamplerServiceId(client_sampler_id_, NULL)); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, + ExecuteImmediateCmd(cmd, sizeof(client_sampler_id_))); +} + +TEST_P(GLES2DecoderTest1, DeleteSamplersImmediateInvalidArgs) { + cmds::DeleteSamplersImmediate& cmd = + *GetImmediateAs<cmds::DeleteSamplersImmediate>(); + SpecializedSetup<cmds::DeleteSamplersImmediate, 0>(false); + GLuint temp = kInvalidClientId; + cmd.Init(1, &temp); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest1, DeleteSyncValidArgs) { + EXPECT_CALL(*gl_, DeleteSync(reinterpret_cast<GLsync>(kServiceSyncId))); + SpecializedSetup<cmds::DeleteSync, 0>(true); + cmds::DeleteSync cmd; + cmd.Init(client_sync_id_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest1, DeleteShaderValidArgs) { EXPECT_CALL(*gl_, DeleteShader(kServiceShaderId)); SpecializedSetup<cmds::DeleteShader, 0>(true); @@ -533,6 +708,36 @@ TEST_P(GLES2DecoderTest1, DeleteTexturesImmediateInvalidArgs) { EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); } +TEST_P(GLES2DecoderTest1, DeleteTransformFeedbacksImmediateValidArgs) { + EXPECT_CALL(*gl_, DeleteTransformFeedbacks( + 1, Pointee(kServiceTransformFeedbackId))).Times(1); + cmds::DeleteTransformFeedbacksImmediate& cmd = + *GetImmediateAs<cmds::DeleteTransformFeedbacksImmediate>(); + SpecializedSetup<cmds::DeleteTransformFeedbacksImmediate, 0>(true); + cmd.Init(1, &client_transformfeedback_id_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, + ExecuteImmediateCmd(cmd, sizeof(client_transformfeedback_id_))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_FALSE( + GetTransformFeedbackServiceId(client_transformfeedback_id_, NULL)); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, + ExecuteImmediateCmd(cmd, sizeof(client_transformfeedback_id_))); +} + +TEST_P(GLES2DecoderTest1, DeleteTransformFeedbacksImmediateInvalidArgs) { + cmds::DeleteTransformFeedbacksImmediate& cmd = + *GetImmediateAs<cmds::DeleteTransformFeedbacksImmediate>(); + SpecializedSetup<cmds::DeleteTransformFeedbacksImmediate, 0>(false); + GLuint temp = kInvalidClientId; + cmd.Init(1, &temp); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + TEST_P(GLES2DecoderTest1, DepthFuncValidArgs) { EXPECT_CALL(*gl_, DepthFunc(GL_NEVER)); SpecializedSetup<cmds::DepthFunc, 0>(true); @@ -643,6 +848,23 @@ TEST_P(GLES2DecoderTest1, EnableVertexAttribArrayValidArgs) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +TEST_P(GLES2DecoderTest1, FenceSyncValidArgs) { + const GLsync kNewServiceIdGLuint = reinterpret_cast<GLsync>(kNewServiceId); + EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)) + .WillOnce(Return(kNewServiceIdGLuint)); + SpecializedSetup<cmds::FenceSync, 0>(true); + cmds::FenceSync cmd; + cmd.Init(kNewClientId); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + GLsync service_id = 0; + EXPECT_TRUE(GetSyncServiceId(kNewClientId, &service_id)); + EXPECT_EQ(kNewServiceIdGLuint, service_id); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest1, FinishValidArgs) { EXPECT_CALL(*gl_, Finish()); SpecializedSetup<cmds::Finish, 0>(true); @@ -677,17 +899,7 @@ TEST_P(GLES2DecoderTest1, FramebufferRenderbufferInvalidArgs0_0) { EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(_, _, _, _)).Times(0); SpecializedSetup<cmds::FramebufferRenderbuffer, 0>(false); cmds::FramebufferRenderbuffer cmd; - cmd.Init(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, - client_renderbuffer_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, FramebufferRenderbufferInvalidArgs0_1) { - EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(_, _, _, _)).Times(0); - SpecializedSetup<cmds::FramebufferRenderbuffer, 0>(false); - cmds::FramebufferRenderbuffer cmd; - cmd.Init(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + cmd.Init(GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, client_renderbuffer_id_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); @@ -719,30 +931,34 @@ TEST_P(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs0_0) { EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0); SpecializedSetup<cmds::FramebufferTexture2D, 0>(false); cmds::FramebufferTexture2D cmd; - cmd.Init(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + cmd.Init(GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } -TEST_P(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs0_1) { +TEST_P(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs2_0) { EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0); SpecializedSetup<cmds::FramebufferTexture2D, 0>(false); cmds::FramebufferTexture2D cmd; - cmd.Init(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_PROXY_TEXTURE_CUBE_MAP, client_texture_id_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } -TEST_P(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs2_0) { - EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0); - SpecializedSetup<cmds::FramebufferTexture2D, 0>(false); - cmds::FramebufferTexture2D cmd; - cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_PROXY_TEXTURE_CUBE_MAP, - client_texture_id_); +TEST_P(GLES2DecoderTest1, FramebufferTextureLayerValidArgs) { + EXPECT_CALL(*gl_, + FramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + kServiceTextureId, 4, 5)); + SpecializedSetup<cmds::FramebufferTextureLayer, 0>(true); + cmds::FramebufferTextureLayer cmd; + cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, client_texture_id_, 4, 5); + decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } TEST_P(GLES2DecoderTest1, FrontFaceValidArgs) { @@ -848,6 +1064,36 @@ TEST_P(GLES2DecoderTest1, GenRenderbuffersImmediateInvalidArgs) { ExecuteImmediateCmd(*cmd, sizeof(&client_renderbuffer_id_))); } +TEST_P(GLES2DecoderTest1, GenSamplersImmediateValidArgs) { + EXPECT_CALL(*gl_, GenSamplers(1, _)) + .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + cmds::GenSamplersImmediate* cmd = + GetImmediateAs<cmds::GenSamplersImmediate>(); + GLuint temp = kNewClientId; + SpecializedSetup<cmds::GenSamplersImmediate, 0>(true); + decoder_->set_unsafe_es3_apis_enabled(true); + cmd->Init(1, &temp); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + GLuint service_id; + EXPECT_TRUE(GetSamplerServiceId(kNewClientId, &service_id)); + EXPECT_EQ(kNewServiceId, service_id); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(*cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest1, GenSamplersImmediateInvalidArgs) { + EXPECT_CALL(*gl_, GenSamplers(_, _)).Times(0); + cmds::GenSamplersImmediate* cmd = + GetImmediateAs<cmds::GenSamplersImmediate>(); + SpecializedSetup<cmds::GenSamplersImmediate, 0>(false); + cmd->Init(1, &client_sampler_id_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kInvalidArguments, + ExecuteImmediateCmd(*cmd, sizeof(&client_sampler_id_))); + decoder_->set_unsafe_es3_apis_enabled(false); +} + TEST_P(GLES2DecoderTest1, GenTexturesImmediateValidArgs) { EXPECT_CALL(*gl_, GenTextures(1, _)) .WillOnce(SetArgumentPointee<1>(kNewServiceId)); @@ -870,10 +1116,46 @@ TEST_P(GLES2DecoderTest1, GenTexturesImmediateInvalidArgs) { EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(&client_texture_id_))); } + +TEST_P(GLES2DecoderTest1, GenTransformFeedbacksImmediateValidArgs) { + EXPECT_CALL(*gl_, GenTransformFeedbacks(1, _)) + .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + cmds::GenTransformFeedbacksImmediate* cmd = + GetImmediateAs<cmds::GenTransformFeedbacksImmediate>(); + GLuint temp = kNewClientId; + SpecializedSetup<cmds::GenTransformFeedbacksImmediate, 0>(true); + decoder_->set_unsafe_es3_apis_enabled(true); + cmd->Init(1, &temp); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + GLuint service_id; + EXPECT_TRUE(GetTransformFeedbackServiceId(kNewClientId, &service_id)); + EXPECT_EQ(kNewServiceId, service_id); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(*cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest1, GenTransformFeedbacksImmediateInvalidArgs) { + EXPECT_CALL(*gl_, GenTransformFeedbacks(_, _)).Times(0); + cmds::GenTransformFeedbacksImmediate* cmd = + GetImmediateAs<cmds::GenTransformFeedbacksImmediate>(); + SpecializedSetup<cmds::GenTransformFeedbacksImmediate, 0>(false); + cmd->Init(1, &client_transformfeedback_id_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kInvalidArguments, + ExecuteImmediateCmd(*cmd, sizeof(&client_transformfeedback_id_))); + decoder_->set_unsafe_es3_apis_enabled(false); +} // TODO(gman): GetActiveAttrib // TODO(gman): GetActiveUniform +// TODO(gman): GetActiveUniformBlockiv + +// TODO(gman): GetActiveUniformBlockName + +// TODO(gman): GetActiveUniformsiv + // TODO(gman): GetAttachedShaders // TODO(gman): GetAttribLocation @@ -1073,6 +1355,7 @@ TEST_P(GLES2DecoderTest1, GetFloatvInvalidArgs1_1) { EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); EXPECT_EQ(0u, result->size); } +// TODO(gman): GetFragDataLocation TEST_P(GLES2DecoderTest1, GetFramebufferAttachmentParameterivValidArgs) { EXPECT_CALL(*gl_, GetError()) @@ -1107,24 +1390,7 @@ TEST_P(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs0_0) { shared_memory_address_); result->size = 0; cmds::GetFramebufferAttachmentParameteriv cmd; - cmd.Init(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs0_1) { - EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _)) - .Times(0); - SpecializedSetup<cmds::GetFramebufferAttachmentParameteriv, 0>(false); - cmds::GetFramebufferAttachmentParameteriv::Result* result = - static_cast<cmds::GetFramebufferAttachmentParameteriv::Result*>( - shared_memory_address_); - result->size = 0; - cmds::GetFramebufferAttachmentParameteriv cmd; - cmd.Init(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + cmd.Init(GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1163,6 +1429,75 @@ TEST_P(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs3_1) { EXPECT_EQ(0u, result->size); } +TEST_P(GLES2DecoderTest1, GetInteger64vValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetInteger64v, 0>(true); + typedef cmds::GetInteger64v::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL(*gl_, GetInteger64v(GL_ACTIVE_TEXTURE, result->GetData())); + result->size = 0; + cmds::GetInteger64v cmd; + cmd.Init(GL_ACTIVE_TEXTURE, shared_memory_id_, shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ACTIVE_TEXTURE), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest1, GetIntegeri_vValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetIntegeri_v, 0>(true); + typedef cmds::GetIntegeri_v::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL(*gl_, GetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 2, + result->GetData())); + result->size = 0; + cmds::GetIntegeri_v cmd; + cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 2, shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( + GL_TRANSFORM_FEEDBACK_BUFFER_BINDING), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest1, GetInteger64i_vValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetInteger64i_v, 0>(true); + typedef cmds::GetInteger64i_v::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL(*gl_, GetInteger64i_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 2, + result->GetData())); + result->size = 0; + cmds::GetInteger64i_v cmd; + cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 2, shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( + GL_TRANSFORM_FEEDBACK_BUFFER_BINDING), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest1, GetIntegervValidArgs) { EXPECT_CALL(*gl_, GetError()) .WillOnce(Return(GL_NO_ERROR)) @@ -1218,6 +1553,31 @@ TEST_P(GLES2DecoderTest1, GetIntegervInvalidArgs1_1) { EXPECT_EQ(0u, result->size); } +TEST_P(GLES2DecoderTest1, GetInternalformativValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetInternalformativ, 0>(true); + typedef cmds::GetInternalformativ::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL( + *gl_, GetInternalformativ(GL_RENDERBUFFER, GL_RGBA4, GL_NUM_SAMPLE_COUNTS, + 4, result->GetData())); + result->size = 0; + cmds::GetInternalformativ cmd; + cmd.Init(GL_RENDERBUFFER, GL_RGBA4, GL_NUM_SAMPLE_COUNTS, 4, + shared_memory_id_, shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ( + decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_NUM_SAMPLE_COUNTS), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest1, GetProgramivValidArgs) { SpecializedSetup<cmds::GetProgramiv, 0>(true); typedef cmds::GetProgramiv::Result Result; @@ -1232,6 +1592,20 @@ TEST_P(GLES2DecoderTest1, GetProgramivValidArgs) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +TEST_P(GLES2DecoderTest1, GetProgramivInvalidArgs1_0) { + EXPECT_CALL(*gl_, GetProgramiv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetProgramiv, 0>(false); + cmds::GetProgramiv::Result* result = + static_cast<cmds::GetProgramiv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetProgramiv cmd; + cmd.Init(client_program_id_, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + TEST_P(GLES2DecoderTest1, GetProgramivInvalidArgs2_0) { EXPECT_CALL(*gl_, GetProgramiv(_, _, _)).Times(0); SpecializedSetup<cmds::GetProgramiv, 0>(false); @@ -1280,603 +1654,4 @@ TEST_P(GLES2DecoderTest1, GetProgramInfoLogInvalidArgs) { EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); } - -TEST_P(GLES2DecoderTest1, GetRenderbufferParameterivValidArgs) { - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - SpecializedSetup<cmds::GetRenderbufferParameteriv, 0>(true); - typedef cmds::GetRenderbufferParameteriv::Result Result; - Result* result = static_cast<Result*>(shared_memory_address_); - EXPECT_CALL( - *gl_, GetRenderbufferParameterivEXT( - GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, result->GetData())); - result->size = 0; - cmds::GetRenderbufferParameteriv cmd; - cmd.Init(GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( - GL_RENDERBUFFER_RED_SIZE), - result->GetNumResults()); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs0_0) { - EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0); - SpecializedSetup<cmds::GetRenderbufferParameteriv, 0>(false); - cmds::GetRenderbufferParameteriv::Result* result = - static_cast<cmds::GetRenderbufferParameteriv::Result*>( - shared_memory_address_); - result->size = 0; - cmds::GetRenderbufferParameteriv cmd; - cmd.Init(GL_FRAMEBUFFER, GL_RENDERBUFFER_RED_SIZE, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs2_0) { - EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0); - SpecializedSetup<cmds::GetRenderbufferParameteriv, 0>(false); - cmds::GetRenderbufferParameteriv::Result* result = - static_cast<cmds::GetRenderbufferParameteriv::Result*>( - shared_memory_address_); - result->size = 0; - cmds::GetRenderbufferParameteriv cmd; - cmd.Init(GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, kInvalidSharedMemoryId, - 0); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} - -TEST_P(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs2_1) { - EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0); - SpecializedSetup<cmds::GetRenderbufferParameteriv, 0>(false); - cmds::GetRenderbufferParameteriv::Result* result = - static_cast<cmds::GetRenderbufferParameteriv::Result*>( - shared_memory_address_); - result->size = 0; - cmds::GetRenderbufferParameteriv cmd; - cmd.Init(GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, shared_memory_id_, - kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} - -TEST_P(GLES2DecoderTest1, GetShaderivValidArgs) { - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - SpecializedSetup<cmds::GetShaderiv, 0>(true); - typedef cmds::GetShaderiv::Result Result; - Result* result = static_cast<Result*>(shared_memory_address_); - EXPECT_CALL(*gl_, - GetShaderiv(kServiceShaderId, GL_SHADER_TYPE, result->GetData())); - result->size = 0; - cmds::GetShaderiv cmd; - cmd.Init(client_shader_id_, GL_SHADER_TYPE, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_SHADER_TYPE), - result->GetNumResults()); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetShaderivInvalidArgs2_0) { - EXPECT_CALL(*gl_, GetShaderiv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetShaderiv, 0>(false); - cmds::GetShaderiv::Result* result = - static_cast<cmds::GetShaderiv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetShaderiv cmd; - cmd.Init(client_shader_id_, GL_SHADER_TYPE, kInvalidSharedMemoryId, 0); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} - -TEST_P(GLES2DecoderTest1, GetShaderivInvalidArgs2_1) { - EXPECT_CALL(*gl_, GetShaderiv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetShaderiv, 0>(false); - cmds::GetShaderiv::Result* result = - static_cast<cmds::GetShaderiv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetShaderiv cmd; - cmd.Init(client_shader_id_, GL_SHADER_TYPE, shared_memory_id_, - kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} -// TODO(gman): GetShaderInfoLog -// TODO(gman): GetShaderPrecisionFormat - -// TODO(gman): GetShaderSource -// TODO(gman): GetString - -TEST_P(GLES2DecoderTest1, GetTexParameterfvValidArgs) { - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - SpecializedSetup<cmds::GetTexParameterfv, 0>(true); - typedef cmds::GetTexParameterfv::Result Result; - Result* result = static_cast<Result*>(shared_memory_address_); - EXPECT_CALL(*gl_, GetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - result->GetData())); - result->size = 0; - cmds::GetTexParameterfv cmd; - cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ( - decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_TEXTURE_MAG_FILTER), - result->GetNumResults()); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterfvInvalidArgs0_0) { - EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameterfv, 0>(false); - cmds::GetTexParameterfv::Result* result = - static_cast<cmds::GetTexParameterfv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameterfv cmd; - cmd.Init(GL_PROXY_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterfvInvalidArgs1_0) { - EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameterfv, 0>(false); - cmds::GetTexParameterfv::Result* result = - static_cast<cmds::GetTexParameterfv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameterfv cmd; - cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterfvInvalidArgs2_0) { - EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameterfv, 0>(false); - cmds::GetTexParameterfv::Result* result = - static_cast<cmds::GetTexParameterfv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameterfv cmd; - cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, kInvalidSharedMemoryId, 0); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterfvInvalidArgs2_1) { - EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameterfv, 0>(false); - cmds::GetTexParameterfv::Result* result = - static_cast<cmds::GetTexParameterfv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameterfv cmd; - cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, - kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterivValidArgs) { - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - SpecializedSetup<cmds::GetTexParameteriv, 0>(true); - typedef cmds::GetTexParameteriv::Result Result; - Result* result = static_cast<Result*>(shared_memory_address_); - EXPECT_CALL(*gl_, GetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - result->GetData())); - result->size = 0; - cmds::GetTexParameteriv cmd; - cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ( - decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_TEXTURE_MAG_FILTER), - result->GetNumResults()); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs0_0) { - EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameteriv, 0>(false); - cmds::GetTexParameteriv::Result* result = - static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameteriv cmd; - cmd.Init(GL_PROXY_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs1_0) { - EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameteriv, 0>(false); - cmds::GetTexParameteriv::Result* result = - static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameteriv cmd; - cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_0) { - EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameteriv, 0>(false); - cmds::GetTexParameteriv::Result* result = - static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameteriv cmd; - cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, kInvalidSharedMemoryId, 0); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} - -TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_1) { - EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetTexParameteriv, 0>(false); - cmds::GetTexParameteriv::Result* result = - static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetTexParameteriv cmd; - cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, - kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} -// TODO(gman): GetUniformfv - -// TODO(gman): GetUniformiv - -// TODO(gman): GetUniformLocation - -TEST_P(GLES2DecoderTest1, GetVertexAttribfvValidArgs) { - SpecializedSetup<cmds::GetVertexAttribfv, 0>(true); - typedef cmds::GetVertexAttribfv::Result Result; - Result* result = static_cast<Result*>(shared_memory_address_); - result->size = 0; - cmds::GetVertexAttribfv cmd; - cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( - GL_VERTEX_ATTRIB_ARRAY_NORMALIZED), - result->GetNumResults()); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetVertexAttribfvInvalidArgs2_0) { - EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetVertexAttribfv, 0>(false); - cmds::GetVertexAttribfv::Result* result = - static_cast<cmds::GetVertexAttribfv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetVertexAttribfv cmd; - cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} - -TEST_P(GLES2DecoderTest1, GetVertexAttribfvInvalidArgs2_1) { - EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetVertexAttribfv, 0>(false); - cmds::GetVertexAttribfv::Result* result = - static_cast<cmds::GetVertexAttribfv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetVertexAttribfv cmd; - cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, - kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} - -TEST_P(GLES2DecoderTest1, GetVertexAttribivValidArgs) { - SpecializedSetup<cmds::GetVertexAttribiv, 0>(true); - typedef cmds::GetVertexAttribiv::Result Result; - Result* result = static_cast<Result*>(shared_memory_address_); - result->size = 0; - cmds::GetVertexAttribiv cmd; - cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( - GL_VERTEX_ATTRIB_ARRAY_NORMALIZED), - result->GetNumResults()); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, GetVertexAttribivInvalidArgs2_0) { - EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetVertexAttribiv, 0>(false); - cmds::GetVertexAttribiv::Result* result = - static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetVertexAttribiv cmd; - cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} - -TEST_P(GLES2DecoderTest1, GetVertexAttribivInvalidArgs2_1) { - EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetVertexAttribiv, 0>(false); - cmds::GetVertexAttribiv::Result* result = - static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetVertexAttribiv cmd; - cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, - kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} -// TODO(gman): GetVertexAttribPointerv - -TEST_P(GLES2DecoderTest1, HintValidArgs) { - EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST)); - SpecializedSetup<cmds::Hint, 0>(true); - cmds::Hint cmd; - cmd.Init(GL_GENERATE_MIPMAP_HINT, GL_FASTEST); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, HintInvalidArgs0_0) { - EXPECT_CALL(*gl_, Hint(_, _)).Times(0); - SpecializedSetup<cmds::Hint, 0>(false); - cmds::Hint cmd; - cmd.Init(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, IsBufferValidArgs) { - SpecializedSetup<cmds::IsBuffer, 0>(true); - cmds::IsBuffer cmd; - cmd.Init(client_buffer_id_, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, IsBufferInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsBuffer, 0>(false); - cmds::IsBuffer cmd; - cmd.Init(client_buffer_id_, kInvalidSharedMemoryId, shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(client_buffer_id_, shared_memory_id_, kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} - -TEST_P(GLES2DecoderTest1, IsEnabledValidArgs) { - SpecializedSetup<cmds::IsEnabled, 0>(true); - cmds::IsEnabled cmd; - cmd.Init(GL_BLEND, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, IsEnabledInvalidArgs0_0) { - EXPECT_CALL(*gl_, IsEnabled(_)).Times(0); - SpecializedSetup<cmds::IsEnabled, 0>(false); - cmds::IsEnabled cmd; - cmd.Init(GL_CLIP_PLANE0, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, IsEnabledInvalidArgs0_1) { - EXPECT_CALL(*gl_, IsEnabled(_)).Times(0); - SpecializedSetup<cmds::IsEnabled, 0>(false); - cmds::IsEnabled cmd; - cmd.Init(GL_POINT_SPRITE, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, IsEnabledInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsEnabled, 0>(false); - cmds::IsEnabled cmd; - cmd.Init(GL_BLEND, kInvalidSharedMemoryId, shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(GL_BLEND, shared_memory_id_, kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} - -TEST_P(GLES2DecoderTest1, IsFramebufferValidArgs) { - SpecializedSetup<cmds::IsFramebuffer, 0>(true); - cmds::IsFramebuffer cmd; - cmd.Init(client_framebuffer_id_, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, IsFramebufferInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsFramebuffer, 0>(false); - cmds::IsFramebuffer cmd; - cmd.Init(client_framebuffer_id_, kInvalidSharedMemoryId, - shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(client_framebuffer_id_, shared_memory_id_, - kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} - -TEST_P(GLES2DecoderTest1, IsProgramValidArgs) { - SpecializedSetup<cmds::IsProgram, 0>(true); - cmds::IsProgram cmd; - cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, IsProgramInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsProgram, 0>(false); - cmds::IsProgram cmd; - cmd.Init(client_program_id_, kInvalidSharedMemoryId, shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(client_program_id_, shared_memory_id_, kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} - -TEST_P(GLES2DecoderTest1, IsRenderbufferValidArgs) { - SpecializedSetup<cmds::IsRenderbuffer, 0>(true); - cmds::IsRenderbuffer cmd; - cmd.Init(client_renderbuffer_id_, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, IsRenderbufferInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsRenderbuffer, 0>(false); - cmds::IsRenderbuffer cmd; - cmd.Init(client_renderbuffer_id_, kInvalidSharedMemoryId, - shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(client_renderbuffer_id_, shared_memory_id_, - kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} - -TEST_P(GLES2DecoderTest1, IsShaderValidArgs) { - SpecializedSetup<cmds::IsShader, 0>(true); - cmds::IsShader cmd; - cmd.Init(client_shader_id_, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, IsShaderInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsShader, 0>(false); - cmds::IsShader cmd; - cmd.Init(client_shader_id_, kInvalidSharedMemoryId, shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(client_shader_id_, shared_memory_id_, kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} - -TEST_P(GLES2DecoderTest1, IsTextureValidArgs) { - SpecializedSetup<cmds::IsTexture, 0>(true); - cmds::IsTexture cmd; - cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, IsTextureInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsTexture, 0>(false); - cmds::IsTexture cmd; - cmd.Init(client_texture_id_, kInvalidSharedMemoryId, shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(client_texture_id_, shared_memory_id_, kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} - -TEST_P(GLES2DecoderTest1, LineWidthValidArgs) { - EXPECT_CALL(*gl_, LineWidth(0.5f)); - SpecializedSetup<cmds::LineWidth, 0>(true); - cmds::LineWidth cmd; - cmd.Init(0.5f); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, LineWidthInvalidValue0_0) { - SpecializedSetup<cmds::LineWidth, 0>(false); - cmds::LineWidth cmd; - cmd.Init(0.0f); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, LineWidthNaNValue0) { - SpecializedSetup<cmds::LineWidth, 0>(false); - cmds::LineWidth cmd; - cmd.Init(nanf("")); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, LinkProgramValidArgs) { - EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId)); - SpecializedSetup<cmds::LinkProgram, 0>(true); - cmds::LinkProgram cmd; - cmd.Init(client_program_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} -// TODO(gman): PixelStorei - -TEST_P(GLES2DecoderTest1, PolygonOffsetValidArgs) { - EXPECT_CALL(*gl_, PolygonOffset(1, 2)); - SpecializedSetup<cmds::PolygonOffset, 0>(true); - cmds::PolygonOffset cmd; - cmd.Init(1, 2); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} -// TODO(gman): ReadPixels - -// TODO(gman): ReleaseShaderCompiler - -TEST_P(GLES2DecoderTest1, RenderbufferStorageValidArgs) { - SpecializedSetup<cmds::RenderbufferStorage, 0>(true); - cmds::RenderbufferStorage cmd; - cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 3, 4); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, RenderbufferStorageInvalidArgs0_0) { - EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0); - SpecializedSetup<cmds::RenderbufferStorage, 0>(false); - cmds::RenderbufferStorage cmd; - cmd.Init(GL_FRAMEBUFFER, GL_RGBA4, 3, 4); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, RenderbufferStorageInvalidArgs2_0) { - EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0); - SpecializedSetup<cmds::RenderbufferStorage, 0>(false); - cmds::RenderbufferStorage cmd; - cmd.Init(GL_RENDERBUFFER, GL_RGBA4, -1, 4); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, RenderbufferStorageInvalidArgs3_0) { - EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0); - SpecializedSetup<cmds::RenderbufferStorage, 0>(false); - cmds::RenderbufferStorage cmd; - cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 3, -1); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); -} - -TEST_P(GLES2DecoderTest1, SampleCoverageValidArgs) { - EXPECT_CALL(*gl_, SampleCoverage(1, true)); - SpecializedSetup<cmds::SampleCoverage, 0>(true); - cmds::SampleCoverage cmd; - cmd.Init(1, true); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc index 1d8ac4076de..2b471b9722e 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc @@ -252,6 +252,34 @@ class GLES2DecoderTest2 : public GLES2DecoderTestBase { INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest2, ::testing::Bool()); template <> +void GLES2DecoderTestBase::SpecializedSetup< + cmds::GetRenderbufferParameteriv, 0>( + bool /* valid */) { + DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_, + kServiceRenderbufferId); +}; + +template <> +void GLES2DecoderTestBase::SpecializedSetup<cmds::RenderbufferStorage, 0>( + bool valid) { + DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_, + kServiceRenderbufferId); + if (valid) { + EnsureRenderbufferBound(false); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + RenderbufferStorageEXT(GL_RENDERBUFFER, _, 3, 4)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + } +} + +template <> void GLES2DecoderTestBase::SpecializedSetup<cmds::GenQueriesEXTImmediate, 0>( bool valid) { if (!valid) { @@ -332,41 +360,6 @@ void GLES2DecoderTestBase::SpecializedSetup<cmds::LinkProgram, 0>( }; template <> -void GLES2DecoderTestBase::SpecializedSetup<cmds::UseProgram, 0>( - bool /* valid */) { - // Needs the same setup as LinkProgram. - SpecializedSetup<cmds::LinkProgram, 0>(false); - - EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId)) - .Times(1) - .RetiresOnSaturation(); - - cmds::LinkProgram link_cmd; - link_cmd.Init(client_program_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(link_cmd)); -}; - -template <> -void GLES2DecoderTestBase::SpecializedSetup<cmds::ValidateProgram, 0>( - bool /* valid */) { - // Needs the same setup as LinkProgram. - SpecializedSetup<cmds::LinkProgram, 0>(false); - - EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId)) - .Times(1) - .RetiresOnSaturation(); - - cmds::LinkProgram link_cmd; - link_cmd.Init(client_program_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(link_cmd)); - - EXPECT_CALL(*gl_, - GetProgramiv(kServiceProgramId, GL_INFO_LOG_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(0)) - .RetiresOnSaturation(); -}; - -template <> void GLES2DecoderTestBase::SpecializedSetup<cmds::Uniform1f, 0>( bool /* valid */) { SetupShaderForUniform(GL_FLOAT); @@ -463,18 +456,6 @@ void GLES2DecoderTestBase::SpecializedSetup<cmds::UniformMatrix2fvImmediate, 0>( }; template <> -void GLES2DecoderTestBase::SpecializedSetup<cmds::UniformMatrix3fvImmediate, 0>( - bool /* valid */) { - SetupShaderForUniform(GL_FLOAT_MAT3); -}; - -template <> -void GLES2DecoderTestBase::SpecializedSetup<cmds::UniformMatrix4fvImmediate, 0>( - bool /* valid */) { - SetupShaderForUniform(GL_FLOAT_MAT4); -}; - -template <> void GLES2DecoderTestBase::SpecializedSetup<cmds::TexParameterf, 0>( bool /* valid */) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); @@ -498,6 +479,59 @@ void GLES2DecoderTestBase::SpecializedSetup<cmds::TexParameterivImmediate, 0>( DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); }; +template <> +void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribiv, 0>( + bool valid) { + DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); + DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0); + if (valid) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + } +}; + +template <> +void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribfv, 0>( + bool valid) { + DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); + DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0); + if (valid) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + } +}; + +template <> +void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribIiv, 0>( + bool valid) { + DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); + DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0); + if (valid) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + } +}; + +template <> +void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribIuiv, 0>( + bool valid) { + DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); + DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0); + if (valid) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + } +}; + + #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h" TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_INT) { diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h index 40003f86147..d21613b46ba 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h @@ -12,6 +12,894 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ +TEST_P(GLES2DecoderTest2, GetRenderbufferParameterivValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetRenderbufferParameteriv, 0>(true); + typedef cmds::GetRenderbufferParameteriv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL( + *gl_, GetRenderbufferParameterivEXT( + GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, result->GetData())); + result->size = 0; + cmds::GetRenderbufferParameteriv cmd; + cmd.Init(GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( + GL_RENDERBUFFER_RED_SIZE), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetRenderbufferParameterivInvalidArgs0_0) { + EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0); + SpecializedSetup<cmds::GetRenderbufferParameteriv, 0>(false); + cmds::GetRenderbufferParameteriv::Result* result = + static_cast<cmds::GetRenderbufferParameteriv::Result*>( + shared_memory_address_); + result->size = 0; + cmds::GetRenderbufferParameteriv cmd; + cmd.Init(GL_FRAMEBUFFER, GL_RENDERBUFFER_RED_SIZE, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetRenderbufferParameterivInvalidArgs2_0) { + EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0); + SpecializedSetup<cmds::GetRenderbufferParameteriv, 0>(false); + cmds::GetRenderbufferParameteriv::Result* result = + static_cast<cmds::GetRenderbufferParameteriv::Result*>( + shared_memory_address_); + result->size = 0; + cmds::GetRenderbufferParameteriv cmd; + cmd.Init(GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, kInvalidSharedMemoryId, + 0); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_P(GLES2DecoderTest2, GetRenderbufferParameterivInvalidArgs2_1) { + EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0); + SpecializedSetup<cmds::GetRenderbufferParameteriv, 0>(false); + cmds::GetRenderbufferParameteriv::Result* result = + static_cast<cmds::GetRenderbufferParameteriv::Result*>( + shared_memory_address_); + result->size = 0; + cmds::GetRenderbufferParameteriv cmd; + cmd.Init(GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_P(GLES2DecoderTest2, GetSamplerParameterfvValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetSamplerParameterfv, 0>(true); + typedef cmds::GetSamplerParameterfv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL(*gl_, + GetSamplerParameterfv(kServiceSamplerId, GL_TEXTURE_MAG_FILTER, + result->GetData())); + result->size = 0; + cmds::GetSamplerParameterfv cmd; + cmd.Init(client_sampler_id_, GL_TEXTURE_MAG_FILTER, shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ( + decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_TEXTURE_MAG_FILTER), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, GetSamplerParameterivValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetSamplerParameteriv, 0>(true); + typedef cmds::GetSamplerParameteriv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL(*gl_, + GetSamplerParameteriv(kServiceSamplerId, GL_TEXTURE_MAG_FILTER, + result->GetData())); + result->size = 0; + cmds::GetSamplerParameteriv cmd; + cmd.Init(client_sampler_id_, GL_TEXTURE_MAG_FILTER, shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ( + decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_TEXTURE_MAG_FILTER), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, GetShaderivValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetShaderiv, 0>(true); + typedef cmds::GetShaderiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL(*gl_, + GetShaderiv(kServiceShaderId, GL_SHADER_TYPE, result->GetData())); + result->size = 0; + cmds::GetShaderiv cmd; + cmd.Init(client_shader_id_, GL_SHADER_TYPE, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_SHADER_TYPE), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetShaderivInvalidArgs2_0) { + EXPECT_CALL(*gl_, GetShaderiv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetShaderiv, 0>(false); + cmds::GetShaderiv::Result* result = + static_cast<cmds::GetShaderiv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetShaderiv cmd; + cmd.Init(client_shader_id_, GL_SHADER_TYPE, kInvalidSharedMemoryId, 0); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_P(GLES2DecoderTest2, GetShaderivInvalidArgs2_1) { + EXPECT_CALL(*gl_, GetShaderiv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetShaderiv, 0>(false); + cmds::GetShaderiv::Result* result = + static_cast<cmds::GetShaderiv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetShaderiv cmd; + cmd.Init(client_shader_id_, GL_SHADER_TYPE, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} +// TODO(gman): GetShaderInfoLog +// TODO(gman): GetShaderPrecisionFormat + +// TODO(gman): GetShaderSource +// TODO(gman): GetString + +TEST_P(GLES2DecoderTest2, GetSyncivValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetSynciv, 0>(true); + typedef cmds::GetSynciv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL( + *gl_, GetSynciv(reinterpret_cast<GLsync>(kServiceSyncId), GL_SYNC_STATUS, + decoder_->GetGLES2Util()->GLGetNumValuesReturned( + GL_SYNC_STATUS), + nullptr, result->GetData())); + result->size = 0; + cmds::GetSynciv cmd; + cmd.Init(client_sync_id_, GL_SYNC_STATUS, shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_SYNC_STATUS), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterfvValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetTexParameterfv, 0>(true); + typedef cmds::GetTexParameterfv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL(*gl_, GetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + result->GetData())); + result->size = 0; + cmds::GetTexParameterfv cmd; + cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ( + decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_TEXTURE_MAG_FILTER), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterfvInvalidArgs0_0) { + EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameterfv, 0>(false); + cmds::GetTexParameterfv::Result* result = + static_cast<cmds::GetTexParameterfv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameterfv cmd; + cmd.Init(GL_PROXY_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterfvInvalidArgs1_0) { + EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameterfv, 0>(false); + cmds::GetTexParameterfv::Result* result = + static_cast<cmds::GetTexParameterfv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameterfv cmd; + cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterfvInvalidArgs2_0) { + EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameterfv, 0>(false); + cmds::GetTexParameterfv::Result* result = + static_cast<cmds::GetTexParameterfv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameterfv cmd; + cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, kInvalidSharedMemoryId, 0); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterfvInvalidArgs2_1) { + EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameterfv, 0>(false); + cmds::GetTexParameterfv::Result* result = + static_cast<cmds::GetTexParameterfv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameterfv cmd; + cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterivValidArgs) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::GetTexParameteriv, 0>(true); + typedef cmds::GetTexParameteriv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL(*gl_, GetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + result->GetData())); + result->size = 0; + cmds::GetTexParameteriv cmd; + cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ( + decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_TEXTURE_MAG_FILTER), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterivInvalidArgs0_0) { + EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameteriv, 0>(false); + cmds::GetTexParameteriv::Result* result = + static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameteriv cmd; + cmd.Init(GL_PROXY_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterivInvalidArgs1_0) { + EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameteriv, 0>(false); + cmds::GetTexParameteriv::Result* result = + static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameteriv cmd; + cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterivInvalidArgs2_0) { + EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameteriv, 0>(false); + cmds::GetTexParameteriv::Result* result = + static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameteriv cmd; + cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, kInvalidSharedMemoryId, 0); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_P(GLES2DecoderTest2, GetTexParameterivInvalidArgs2_1) { + EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetTexParameteriv, 0>(false); + cmds::GetTexParameteriv::Result* result = + static_cast<cmds::GetTexParameteriv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetTexParameteriv cmd; + cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} +// TODO(gman): GetTransformFeedbackVarying + +// TODO(gman): GetUniformBlockIndex + +// TODO(gman): GetUniformfv + +// TODO(gman): GetUniformiv + +// TODO(gman): GetUniformuiv + +// TODO(gman): GetUniformIndices + +// TODO(gman): GetUniformLocation + +TEST_P(GLES2DecoderTest2, GetVertexAttribfvValidArgs) { + SpecializedSetup<cmds::GetVertexAttribfv, 0>(true); + typedef cmds::GetVertexAttribfv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->size = 0; + cmds::GetVertexAttribfv cmd; + cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetVertexAttribfvInvalidArgs2_0) { + EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetVertexAttribfv, 0>(false); + cmds::GetVertexAttribfv::Result* result = + static_cast<cmds::GetVertexAttribfv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetVertexAttribfv cmd; + cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_P(GLES2DecoderTest2, GetVertexAttribfvInvalidArgs2_1) { + EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetVertexAttribfv, 0>(false); + cmds::GetVertexAttribfv::Result* result = + static_cast<cmds::GetVertexAttribfv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetVertexAttribfv cmd; + cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_P(GLES2DecoderTest2, GetVertexAttribivValidArgs) { + SpecializedSetup<cmds::GetVertexAttribiv, 0>(true); + typedef cmds::GetVertexAttribiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->size = 0; + cmds::GetVertexAttribiv cmd; + cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, GetVertexAttribivInvalidArgs2_0) { + EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetVertexAttribiv, 0>(false); + cmds::GetVertexAttribiv::Result* result = + static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetVertexAttribiv cmd; + cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_P(GLES2DecoderTest2, GetVertexAttribivInvalidArgs2_1) { + EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetVertexAttribiv, 0>(false); + cmds::GetVertexAttribiv::Result* result = + static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetVertexAttribiv cmd; + cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_P(GLES2DecoderTest2, GetVertexAttribIivValidArgs) { + SpecializedSetup<cmds::GetVertexAttribIiv, 0>(true); + typedef cmds::GetVertexAttribIiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->size = 0; + cmds::GetVertexAttribIiv cmd; + cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, GetVertexAttribIuivValidArgs) { + SpecializedSetup<cmds::GetVertexAttribIuiv, 0>(true); + typedef cmds::GetVertexAttribIuiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->size = 0; + cmds::GetVertexAttribIuiv cmd; + cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} +// TODO(gman): GetVertexAttribPointerv + +TEST_P(GLES2DecoderTest2, HintValidArgs) { + EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST)); + SpecializedSetup<cmds::Hint, 0>(true); + cmds::Hint cmd; + cmd.Init(GL_GENERATE_MIPMAP_HINT, GL_FASTEST); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, HintInvalidArgs0_0) { + EXPECT_CALL(*gl_, Hint(_, _)).Times(0); + SpecializedSetup<cmds::Hint, 0>(false); + cmds::Hint cmd; + cmd.Init(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} +// TODO(gman): InvalidateFramebufferImmediate +// TODO(gman): InvalidateSubFramebufferImmediate + +TEST_P(GLES2DecoderTest2, IsBufferValidArgs) { + SpecializedSetup<cmds::IsBuffer, 0>(true); + cmds::IsBuffer cmd; + cmd.Init(client_buffer_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, IsBufferInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsBuffer, 0>(false); + cmds::IsBuffer cmd; + cmd.Init(client_buffer_id_, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_buffer_id_, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, IsEnabledValidArgs) { + SpecializedSetup<cmds::IsEnabled, 0>(true); + cmds::IsEnabled cmd; + cmd.Init(GL_BLEND, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, IsEnabledInvalidArgs0_0) { + EXPECT_CALL(*gl_, IsEnabled(_)).Times(0); + SpecializedSetup<cmds::IsEnabled, 0>(false); + cmds::IsEnabled cmd; + cmd.Init(GL_CLIP_PLANE0, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, IsEnabledInvalidArgs0_1) { + EXPECT_CALL(*gl_, IsEnabled(_)).Times(0); + SpecializedSetup<cmds::IsEnabled, 0>(false); + cmds::IsEnabled cmd; + cmd.Init(GL_POINT_SPRITE, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, IsEnabledInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsEnabled, 0>(false); + cmds::IsEnabled cmd; + cmd.Init(GL_BLEND, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(GL_BLEND, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, IsFramebufferValidArgs) { + SpecializedSetup<cmds::IsFramebuffer, 0>(true); + cmds::IsFramebuffer cmd; + cmd.Init(client_framebuffer_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, IsFramebufferInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsFramebuffer, 0>(false); + cmds::IsFramebuffer cmd; + cmd.Init(client_framebuffer_id_, kInvalidSharedMemoryId, + shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_framebuffer_id_, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, IsProgramValidArgs) { + SpecializedSetup<cmds::IsProgram, 0>(true); + cmds::IsProgram cmd; + cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, IsProgramInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsProgram, 0>(false); + cmds::IsProgram cmd; + cmd.Init(client_program_id_, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, IsRenderbufferValidArgs) { + SpecializedSetup<cmds::IsRenderbuffer, 0>(true); + cmds::IsRenderbuffer cmd; + cmd.Init(client_renderbuffer_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, IsRenderbufferInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsRenderbuffer, 0>(false); + cmds::IsRenderbuffer cmd; + cmd.Init(client_renderbuffer_id_, kInvalidSharedMemoryId, + shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_renderbuffer_id_, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, IsSamplerValidArgs) { + SpecializedSetup<cmds::IsSampler, 0>(true); + cmds::IsSampler cmd; + cmd.Init(client_sampler_id_, shared_memory_id_, shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, IsSamplerInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsSampler, 0>(false); + decoder_->set_unsafe_es3_apis_enabled(true); + cmds::IsSampler cmd; + cmd.Init(client_sampler_id_, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_sampler_id_, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + decoder_->set_unsafe_es3_apis_enabled(true); +} + +TEST_P(GLES2DecoderTest2, IsShaderValidArgs) { + SpecializedSetup<cmds::IsShader, 0>(true); + cmds::IsShader cmd; + cmd.Init(client_shader_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, IsShaderInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsShader, 0>(false); + cmds::IsShader cmd; + cmd.Init(client_shader_id_, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_shader_id_, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, IsSyncValidArgs) { + SpecializedSetup<cmds::IsSync, 0>(true); + cmds::IsSync cmd; + cmd.Init(client_sync_id_, shared_memory_id_, shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, IsSyncInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsSync, 0>(false); + decoder_->set_unsafe_es3_apis_enabled(true); + cmds::IsSync cmd; + cmd.Init(client_sync_id_, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_sync_id_, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + decoder_->set_unsafe_es3_apis_enabled(true); +} + +TEST_P(GLES2DecoderTest2, IsTextureValidArgs) { + SpecializedSetup<cmds::IsTexture, 0>(true); + cmds::IsTexture cmd; + cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, IsTextureInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsTexture, 0>(false); + cmds::IsTexture cmd; + cmd.Init(client_texture_id_, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_texture_id_, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, IsTransformFeedbackValidArgs) { + SpecializedSetup<cmds::IsTransformFeedback, 0>(true); + cmds::IsTransformFeedback cmd; + cmd.Init(client_transformfeedback_id_, shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, IsTransformFeedbackInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsTransformFeedback, 0>(false); + decoder_->set_unsafe_es3_apis_enabled(true); + cmds::IsTransformFeedback cmd; + cmd.Init(client_transformfeedback_id_, kInvalidSharedMemoryId, + shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_transformfeedback_id_, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + decoder_->set_unsafe_es3_apis_enabled(true); +} + +TEST_P(GLES2DecoderTest2, LineWidthValidArgs) { + EXPECT_CALL(*gl_, LineWidth(0.5f)); + SpecializedSetup<cmds::LineWidth, 0>(true); + cmds::LineWidth cmd; + cmd.Init(0.5f); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, LineWidthInvalidValue0_0) { + SpecializedSetup<cmds::LineWidth, 0>(false); + cmds::LineWidth cmd; + cmd.Init(0.0f); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, LineWidthNaNValue0) { + SpecializedSetup<cmds::LineWidth, 0>(false); + cmds::LineWidth cmd; + cmd.Init(nanf("")); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, LinkProgramValidArgs) { + EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId)); + SpecializedSetup<cmds::LinkProgram, 0>(true); + cmds::LinkProgram cmd; + cmd.Init(client_program_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, PauseTransformFeedbackValidArgs) { + EXPECT_CALL(*gl_, PauseTransformFeedback()); + SpecializedSetup<cmds::PauseTransformFeedback, 0>(true); + cmds::PauseTransformFeedback cmd; + cmd.Init(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} +// TODO(gman): PixelStorei + +TEST_P(GLES2DecoderTest2, PolygonOffsetValidArgs) { + EXPECT_CALL(*gl_, PolygonOffset(1, 2)); + SpecializedSetup<cmds::PolygonOffset, 0>(true); + cmds::PolygonOffset cmd; + cmd.Init(1, 2); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, ReadBufferValidArgs) { + EXPECT_CALL(*gl_, ReadBuffer(1)); + SpecializedSetup<cmds::ReadBuffer, 0>(true); + cmds::ReadBuffer cmd; + cmd.Init(1); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} +// TODO(gman): ReadPixels + +// TODO(gman): ReleaseShaderCompiler + +TEST_P(GLES2DecoderTest2, RenderbufferStorageValidArgs) { + SpecializedSetup<cmds::RenderbufferStorage, 0>(true); + cmds::RenderbufferStorage cmd; + cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 3, 4); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, RenderbufferStorageInvalidArgs0_0) { + EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0); + SpecializedSetup<cmds::RenderbufferStorage, 0>(false); + cmds::RenderbufferStorage cmd; + cmd.Init(GL_FRAMEBUFFER, GL_RGBA4, 3, 4); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, RenderbufferStorageInvalidArgs2_0) { + EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0); + SpecializedSetup<cmds::RenderbufferStorage, 0>(false); + cmds::RenderbufferStorage cmd; + cmd.Init(GL_RENDERBUFFER, GL_RGBA4, -1, 4); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, RenderbufferStorageInvalidArgs3_0) { + EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0); + SpecializedSetup<cmds::RenderbufferStorage, 0>(false); + cmds::RenderbufferStorage cmd; + cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 3, -1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, ResumeTransformFeedbackValidArgs) { + EXPECT_CALL(*gl_, ResumeTransformFeedback()); + SpecializedSetup<cmds::ResumeTransformFeedback, 0>(true); + cmds::ResumeTransformFeedback cmd; + cmd.Init(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, SampleCoverageValidArgs) { + EXPECT_CALL(*gl_, SampleCoverage(1, true)); + SpecializedSetup<cmds::SampleCoverage, 0>(true); + cmds::SampleCoverage cmd; + cmd.Init(1, true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, SamplerParameterfValidArgs) { + EXPECT_CALL(*gl_, SamplerParameterf(kServiceSamplerId, GL_TEXTURE_MAG_FILTER, + GL_NEAREST)); + SpecializedSetup<cmds::SamplerParameterf, 0>(true); + cmds::SamplerParameterf cmd; + cmd.Init(client_sampler_id_, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, SamplerParameterfvImmediateValidArgs) { + cmds::SamplerParameterfvImmediate& cmd = + *GetImmediateAs<cmds::SamplerParameterfvImmediate>(); + SpecializedSetup<cmds::SamplerParameterfvImmediate, 0>(true); + GLfloat temp[1] = { + GL_NEAREST, + }; + cmd.Init(kServiceSamplerId, GL_TEXTURE_MAG_FILTER, &temp[0]); + EXPECT_CALL(*gl_, SamplerParameterf(kServiceSamplerId, GL_TEXTURE_MAG_FILTER, + *reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest2, SamplerParameteriValidArgs) { + EXPECT_CALL(*gl_, SamplerParameteri(kServiceSamplerId, GL_TEXTURE_MAG_FILTER, + GL_NEAREST)); + SpecializedSetup<cmds::SamplerParameteri, 0>(true); + cmds::SamplerParameteri cmd; + cmd.Init(client_sampler_id_, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, SamplerParameterivImmediateValidArgs) { + cmds::SamplerParameterivImmediate& cmd = + *GetImmediateAs<cmds::SamplerParameterivImmediate>(); + SpecializedSetup<cmds::SamplerParameterivImmediate, 0>(true); + GLint temp[1] = { + GL_NEAREST, + }; + cmd.Init(kServiceSamplerId, GL_TEXTURE_MAG_FILTER, &temp[0]); + EXPECT_CALL(*gl_, SamplerParameteri( + kServiceSamplerId, GL_TEXTURE_MAG_FILTER, + *reinterpret_cast<GLint*>(ImmediateDataAddress(&cmd)))); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + TEST_P(GLES2DecoderTest2, ScissorValidArgs) { EXPECT_CALL(*gl_, Scissor(1, 2, 3, 4)); SpecializedSetup<cmds::Scissor, 0>(true); @@ -40,7 +928,64 @@ TEST_P(GLES2DecoderTest2, ScissorInvalidArgs3_0) { } // TODO(gman): ShaderBinary -// TODO(gman): ShaderSourceBucket +TEST_P(GLES2DecoderTest2, ShaderSourceBucketValidArgs) { + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = {kSource0}; + const char kValidStrEnd = 0; + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kValidStrEnd); + cmds::ShaderSourceBucket cmd; + cmd.Init(client_shader_id_, kBucketId); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, ShaderSourceBucketInvalidArgs) { + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = {kSource0}; + const char kValidStrEnd = 0; + decoder_->set_unsafe_es3_apis_enabled(true); + cmds::ShaderSourceBucket cmd; + // Test no bucket. + cmd.Init(client_shader_id_, kBucketId); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + // Test invalid client. + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kValidStrEnd); + cmd.Init(kInvalidClientId, kBucketId); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, ShaderSourceBucketInvalidHeader) { + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = {kSource0}; + const char kValidStrEnd = 0; + const GLsizei kCount = static_cast<GLsizei>(arraysize(kSource)); + const GLsizei kTests[] = { + kCount + 1, 0, std::numeric_limits<GLsizei>::max(), -1, + }; + decoder_->set_unsafe_es3_apis_enabled(true); + for (size_t ii = 0; ii < arraysize(kTests); ++ii) { + SetBucketAsCStrings(kBucketId, 1, kSource, kTests[ii], kValidStrEnd); + cmds::ShaderSourceBucket cmd; + cmd.Init(client_shader_id_, kBucketId); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd)); + } +} + +TEST_P(GLES2DecoderTest2, ShaderSourceBucketInvalidStringEnding) { + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = {kSource0}; + const char kInvalidStrEnd = '*'; + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kInvalidStrEnd); + cmds::ShaderSourceBucket cmd; + cmd.Init(client_shader_id_, kBucketId); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd)); +} TEST_P(GLES2DecoderTest2, StencilFuncValidArgs) { EXPECT_CALL(*gl_, StencilFunc(GL_NEVER, 2, 3)); @@ -95,6 +1040,8 @@ TEST_P(GLES2DecoderTest2, StencilOpSeparateValidArgs) { } // TODO(gman): TexImage2D +// TODO(gman): TexImage3D + TEST_P(GLES2DecoderTest2, TexParameterfValidArgs) { EXPECT_CALL(*gl_, TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); @@ -152,12 +1099,14 @@ TEST_P(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs0_0) { cmds::TexParameterfvImmediate& cmd = *GetImmediateAs<cmds::TexParameterfvImmediate>(); EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0); + SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false); GLfloat temp[1] = { GL_NEAREST, }; cmd.Init(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, &temp[0]); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -165,12 +1114,14 @@ TEST_P(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs0_1) { cmds::TexParameterfvImmediate& cmd = *GetImmediateAs<cmds::TexParameterfvImmediate>(); EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0); + SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false); GLfloat temp[1] = { GL_NEAREST, }; cmd.Init(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, &temp[0]); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -178,12 +1129,14 @@ TEST_P(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs1_0) { cmds::TexParameterfvImmediate& cmd = *GetImmediateAs<cmds::TexParameterfvImmediate>(); EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0); + SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false); GLfloat temp[1] = { GL_NEAREST, }; cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, &temp[0]); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -243,12 +1196,14 @@ TEST_P(GLES2DecoderTest2, TexParameterivImmediateInvalidArgs0_0) { cmds::TexParameterivImmediate& cmd = *GetImmediateAs<cmds::TexParameterivImmediate>(); EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); + SpecializedSetup<cmds::TexParameterivImmediate, 0>(false); GLint temp[1] = { GL_NEAREST, }; cmd.Init(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, &temp[0]); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -256,12 +1211,14 @@ TEST_P(GLES2DecoderTest2, TexParameterivImmediateInvalidArgs0_1) { cmds::TexParameterivImmediate& cmd = *GetImmediateAs<cmds::TexParameterivImmediate>(); EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); + SpecializedSetup<cmds::TexParameterivImmediate, 0>(false); GLint temp[1] = { GL_NEAREST, }; cmd.Init(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, &temp[0]); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -269,16 +1226,95 @@ TEST_P(GLES2DecoderTest2, TexParameterivImmediateInvalidArgs1_0) { cmds::TexParameterivImmediate& cmd = *GetImmediateAs<cmds::TexParameterivImmediate>(); EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); + SpecializedSetup<cmds::TexParameterivImmediate, 0>(false); GLint temp[1] = { GL_NEAREST, }; cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, &temp[0]); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } + +TEST_P(GLES2DecoderTest2, TexStorage3DValidArgs) { + EXPECT_CALL(*gl_, TexStorage3D(GL_TEXTURE_3D, 2, GL_RGB565, 4, 5, 6)); + SpecializedSetup<cmds::TexStorage3D, 0>(true); + cmds::TexStorage3D cmd; + cmd.Init(GL_TEXTURE_3D, 2, GL_RGB565, 4, 5, 6); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} // TODO(gman): TexSubImage2D +// TODO(gman): TexSubImage3D + +TEST_P(GLES2DecoderTest2, TransformFeedbackVaryingsBucketValidArgs) { + EXPECT_CALL(*gl_, TransformFeedbackVaryings(kServiceProgramId, 1, _, + GL_INTERLEAVED_ATTRIBS)); + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = {kSource0}; + const char kValidStrEnd = 0; + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kValidStrEnd); + cmds::TransformFeedbackVaryingsBucket cmd; + cmd.Init(client_program_id_, kBucketId, GL_INTERLEAVED_ATTRIBS); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, TransformFeedbackVaryingsBucketInvalidArgs) { + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = {kSource0}; + const char kValidStrEnd = 0; + decoder_->set_unsafe_es3_apis_enabled(true); + cmds::TransformFeedbackVaryingsBucket cmd; + // Test no bucket. + cmd.Init(client_program_id_, kBucketId, GL_INTERLEAVED_ATTRIBS); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + // Test invalid client. + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kValidStrEnd); + cmd.Init(kInvalidClientId, kBucketId, GL_INTERLEAVED_ATTRIBS); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderTest2, TransformFeedbackVaryingsBucketInvalidHeader) { + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = {kSource0}; + const char kValidStrEnd = 0; + const GLsizei kCount = static_cast<GLsizei>(arraysize(kSource)); + const GLsizei kTests[] = { + kCount + 1, 0, std::numeric_limits<GLsizei>::max(), -1, + }; + decoder_->set_unsafe_es3_apis_enabled(true); + for (size_t ii = 0; ii < arraysize(kTests); ++ii) { + SetBucketAsCStrings(kBucketId, 1, kSource, kTests[ii], kValidStrEnd); + cmds::TransformFeedbackVaryingsBucket cmd; + cmd.Init(client_program_id_, kBucketId, GL_INTERLEAVED_ATTRIBS); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd)); + } +} + +TEST_P(GLES2DecoderTest2, TransformFeedbackVaryingsBucketInvalidStringEnding) { + const uint32 kBucketId = 123; + const char kSource0[] = "hello"; + const char* kSource[] = {kSource0}; + const char kInvalidStrEnd = '*'; + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kInvalidStrEnd); + cmds::TransformFeedbackVaryingsBucket cmd; + cmd.Init(client_program_id_, kBucketId, GL_INTERLEAVED_ATTRIBS); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest2, Uniform1fValidArgs) { EXPECT_CALL(*gl_, Uniform1fv(1, 1, _)); SpecializedSetup<cmds::Uniform1f, 0>(true); @@ -304,6 +1340,36 @@ TEST_P(GLES2DecoderTest2, Uniform1fvImmediateValidArgs) { // TODO(gman): Uniform1i // TODO(gman): Uniform1ivImmediate +TEST_P(GLES2DecoderTest2, Uniform1uiValidArgs) { + EXPECT_CALL(*gl_, Uniform1uiv(1, 1, _)); + SpecializedSetup<cmds::Uniform1ui, 0>(true); + cmds::Uniform1ui cmd; + cmd.Init(1, 2); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, Uniform1uivImmediateValidArgs) { + cmds::Uniform1uivImmediate& cmd = + *GetImmediateAs<cmds::Uniform1uivImmediate>(); + EXPECT_CALL( + *gl_, + Uniform1uiv(1, 2, reinterpret_cast<GLuint*>(ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::Uniform1uivImmediate, 0>(true); + GLuint temp[1 * 2] = { + 0, + }; + cmd.Init(1, 2, &temp[0]); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + TEST_P(GLES2DecoderTest2, Uniform2fValidArgs) { EXPECT_CALL(*gl_, Uniform2fv(1, 1, _)); SpecializedSetup<cmds::Uniform2f, 0>(true); @@ -350,6 +1416,36 @@ TEST_P(GLES2DecoderTest2, Uniform2ivImmediateValidArgs) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +TEST_P(GLES2DecoderTest2, Uniform2uiValidArgs) { + EXPECT_CALL(*gl_, Uniform2uiv(1, 1, _)); + SpecializedSetup<cmds::Uniform2ui, 0>(true); + cmds::Uniform2ui cmd; + cmd.Init(1, 2, 3); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, Uniform2uivImmediateValidArgs) { + cmds::Uniform2uivImmediate& cmd = + *GetImmediateAs<cmds::Uniform2uivImmediate>(); + EXPECT_CALL( + *gl_, + Uniform2uiv(1, 2, reinterpret_cast<GLuint*>(ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::Uniform2uivImmediate, 0>(true); + GLuint temp[2 * 2] = { + 0, + }; + cmd.Init(1, 2, &temp[0]); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + TEST_P(GLES2DecoderTest2, Uniform3fValidArgs) { EXPECT_CALL(*gl_, Uniform3fv(1, 1, _)); SpecializedSetup<cmds::Uniform3f, 0>(true); @@ -396,6 +1492,36 @@ TEST_P(GLES2DecoderTest2, Uniform3ivImmediateValidArgs) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +TEST_P(GLES2DecoderTest2, Uniform3uiValidArgs) { + EXPECT_CALL(*gl_, Uniform3uiv(1, 1, _)); + SpecializedSetup<cmds::Uniform3ui, 0>(true); + cmds::Uniform3ui cmd; + cmd.Init(1, 2, 3, 4); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest2, Uniform3uivImmediateValidArgs) { + cmds::Uniform3uivImmediate& cmd = + *GetImmediateAs<cmds::Uniform3uivImmediate>(); + EXPECT_CALL( + *gl_, + Uniform3uiv(1, 2, reinterpret_cast<GLuint*>(ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::Uniform3uivImmediate, 0>(true); + GLuint temp[3 * 2] = { + 0, + }; + cmd.Init(1, 2, &temp[0]); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + TEST_P(GLES2DecoderTest2, Uniform4fValidArgs) { EXPECT_CALL(*gl_, Uniform4fv(1, 1, _)); SpecializedSetup<cmds::Uniform4f, 0>(true); @@ -442,44 +1568,45 @@ TEST_P(GLES2DecoderTest2, Uniform4ivImmediateValidArgs) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); } -TEST_P(GLES2DecoderTest2, UniformMatrix2fvImmediateValidArgs) { - cmds::UniformMatrix2fvImmediate& cmd = - *GetImmediateAs<cmds::UniformMatrix2fvImmediate>(); - EXPECT_CALL(*gl_, - UniformMatrix2fv(1, 2, false, reinterpret_cast<GLfloat*>( - ImmediateDataAddress(&cmd)))); - SpecializedSetup<cmds::UniformMatrix2fvImmediate, 0>(true); - GLfloat temp[4 * 2] = { - 0, - }; - cmd.Init(1, 2, &temp[0]); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); +TEST_P(GLES2DecoderTest2, Uniform4uiValidArgs) { + EXPECT_CALL(*gl_, Uniform4uiv(1, 1, _)); + SpecializedSetup<cmds::Uniform4ui, 0>(true); + cmds::Uniform4ui cmd; + cmd.Init(1, 2, 3, 4, 5); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } -TEST_P(GLES2DecoderTest2, UniformMatrix3fvImmediateValidArgs) { - cmds::UniformMatrix3fvImmediate& cmd = - *GetImmediateAs<cmds::UniformMatrix3fvImmediate>(); - EXPECT_CALL(*gl_, - UniformMatrix3fv(1, 2, false, reinterpret_cast<GLfloat*>( - ImmediateDataAddress(&cmd)))); - SpecializedSetup<cmds::UniformMatrix3fvImmediate, 0>(true); - GLfloat temp[9 * 2] = { +TEST_P(GLES2DecoderTest2, Uniform4uivImmediateValidArgs) { + cmds::Uniform4uivImmediate& cmd = + *GetImmediateAs<cmds::Uniform4uivImmediate>(); + EXPECT_CALL( + *gl_, + Uniform4uiv(1, 2, reinterpret_cast<GLuint*>(ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::Uniform4uivImmediate, 0>(true); + GLuint temp[4 * 2] = { 0, }; cmd.Init(1, 2, &temp[0]); + decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); } +// TODO(gman): UniformBlockBinding -TEST_P(GLES2DecoderTest2, UniformMatrix4fvImmediateValidArgs) { - cmds::UniformMatrix4fvImmediate& cmd = - *GetImmediateAs<cmds::UniformMatrix4fvImmediate>(); +TEST_P(GLES2DecoderTest2, UniformMatrix2fvImmediateValidArgs) { + cmds::UniformMatrix2fvImmediate& cmd = + *GetImmediateAs<cmds::UniformMatrix2fvImmediate>(); EXPECT_CALL(*gl_, - UniformMatrix4fv(1, 2, false, reinterpret_cast<GLfloat*>( + UniformMatrix2fv(1, 2, false, reinterpret_cast<GLfloat*>( ImmediateDataAddress(&cmd)))); - SpecializedSetup<cmds::UniformMatrix4fvImmediate, 0>(true); - GLfloat temp[16 * 2] = { + SpecializedSetup<cmds::UniformMatrix2fvImmediate, 0>(true); + GLfloat temp[4 * 2] = { 0, }; cmd.Init(1, 2, &temp[0]); @@ -487,237 +1614,39 @@ TEST_P(GLES2DecoderTest2, UniformMatrix4fvImmediateValidArgs) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); } -TEST_P(GLES2DecoderTest2, UseProgramValidArgs) { - EXPECT_CALL(*gl_, UseProgram(kServiceProgramId)); - SpecializedSetup<cmds::UseProgram, 0>(true); - cmds::UseProgram cmd; - cmd.Init(client_program_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, UseProgramInvalidArgs0_0) { - EXPECT_CALL(*gl_, UseProgram(_)).Times(0); - SpecializedSetup<cmds::UseProgram, 0>(false); - cmds::UseProgram cmd; - cmd.Init(kInvalidClientId); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, ValidateProgramValidArgs) { - EXPECT_CALL(*gl_, ValidateProgram(kServiceProgramId)); - SpecializedSetup<cmds::ValidateProgram, 0>(true); - cmds::ValidateProgram cmd; - cmd.Init(client_program_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, VertexAttrib1fValidArgs) { - EXPECT_CALL(*gl_, VertexAttrib1f(1, 2)); - SpecializedSetup<cmds::VertexAttrib1f, 0>(true); - cmds::VertexAttrib1f cmd; - cmd.Init(1, 2); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, VertexAttrib1fvImmediateValidArgs) { - cmds::VertexAttrib1fvImmediate& cmd = - *GetImmediateAs<cmds::VertexAttrib1fvImmediate>(); - SpecializedSetup<cmds::VertexAttrib1fvImmediate, 0>(true); - GLfloat temp[1] = { - 0, - }; - cmd.Init(1, &temp[0]); - EXPECT_CALL(*gl_, VertexAttrib1fv(1, reinterpret_cast<GLfloat*>( - ImmediateDataAddress(&cmd)))); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, VertexAttrib2fValidArgs) { - EXPECT_CALL(*gl_, VertexAttrib2f(1, 2, 3)); - SpecializedSetup<cmds::VertexAttrib2f, 0>(true); - cmds::VertexAttrib2f cmd; - cmd.Init(1, 2, 3); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, VertexAttrib2fvImmediateValidArgs) { - cmds::VertexAttrib2fvImmediate& cmd = - *GetImmediateAs<cmds::VertexAttrib2fvImmediate>(); - SpecializedSetup<cmds::VertexAttrib2fvImmediate, 0>(true); - GLfloat temp[2] = { - 0, - }; - cmd.Init(1, &temp[0]); - EXPECT_CALL(*gl_, VertexAttrib2fv(1, reinterpret_cast<GLfloat*>( - ImmediateDataAddress(&cmd)))); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, VertexAttrib3fValidArgs) { - EXPECT_CALL(*gl_, VertexAttrib3f(1, 2, 3, 4)); - SpecializedSetup<cmds::VertexAttrib3f, 0>(true); - cmds::VertexAttrib3f cmd; - cmd.Init(1, 2, 3, 4); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, VertexAttrib3fvImmediateValidArgs) { - cmds::VertexAttrib3fvImmediate& cmd = - *GetImmediateAs<cmds::VertexAttrib3fvImmediate>(); - SpecializedSetup<cmds::VertexAttrib3fvImmediate, 0>(true); - GLfloat temp[3] = { +TEST_P(GLES2DecoderTest2, UniformMatrix2x3fvImmediateValidArgs) { + cmds::UniformMatrix2x3fvImmediate& cmd = + *GetImmediateAs<cmds::UniformMatrix2x3fvImmediate>(); + EXPECT_CALL(*gl_, + UniformMatrix2x3fv(1, 2, false, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::UniformMatrix2x3fvImmediate, 0>(true); + GLfloat temp[6 * 2] = { 0, }; - cmd.Init(1, &temp[0]); - EXPECT_CALL(*gl_, VertexAttrib3fv(1, reinterpret_cast<GLfloat*>( - ImmediateDataAddress(&cmd)))); + cmd.Init(1, 2, &temp[0]); + decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); } -TEST_P(GLES2DecoderTest2, VertexAttrib4fValidArgs) { - EXPECT_CALL(*gl_, VertexAttrib4f(1, 2, 3, 4, 5)); - SpecializedSetup<cmds::VertexAttrib4f, 0>(true); - cmds::VertexAttrib4f cmd; - cmd.Init(1, 2, 3, 4, 5); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, VertexAttrib4fvImmediateValidArgs) { - cmds::VertexAttrib4fvImmediate& cmd = - *GetImmediateAs<cmds::VertexAttrib4fvImmediate>(); - SpecializedSetup<cmds::VertexAttrib4fvImmediate, 0>(true); - GLfloat temp[4] = { +TEST_P(GLES2DecoderTest2, UniformMatrix2x4fvImmediateValidArgs) { + cmds::UniformMatrix2x4fvImmediate& cmd = + *GetImmediateAs<cmds::UniformMatrix2x4fvImmediate>(); + EXPECT_CALL(*gl_, + UniformMatrix2x4fv(1, 2, false, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::UniformMatrix2x4fvImmediate, 0>(true); + GLfloat temp[8 * 2] = { 0, }; - cmd.Init(1, &temp[0]); - EXPECT_CALL(*gl_, VertexAttrib4fv(1, reinterpret_cast<GLfloat*>( - ImmediateDataAddress(&cmd)))); + cmd.Init(1, 2, &temp[0]); + decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); } -// TODO(gman): VertexAttribPointer - -TEST_P(GLES2DecoderTest2, ViewportValidArgs) { - EXPECT_CALL(*gl_, Viewport(1, 2, 3, 4)); - SpecializedSetup<cmds::Viewport, 0>(true); - cmds::Viewport cmd; - cmd.Init(1, 2, 3, 4); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, ViewportInvalidArgs2_0) { - EXPECT_CALL(*gl_, Viewport(_, _, _, _)).Times(0); - SpecializedSetup<cmds::Viewport, 0>(false); - cmds::Viewport cmd; - cmd.Init(1, 2, -1, 4); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, ViewportInvalidArgs3_0) { - EXPECT_CALL(*gl_, Viewport(_, _, _, _)).Times(0); - SpecializedSetup<cmds::Viewport, 0>(false); - cmds::Viewport cmd; - cmd.Init(1, 2, 3, -1); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); -} -// TODO(gman): TexStorage2DEXT -// TODO(gman): GenQueriesEXTImmediate -// TODO(gman): DeleteQueriesEXTImmediate -// TODO(gman): BeginQueryEXT - -// TODO(gman): EndQueryEXT - -// TODO(gman): InsertEventMarkerEXT - -// TODO(gman): PushGroupMarkerEXT - -TEST_P(GLES2DecoderTest2, PopGroupMarkerEXTValidArgs) { - SpecializedSetup<cmds::PopGroupMarkerEXT, 0>(true); - cmds::PopGroupMarkerEXT cmd; - cmd.Init(); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} -// TODO(gman): GenVertexArraysOESImmediate -// TODO(gman): DeleteVertexArraysOESImmediate -// TODO(gman): IsVertexArrayOES -// TODO(gman): BindVertexArrayOES -// TODO(gman): SwapBuffers -// TODO(gman): GetMaxValueInBufferCHROMIUM -// TODO(gman): EnableFeatureCHROMIUM - -// TODO(gman): ResizeCHROMIUM -// TODO(gman): GetRequestableExtensionsCHROMIUM - -// TODO(gman): RequestExtensionCHROMIUM - -// TODO(gman): GetMultipleIntegervCHROMIUM - -// TODO(gman): GetProgramInfoCHROMIUM - -// TODO(gman): GetTranslatedShaderSourceANGLE -// TODO(gman): PostSubBufferCHROMIUM -// TODO(gman): TexImageIOSurface2DCHROMIUM -// TODO(gman): CopyTextureCHROMIUM -// TODO(gman): DrawArraysInstancedANGLE -// TODO(gman): DrawElementsInstancedANGLE -// TODO(gman): VertexAttribDivisorANGLE -// TODO(gman): GenMailboxCHROMIUM - -// TODO(gman): ProduceTextureCHROMIUMImmediate -// TODO(gman): ProduceTextureDirectCHROMIUMImmediate -// TODO(gman): ConsumeTextureCHROMIUMImmediate -// TODO(gman): CreateAndConsumeTextureCHROMIUMImmediate -// TODO(gman): BindUniformLocationCHROMIUMBucket -// TODO(gman): GenValuebuffersCHROMIUMImmediate -// TODO(gman): DeleteValuebuffersCHROMIUMImmediate - -TEST_P(GLES2DecoderTest2, IsValuebufferCHROMIUMValidArgs) { - SpecializedSetup<cmds::IsValuebufferCHROMIUM, 0>(true); - cmds::IsValuebufferCHROMIUM cmd; - cmd.Init(client_valuebuffer_id_, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_P(GLES2DecoderTest2, IsValuebufferCHROMIUMInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsValuebufferCHROMIUM, 0>(false); - cmds::IsValuebufferCHROMIUM cmd; - cmd.Init(client_valuebuffer_id_, kInvalidSharedMemoryId, - shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(client_valuebuffer_id_, shared_memory_id_, - kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} -// TODO(gman): BindValuebufferCHROMIUM -// TODO(gman): SubscribeValueCHROMIUM -// TODO(gman): PopulateSubscribedValuesCHROMIUM -// TODO(gman): UniformValuebufferCHROMIUM -// TODO(gman): BindTexImage2DCHROMIUM -// TODO(gman): ReleaseTexImage2DCHROMIUM -// TODO(gman): TraceBeginCHROMIUM - -// TODO(gman): TraceEndCHROMIUM -// TODO(gman): AsyncTexSubImage2DCHROMIUM - -// TODO(gman): AsyncTexImage2DCHROMIUM - -// TODO(gman): WaitAsyncTexImage2DCHROMIUM - -// TODO(gman): WaitAllAsyncTexImage2DCHROMIUM - #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc index 3fadaf07634..b705f602108 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc @@ -36,13 +36,65 @@ class GLES2DecoderTest3 : public GLES2DecoderTestBase { INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest3, ::testing::Bool()); +template <> +void GLES2DecoderTestBase::SpecializedSetup<cmds::UniformMatrix3fvImmediate, 0>( + bool /* valid */) { + SetupShaderForUniform(GL_FLOAT_MAT3); +}; + +template <> +void GLES2DecoderTestBase::SpecializedSetup<cmds::UniformMatrix4fvImmediate, 0>( + bool /* valid */) { + SetupShaderForUniform(GL_FLOAT_MAT4); +}; + + +template <> +void GLES2DecoderTestBase::SpecializedSetup<cmds::UseProgram, 0>( + bool /* valid */) { + // Needs the same setup as LinkProgram. + SpecializedSetup<cmds::LinkProgram, 0>(false); + + EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId)) + .Times(1) + .RetiresOnSaturation(); + + cmds::LinkProgram link_cmd; + link_cmd.Init(client_program_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(link_cmd)); +}; + +template <> +void GLES2DecoderTestBase::SpecializedSetup<cmds::ValidateProgram, 0>( + bool /* valid */) { + // Needs the same setup as LinkProgram. + SpecializedSetup<cmds::LinkProgram, 0>(false); + + EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId)) + .Times(1) + .RetiresOnSaturation(); + + cmds::LinkProgram link_cmd; + link_cmd.Init(client_program_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(link_cmd)); + + EXPECT_CALL(*gl_, + GetProgramiv(kServiceProgramId, GL_INFO_LOG_LENGTH, _)) + .WillOnce(SetArgumentPointee<2>(0)) + .RetiresOnSaturation(); +}; + TEST_P(GLES2DecoderTest3, TraceBeginCHROMIUM) { - const uint32 kBucketId = 123; + const uint32 kCategoryBucketId = 123; + const uint32 kNameBucketId = 234; + + const char kCategory[] = "test_category"; const char kName[] = "test_command"; - SetBucketAsCString(kBucketId, kName); + SetBucketAsCString(kCategoryBucketId, kCategory); + SetBucketAsCString(kNameBucketId, kName); TraceBeginCHROMIUM begin_cmd; - begin_cmd.Init(kBucketId); + begin_cmd.Init(kCategoryBucketId, kNameBucketId); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); } @@ -53,12 +105,16 @@ TEST_P(GLES2DecoderTest3, TraceEndCHROMIUM) { EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); - const uint32 kBucketId = 123; + const uint32 kCategoryBucketId = 123; + const uint32 kNameBucketId = 234; + + const char kCategory[] = "test_category"; const char kName[] = "test_command"; - SetBucketAsCString(kBucketId, kName); + SetBucketAsCString(kCategoryBucketId, kCategory); + SetBucketAsCString(kNameBucketId, kName); TraceBeginCHROMIUM begin_cmd; - begin_cmd.Init(kBucketId); + begin_cmd.Init(kCategoryBucketId, kNameBucketId); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); end_cmd.Init(); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h index 1c98b68da6f..e09d54020fc 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h @@ -12,6 +12,434 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ +TEST_P(GLES2DecoderTest3, UniformMatrix3fvImmediateValidArgs) { + cmds::UniformMatrix3fvImmediate& cmd = + *GetImmediateAs<cmds::UniformMatrix3fvImmediate>(); + EXPECT_CALL(*gl_, + UniformMatrix3fv(1, 2, false, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::UniformMatrix3fvImmediate, 0>(true); + GLfloat temp[9 * 2] = { + 0, + }; + cmd.Init(1, 2, &temp[0]); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, UniformMatrix3x2fvImmediateValidArgs) { + cmds::UniformMatrix3x2fvImmediate& cmd = + *GetImmediateAs<cmds::UniformMatrix3x2fvImmediate>(); + EXPECT_CALL(*gl_, + UniformMatrix3x2fv(1, 2, false, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::UniformMatrix3x2fvImmediate, 0>(true); + GLfloat temp[6 * 2] = { + 0, + }; + cmd.Init(1, 2, &temp[0]); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest3, UniformMatrix3x4fvImmediateValidArgs) { + cmds::UniformMatrix3x4fvImmediate& cmd = + *GetImmediateAs<cmds::UniformMatrix3x4fvImmediate>(); + EXPECT_CALL(*gl_, + UniformMatrix3x4fv(1, 2, false, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::UniformMatrix3x4fvImmediate, 0>(true); + GLfloat temp[12 * 2] = { + 0, + }; + cmd.Init(1, 2, &temp[0]); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest3, UniformMatrix4fvImmediateValidArgs) { + cmds::UniformMatrix4fvImmediate& cmd = + *GetImmediateAs<cmds::UniformMatrix4fvImmediate>(); + EXPECT_CALL(*gl_, + UniformMatrix4fv(1, 2, false, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::UniformMatrix4fvImmediate, 0>(true); + GLfloat temp[16 * 2] = { + 0, + }; + cmd.Init(1, 2, &temp[0]); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, UniformMatrix4x2fvImmediateValidArgs) { + cmds::UniformMatrix4x2fvImmediate& cmd = + *GetImmediateAs<cmds::UniformMatrix4x2fvImmediate>(); + EXPECT_CALL(*gl_, + UniformMatrix4x2fv(1, 2, false, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::UniformMatrix4x2fvImmediate, 0>(true); + GLfloat temp[8 * 2] = { + 0, + }; + cmd.Init(1, 2, &temp[0]); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest3, UniformMatrix4x3fvImmediateValidArgs) { + cmds::UniformMatrix4x3fvImmediate& cmd = + *GetImmediateAs<cmds::UniformMatrix4x3fvImmediate>(); + EXPECT_CALL(*gl_, + UniformMatrix4x3fv(1, 2, false, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + SpecializedSetup<cmds::UniformMatrix4x3fvImmediate, 0>(true); + GLfloat temp[12 * 2] = { + 0, + }; + cmd.Init(1, 2, &temp[0]); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest3, UseProgramValidArgs) { + EXPECT_CALL(*gl_, UseProgram(kServiceProgramId)); + SpecializedSetup<cmds::UseProgram, 0>(true); + cmds::UseProgram cmd; + cmd.Init(client_program_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, UseProgramInvalidArgs0_0) { + EXPECT_CALL(*gl_, UseProgram(_)).Times(0); + SpecializedSetup<cmds::UseProgram, 0>(false); + cmds::UseProgram cmd; + cmd.Init(kInvalidClientId); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, ValidateProgramValidArgs) { + EXPECT_CALL(*gl_, ValidateProgram(kServiceProgramId)); + SpecializedSetup<cmds::ValidateProgram, 0>(true); + cmds::ValidateProgram cmd; + cmd.Init(client_program_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, VertexAttrib1fValidArgs) { + EXPECT_CALL(*gl_, VertexAttrib1f(1, 2)); + SpecializedSetup<cmds::VertexAttrib1f, 0>(true); + cmds::VertexAttrib1f cmd; + cmd.Init(1, 2); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, VertexAttrib1fvImmediateValidArgs) { + cmds::VertexAttrib1fvImmediate& cmd = + *GetImmediateAs<cmds::VertexAttrib1fvImmediate>(); + SpecializedSetup<cmds::VertexAttrib1fvImmediate, 0>(true); + GLfloat temp[1] = { + 0, + }; + cmd.Init(1, &temp[0]); + EXPECT_CALL(*gl_, VertexAttrib1fv(1, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, VertexAttrib2fValidArgs) { + EXPECT_CALL(*gl_, VertexAttrib2f(1, 2, 3)); + SpecializedSetup<cmds::VertexAttrib2f, 0>(true); + cmds::VertexAttrib2f cmd; + cmd.Init(1, 2, 3); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, VertexAttrib2fvImmediateValidArgs) { + cmds::VertexAttrib2fvImmediate& cmd = + *GetImmediateAs<cmds::VertexAttrib2fvImmediate>(); + SpecializedSetup<cmds::VertexAttrib2fvImmediate, 0>(true); + GLfloat temp[2] = { + 0, + }; + cmd.Init(1, &temp[0]); + EXPECT_CALL(*gl_, VertexAttrib2fv(1, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, VertexAttrib3fValidArgs) { + EXPECT_CALL(*gl_, VertexAttrib3f(1, 2, 3, 4)); + SpecializedSetup<cmds::VertexAttrib3f, 0>(true); + cmds::VertexAttrib3f cmd; + cmd.Init(1, 2, 3, 4); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, VertexAttrib3fvImmediateValidArgs) { + cmds::VertexAttrib3fvImmediate& cmd = + *GetImmediateAs<cmds::VertexAttrib3fvImmediate>(); + SpecializedSetup<cmds::VertexAttrib3fvImmediate, 0>(true); + GLfloat temp[3] = { + 0, + }; + cmd.Init(1, &temp[0]); + EXPECT_CALL(*gl_, VertexAttrib3fv(1, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, VertexAttrib4fValidArgs) { + EXPECT_CALL(*gl_, VertexAttrib4f(1, 2, 3, 4, 5)); + SpecializedSetup<cmds::VertexAttrib4f, 0>(true); + cmds::VertexAttrib4f cmd; + cmd.Init(1, 2, 3, 4, 5); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, VertexAttrib4fvImmediateValidArgs) { + cmds::VertexAttrib4fvImmediate& cmd = + *GetImmediateAs<cmds::VertexAttrib4fvImmediate>(); + SpecializedSetup<cmds::VertexAttrib4fvImmediate, 0>(true); + GLfloat temp[4] = { + 0, + }; + cmd.Init(1, &temp[0]); + EXPECT_CALL(*gl_, VertexAttrib4fv(1, reinterpret_cast<GLfloat*>( + ImmediateDataAddress(&cmd)))); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, VertexAttribI4iValidArgs) { + EXPECT_CALL(*gl_, VertexAttribI4i(1, 2, 3, 4, 5)); + SpecializedSetup<cmds::VertexAttribI4i, 0>(true); + cmds::VertexAttribI4i cmd; + cmd.Init(1, 2, 3, 4, 5); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest3, VertexAttribI4ivImmediateValidArgs) { + cmds::VertexAttribI4ivImmediate& cmd = + *GetImmediateAs<cmds::VertexAttribI4ivImmediate>(); + SpecializedSetup<cmds::VertexAttribI4ivImmediate, 0>(true); + GLint temp[4] = { + 0, + }; + cmd.Init(1, &temp[0]); + EXPECT_CALL(*gl_, VertexAttribI4iv(1, reinterpret_cast<GLint*>( + ImmediateDataAddress(&cmd)))); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} + +TEST_P(GLES2DecoderTest3, VertexAttribI4uiValidArgs) { + EXPECT_CALL(*gl_, VertexAttribI4ui(1, 2, 3, 4, 5)); + SpecializedSetup<cmds::VertexAttribI4ui, 0>(true); + cmds::VertexAttribI4ui cmd; + cmd.Init(1, 2, 3, 4, 5); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest3, VertexAttribI4uivImmediateValidArgs) { + cmds::VertexAttribI4uivImmediate& cmd = + *GetImmediateAs<cmds::VertexAttribI4uivImmediate>(); + SpecializedSetup<cmds::VertexAttribI4uivImmediate, 0>(true); + GLuint temp[4] = { + 0, + }; + cmd.Init(1, &temp[0]); + EXPECT_CALL(*gl_, VertexAttribI4uiv(1, reinterpret_cast<GLuint*>( + ImmediateDataAddress(&cmd)))); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); +} +// TODO(gman): VertexAttribIPointer + +// TODO(gman): VertexAttribPointer + +TEST_P(GLES2DecoderTest3, ViewportValidArgs) { + EXPECT_CALL(*gl_, Viewport(1, 2, 3, 4)); + SpecializedSetup<cmds::Viewport, 0>(true); + cmds::Viewport cmd; + cmd.Init(1, 2, 3, 4); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, ViewportInvalidArgs2_0) { + EXPECT_CALL(*gl_, Viewport(_, _, _, _)).Times(0); + SpecializedSetup<cmds::Viewport, 0>(false); + cmds::Viewport cmd; + cmd.Init(1, 2, -1, 4); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, ViewportInvalidArgs3_0) { + EXPECT_CALL(*gl_, Viewport(_, _, _, _)).Times(0); + SpecializedSetup<cmds::Viewport, 0>(false); + cmds::Viewport cmd; + cmd.Init(1, 2, 3, -1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} +// TODO(gman): WaitSync + +// TODO(gman): TexStorage2DEXT +// TODO(gman): GenQueriesEXTImmediate +// TODO(gman): DeleteQueriesEXTImmediate +// TODO(gman): BeginQueryEXT + +TEST_P(GLES2DecoderTest3, BeginTransformFeedbackValidArgs) { + EXPECT_CALL(*gl_, BeginTransformFeedback(GL_POINTS)); + SpecializedSetup<cmds::BeginTransformFeedback, 0>(true); + cmds::BeginTransformFeedback cmd; + cmd.Init(GL_POINTS); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} +// TODO(gman): EndQueryEXT + +TEST_P(GLES2DecoderTest3, EndTransformFeedbackValidArgs) { + EXPECT_CALL(*gl_, EndTransformFeedback()); + SpecializedSetup<cmds::EndTransformFeedback, 0>(true); + cmds::EndTransformFeedback cmd; + cmd.Init(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} +// TODO(gman): InsertEventMarkerEXT + +// TODO(gman): PushGroupMarkerEXT + +TEST_P(GLES2DecoderTest3, PopGroupMarkerEXTValidArgs) { + SpecializedSetup<cmds::PopGroupMarkerEXT, 0>(true); + cmds::PopGroupMarkerEXT cmd; + cmd.Init(); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} +// TODO(gman): GenVertexArraysOESImmediate +// TODO(gman): DeleteVertexArraysOESImmediate +// TODO(gman): IsVertexArrayOES +// TODO(gman): BindVertexArrayOES +// TODO(gman): SwapBuffers +// TODO(gman): GetMaxValueInBufferCHROMIUM +// TODO(gman): EnableFeatureCHROMIUM + +// TODO(gman): MapBufferRange + +// TODO(gman): UnmapBuffer + +// TODO(gman): ResizeCHROMIUM +// TODO(gman): GetRequestableExtensionsCHROMIUM + +// TODO(gman): RequestExtensionCHROMIUM + +// TODO(gman): GetProgramInfoCHROMIUM + +// TODO(gman): GetUniformBlocksCHROMIUM + +// TODO(gman): GetTransformFeedbackVaryingsCHROMIUM + +// TODO(gman): GetUniformsES3CHROMIUM + +// TODO(gman): GetTranslatedShaderSourceANGLE +// TODO(gman): PostSubBufferCHROMIUM +// TODO(gman): TexImageIOSurface2DCHROMIUM +// TODO(gman): CopyTextureCHROMIUM +// TODO(gman): CopySubTextureCHROMIUM +// TODO(gman): DrawArraysInstancedANGLE +// TODO(gman): DrawElementsInstancedANGLE +// TODO(gman): VertexAttribDivisorANGLE +// TODO(gman): GenMailboxCHROMIUM + +// TODO(gman): ProduceTextureCHROMIUMImmediate +// TODO(gman): ProduceTextureDirectCHROMIUMImmediate +// TODO(gman): ConsumeTextureCHROMIUMImmediate +// TODO(gman): CreateAndConsumeTextureCHROMIUMImmediate +// TODO(gman): BindUniformLocationCHROMIUMBucket +// TODO(gman): GenValuebuffersCHROMIUMImmediate +// TODO(gman): DeleteValuebuffersCHROMIUMImmediate + +TEST_P(GLES2DecoderTest3, IsValuebufferCHROMIUMValidArgs) { + SpecializedSetup<cmds::IsValuebufferCHROMIUM, 0>(true); + cmds::IsValuebufferCHROMIUM cmd; + cmd.Init(client_valuebuffer_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest3, IsValuebufferCHROMIUMInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsValuebufferCHROMIUM, 0>(false); + cmds::IsValuebufferCHROMIUM cmd; + cmd.Init(client_valuebuffer_id_, kInvalidSharedMemoryId, + shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_valuebuffer_id_, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} +// TODO(gman): BindValuebufferCHROMIUM +// TODO(gman): SubscribeValueCHROMIUM +// TODO(gman): PopulateSubscribedValuesCHROMIUM +// TODO(gman): UniformValuebufferCHROMIUM +// TODO(gman): BindTexImage2DCHROMIUM +// TODO(gman): ReleaseTexImage2DCHROMIUM +// TODO(gman): TraceBeginCHROMIUM + +// TODO(gman): TraceEndCHROMIUM +// TODO(gman): AsyncTexSubImage2DCHROMIUM + +// TODO(gman): AsyncTexImage2DCHROMIUM + +// TODO(gman): WaitAsyncTexImage2DCHROMIUM + +// TODO(gman): WaitAllAsyncTexImage2DCHROMIUM + // TODO(gman): LoseContextCHROMIUM // TODO(gman): InsertSyncPointCHROMIUM @@ -21,4 +449,5 @@ // TODO(gman): DiscardBackbufferCHROMIUM // TODO(gman): ScheduleOverlayPlaneCHROMIUM +// TODO(gman): SwapInterval #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_async_pixel.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_async_pixel.cc index d32870d9a1a..168740e73b6 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_async_pixel.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_async_pixel.cc @@ -57,7 +57,6 @@ using namespace cmds; TEST_P(GLES2DecoderManualInitTest, AsyncPixelTransfers) { InitState init; init.extensions = "GL_CHROMIUM_async_pixel_transfers"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); @@ -135,7 +134,8 @@ TEST_P(GLES2DecoderManualInitTest, AsyncPixelTransfers) { // The texture is safe but the level has not been defined yet. EXPECT_TRUE(texture->SafeToRenderFrom()); GLsizei width, height; - EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_FALSE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); EXPECT_EQ(texture_ref->num_observers(), 1); } { @@ -164,7 +164,8 @@ TEST_P(GLES2DecoderManualInitTest, AsyncPixelTransfers) { // and has the right size etc. EXPECT_TRUE(texture->SafeToRenderFrom()); GLsizei width, height; - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); EXPECT_EQ(width, 8); EXPECT_EQ(height, 8); } @@ -319,7 +320,6 @@ TEST_P(GLES2DecoderManualInitTest, AsyncPixelTransfers) { TEST_P(GLES2DecoderManualInitTest, AsyncPixelTransferManager) { InitState init; init.extensions = "GL_CHROMIUM_async_pixel_transfers"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc index a858cf7b59c..cd39253d079 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc @@ -54,8 +54,7 @@ namespace gles2 { using namespace cmds; TEST_P(GLES2DecoderWithShaderTest, GetVertexAttribPointervSucceeds) { - const float dummy = 0; - const GLuint kOffsetToTestFor = sizeof(dummy) * 4; + const GLuint kOffsetToTestFor = sizeof(float) * 4; const GLuint kIndexToTest = 1; GetVertexAttribPointerv::Result* result = static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_); @@ -357,7 +356,6 @@ class GLES2DecoderEmulatedVertexArraysOESTest void SetUp() override { InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; init.use_native_vao = false; InitDecoder(init); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index 36afe385760..6bd61561fed 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -12,6 +12,7 @@ #include "base/strings/string_split.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/common/value_state.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/logger.h" @@ -56,6 +57,7 @@ void NormalizeInitState(gpu::gles2::GLES2DecoderTestBase::InitState* init) { break; } } + if (init->use_native_vao) { if (contains_vao_extension) return; @@ -74,8 +76,15 @@ void NormalizeInitState(gpu::gles2::GLES2DecoderTestBase::InitState* init) { // Make sure we don't set up an invalid InitState. CHECK(!contains_vao_extension); } + + if (!init->extensions.empty()) + init->extensions += " "; + init->extensions += "GL_EXT_framebuffer_object "; } +const uint32 kMaxColorAttachments = 16; +const uint32 kMaxDrawBuffers = 16; + } // namespace Anonymous namespace gpu { @@ -89,7 +98,8 @@ GLES2DecoderTestBase::GLES2DecoderTestBase() client_framebuffer_id_(101), client_program_id_(102), client_renderbuffer_id_(103), - client_shader_id_(104), + client_sampler_id_(104), + client_shader_id_(105), client_texture_id_(106), client_element_buffer_id_(107), client_vertex_shader_id_(121), @@ -97,6 +107,8 @@ GLES2DecoderTestBase::GLES2DecoderTestBase() client_query_id_(123), client_vertexarray_id_(124), client_valuebuffer_id_(125), + client_transformfeedback_id_(126), + client_sync_id_(127), service_renderbuffer_id_(0), service_renderbuffer_valid_(false), ignore_cached_state_for_test_(GetParam()), @@ -114,7 +126,10 @@ GLES2DecoderTestBase::~GLES2DecoderTestBase() {} void GLES2DecoderTestBase::SetUp() { InitState init; - init.gl_version = "3.0"; + // Autogenerated tests do not overwrite version or extension string, + // so we have to pick something that supports everything here. + init.gl_version = "4.4"; + init.extensions += " GL_ARB_compatibility"; init.has_alpha = true; init.has_depth = true; init.request_alpha = true; @@ -132,7 +147,9 @@ void GLES2DecoderTestBase::AddExpectationsForVertexAttribManager() { } GLES2DecoderTestBase::InitState::InitState() - : has_alpha(false), + : extensions("GL_EXT_framebuffer_object"), + gl_version("2.1"), + has_alpha(false), has_depth(false), has_stencil(false), request_alpha(false), @@ -152,6 +169,9 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( const base::CommandLine* command_line) { InitState normalized_init = init; NormalizeInitState(&normalized_init); + // For easier substring/extension matching + DCHECK(normalized_init.extensions.empty() || + *normalized_init.extensions.rbegin() == ' '); Framebuffer::ClearFramebufferCompleteComboMap(); gfx::SetGLGetProcAddressProc(gfx::MockGLInterface::GetGLProcAddress); @@ -162,9 +182,6 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( SetupMockGLBehaviors(); - // Only create stream texture manager if extension is requested. - std::vector<std::string> list; - base::SplitString(normalized_init.extensions, ' ', &list); scoped_refptr<FeatureInfo> feature_info; if (command_line) feature_info = new FeatureInfo(*command_line); @@ -173,6 +190,8 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( memory_tracker_, new ShaderTranslatorCache, feature_info.get(), + new SubscriptionRefSet, + new ValueStateMap, normalized_init.bind_generates_resource)); bool use_default_textures = normalized_init.bind_generates_resource; @@ -184,11 +203,11 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( // Context needs to be created before initializing ContextGroup, which will // in turn initialize FeatureInfo, which needs a context to determine // extension support. - context_ = new gfx::GLContextStubWithExtensions; + context_ = new StrictMock<GLContextMock>(); context_->AddExtensionsString(normalized_init.extensions.c_str()); context_->SetGLVersionString(normalized_init.gl_version.c_str()); - context_->MakeCurrent(surface_.get()); + context_->GLContextStubWithExtensions::MakeCurrent(surface_.get()); gfx::GLSurface::InitializeDynamicMockBindingsForTests(context_.get()); TestHelper::SetupContextGroupInitExpectations( @@ -211,9 +230,18 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( EXPECT_TRUE( group_->Initialize(mock_decoder_.get(), DisallowedFeatures())); + if (group_->feature_info()->IsES3Capable()) { + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxColorAttachments)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_DRAW_BUFFERS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxDrawBuffers)) + .RetiresOnSaturation(); + } + if (group_->feature_info()->feature_flags().native_vertex_array_object) { EXPECT_CALL(*gl_, GenVertexArraysOES(1, _)) - .WillOnce(SetArgumentPointee<1>(kServiceVertexArrayId)) + .WillOnce(SetArgumentPointee<1>(kServiceVertexArrayId)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, BindVertexArrayOES(_)).Times(1).RetiresOnSaturation(); } @@ -306,13 +334,15 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( .WillOnce(SetArgumentPointee<1>(normalized_init.has_stencil ? 8 : 0)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE)) - .Times(1) - .RetiresOnSaturation(); + if (!group_->feature_info()->gl_version_info().BehavesLikeGLES()) { + EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE)) + .Times(1) + .RetiresOnSaturation(); - EXPECT_CALL(*gl_, Enable(GL_POINT_SPRITE)) - .Times(1) - .RetiresOnSaturation(); + EXPECT_CALL(*gl_, Enable(GL_POINT_SPRITE)) + .Times(1) + .RetiresOnSaturation(); + } static GLint max_viewport_dims[] = { kMaxViewportWidth, @@ -323,7 +353,7 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( max_viewport_dims, max_viewport_dims + arraysize(max_viewport_dims))) .RetiresOnSaturation(); - SetupInitCapabilitiesExpectations(); + SetupInitCapabilitiesExpectations(group_->feature_info()->IsES3Capable()); SetupInitStateExpectations(); EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)) @@ -346,10 +376,18 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( // TODO(boliu): Remove OS_ANDROID once crbug.com/259023 is fixed and the // workaround has been reverted. #if !defined(OS_ANDROID) + if (normalized_init.has_alpha && !normalized_init.request_alpha) { + EXPECT_CALL(*gl_, ClearColor(0, 0, 0, 1)).Times(1).RetiresOnSaturation(); + } + EXPECT_CALL(*gl_, Clear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) .Times(1) .RetiresOnSaturation(); + + if (normalized_init.has_alpha && !normalized_init.request_alpha) { + EXPECT_CALL(*gl_, ClearColor(0, 0, 0, 0)).Times(1).RetiresOnSaturation(); + } #endif engine_.reset(new StrictMock<MockCommandBufferEngine>()); @@ -362,6 +400,9 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( shared_memory_base_ = buffer->memory(); static const int32 kLoseContextWhenOutOfMemory = 0x10002; + static const int32 kES3ContextRequired = 0x10003; + + bool es3_context_required = group_->feature_info()->IsES3Capable(); int32 attributes[] = { EGL_ALPHA_SIZE, @@ -371,7 +412,10 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( EGL_STENCIL_SIZE, normalized_init.request_stencil ? 8 : 0, kLoseContextWhenOutOfMemory, - normalized_init.lose_context_when_out_of_memory ? 1 : 0, }; + normalized_init.lose_context_when_out_of_memory ? 1 : 0, + kES3ContextRequired, + es3_context_required ? 1 : 0 + }; std::vector<int32> attribs(attributes, attributes + arraysize(attributes)); decoder_.reset(GLES2Decoder::Create(group_.get())); @@ -383,6 +427,11 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( surface_->GetSize(), DisallowedFeatures(), attribs); + EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(true)); + if (context_->WasAllocatedUsingRobustnessExtension()) { + EXPECT_CALL(*gl_, GetGraphicsResetStatusARB()) + .WillOnce(Return(GL_NO_ERROR)); + } decoder_->MakeCurrent(); decoder_->set_engine(engine_.get()); decoder_->BeginDecoding(); @@ -411,6 +460,37 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( DoCreateProgram(client_program_id_, kServiceProgramId); DoCreateShader(GL_VERTEX_SHADER, client_shader_id_, kServiceShaderId); + // Unsafe commands. + bool reset_unsafe_es3_apis_enabled = false; + if (!decoder_->unsafe_es3_apis_enabled()) { + decoder_->set_unsafe_es3_apis_enabled(true); + reset_unsafe_es3_apis_enabled = true; + } + + const gfx::GLVersionInfo* version = context_->GetVersionInfo(); + if (version->IsAtLeastGL(3, 3) || version->IsAtLeastGLES(3, 0)) { + EXPECT_CALL(*gl_, GenSamplers(_, _)) + .WillOnce(SetArgumentPointee<1>(kServiceSamplerId)) + .RetiresOnSaturation(); + GenHelper<cmds::GenSamplersImmediate>(client_sampler_id_); + } + if (version->IsAtLeastGL(4, 0) || version->IsAtLeastGLES(3, 0)) { + EXPECT_CALL(*gl_, GenTransformFeedbacks(_, _)) + .WillOnce(SetArgumentPointee<1>(kServiceTransformFeedbackId)) + .RetiresOnSaturation(); + GenHelper<cmds::GenTransformFeedbacksImmediate>( + client_transformfeedback_id_); + } + + if (init.extensions.find("GL_ARB_sync ") != std::string::npos || + version->IsAtLeastGL(3, 2) || version->IsAtLeastGLES(3, 0)) { + DoFenceSync(client_sync_id_, kServiceSyncId); + } + + if (reset_unsafe_es3_apis_enabled) { + decoder_->set_unsafe_es3_apis_enabled(false); + } + EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -513,21 +593,70 @@ void GLES2DecoderTestBase::DoDeleteProgram( EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } -void GLES2DecoderTestBase::SetBucketAsCString( - uint32 bucket_id, const char* str) { - uint32 size = str ? (strlen(str) + 1) : 0; +void GLES2DecoderTestBase::DoFenceSync( + GLuint client_id, GLuint service_id) { + EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)) + .Times(1) + .WillOnce(Return(reinterpret_cast<GLsync>(service_id))) + .RetiresOnSaturation(); + cmds::FenceSync cmd; + cmd.Init(client_id); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + +void GLES2DecoderTestBase::SetBucketData( + uint32_t bucket_id, const void* data, uint32_t data_size) { + DCHECK(data || data_size == 0); cmd::SetBucketSize cmd1; - cmd1.Init(bucket_id, size); + cmd1.Init(bucket_id, data_size); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1)); - if (str) { - memcpy(shared_memory_address_, str, size); + if (data) { + memcpy(shared_memory_address_, data, data_size); cmd::SetBucketData cmd2; - cmd2.Init(bucket_id, 0, size, kSharedMemoryId, kSharedMemoryOffset); + cmd2.Init(bucket_id, 0, data_size, kSharedMemoryId, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); ClearSharedMemory(); } } +void GLES2DecoderTestBase::SetBucketAsCString( + uint32 bucket_id, const char* str) { + SetBucketData(bucket_id, str, str ? (strlen(str) + 1) : 0); +} + +void GLES2DecoderTestBase::SetBucketAsCStrings( + uint32 bucket_id, GLsizei count, const char** str, + GLsizei count_in_header, char str_end) { + uint32_t header_size = sizeof(GLint) * (count + 1); + uint32_t total_size = header_size; + scoped_ptr<GLint[]> header(new GLint[count + 1]); + header[0] = static_cast<GLint>(count_in_header); + for (GLsizei ii = 0; ii < count; ++ii) { + header[ii + 1] = str && str[ii] ? strlen(str[ii]) : 0; + total_size += header[ii + 1] + 1; + } + cmd::SetBucketSize cmd1; + cmd1.Init(bucket_id, total_size); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1)); + memcpy(shared_memory_address_, header.get(), header_size); + uint32_t offset = header_size; + for (GLsizei ii = 0; ii < count; ++ii) { + if (str && str[ii]) { + size_t str_len = strlen(str[ii]); + memcpy(reinterpret_cast<char*>(shared_memory_address_) + offset, + str[ii], str_len); + offset += str_len; + } + memcpy(reinterpret_cast<char*>(shared_memory_address_) + offset, + &str_end, 1); + offset += 1; + } + cmd::SetBucketData cmd2; + cmd2.Init(bucket_id, 0, total_size, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); + ClearSharedMemory(); +} + void GLES2DecoderTestBase::SetupClearTextureExpectations( GLuint service_id, GLuint old_service_id, @@ -998,6 +1127,18 @@ void GLES2DecoderTestBase::DoDeleteTexture( GenHelper<cmds::DeleteTexturesImmediate>(client_id); } +void GLES2DecoderTestBase::DoBindTexImage2DCHROMIUM(GLenum target, + GLint image_id) { + cmds::BindTexImage2DCHROMIUM bind_tex_image_2d_cmd; + bind_tex_image_2d_cmd.Init(target, image_id); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + void GLES2DecoderTestBase::DoTexImage2D( GLenum target, GLint level, GLenum internal_format, GLsizei width, GLsizei height, GLint border, @@ -1243,12 +1384,15 @@ const GLuint GLES2DecoderTestBase::kServiceFixedAttribBufferId; const GLuint GLES2DecoderTestBase::kServiceBufferId; const GLuint GLES2DecoderTestBase::kServiceFramebufferId; const GLuint GLES2DecoderTestBase::kServiceRenderbufferId; +const GLuint GLES2DecoderTestBase::kServiceSamplerId; const GLuint GLES2DecoderTestBase::kServiceTextureId; const GLuint GLES2DecoderTestBase::kServiceProgramId; const GLuint GLES2DecoderTestBase::kServiceShaderId; const GLuint GLES2DecoderTestBase::kServiceElementBufferId; const GLuint GLES2DecoderTestBase::kServiceQueryId; const GLuint GLES2DecoderTestBase::kServiceVertexArrayId; +const GLuint GLES2DecoderTestBase::kServiceTransformFeedbackId; +const GLuint GLES2DecoderTestBase::kServiceSyncId; const int32 GLES2DecoderTestBase::kSharedMemoryId; const size_t GLES2DecoderTestBase::kSharedBufferSize; @@ -1532,8 +1676,7 @@ void GLES2DecoderTestBase::DoBufferSubData( void GLES2DecoderTestBase::SetupVertexBuffer() { DoEnableVertexAttribArray(1); DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); - GLfloat f = 0; - DoBufferData(GL_ARRAY_BUFFER, kNumVertices * 2 * sizeof(f)); + DoBufferData(GL_ARRAY_BUFFER, kNumVertices * 2 * sizeof(GLfloat)); } void GLES2DecoderTestBase::SetupAllNeededVertexBuffers() { @@ -1552,7 +1695,8 @@ void GLES2DecoderTestBase::SetupIndexBuffer() { client_element_buffer_id_, kServiceElementBufferId); static const GLshort indices[] = {100, 1, 2, 3, 4, 5, 6, 7, 100, 9}; - COMPILE_ASSERT(arraysize(indices) == kNumIndices, Indices_is_not_10); + static_assert(arraysize(indices) == kNumIndices, + "indices should have kNumIndices elements"); DoBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices)); DoBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 2, indices); DoBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 2, sizeof(indices) - 2, &indices[1]); @@ -1574,7 +1718,7 @@ void GLES2DecoderTestBase::DeleteIndexBuffer() { void GLES2DecoderTestBase::AddExpectationsForSimulatedAttrib0WithError( GLsizei num_vertices, GLuint buffer_id, GLenum error) { - if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { + if (group_->feature_info()->gl_version_info().BehavesLikeGLES()) { return; } diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index 1a2b54a3a0b..7719cdf3960 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -11,6 +11,7 @@ #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/framebuffer_manager.h" +#include "gpu/command_buffer/service/gl_context_mock.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/program_manager.h" @@ -22,7 +23,6 @@ #include "gpu/command_buffer/service/valuebuffer_manager.h" #include "gpu/command_buffer/service/vertex_array_manager.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/gl/gl_context_stub_with_extensions.h" #include "ui/gl/gl_surface_stub.h" #include "ui/gl/gl_mock.h" @@ -75,14 +75,16 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { template <typename T> error::Error ExecuteCmd(const T& cmd) { - COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); + static_assert(T::kArgFlags == cmd::kFixed, + "T::kArgFlags should equal cmd::kFixed"); return decoder_->DoCommands( 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd)), 0); } template <typename T> error::Error ExecuteImmediateCmd(const T& cmd, size_t data_size) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + static_assert(T::kArgFlags == cmd::kAtLeastN, + "T::kArgFlags should equal cmd::kAtLeastN"); return decoder_->DoCommands( 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd) + data_size), 0); } @@ -131,6 +133,19 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { return decoder_->GetQueryManager()->GetQuery(client_id); } + bool GetSamplerServiceId(GLuint client_id, GLuint* service_id) const { + return group_->GetSamplerServiceId(client_id, service_id); + } + + bool GetTransformFeedbackServiceId( + GLuint client_id, GLuint* service_id) const { + return group_->GetTransformFeedbackServiceId(client_id, service_id); + } + + bool GetSyncServiceId(GLuint client_id, GLsync* service_id) const { + return group_->GetSyncServiceId(client_id, service_id); + } + // This name doesn't match the underlying function, but doing it this way // prevents the need to special-case the unit test generation VertexAttribManager* GetVertexArrayInfo(GLuint client_id) { @@ -145,12 +160,26 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { return group_->valuebuffer_manager(); } + ValueStateMap* pending_valuebuffer_state() { + return group_->pending_valuebuffer_state(); + } + + FeatureInfo* feature_info() { + return group_->feature_info(); + } + ImageManager* GetImageManager() { return decoder_->GetImageManager(); } void DoCreateProgram(GLuint client_id, GLuint service_id); void DoCreateShader(GLenum shader_type, GLuint client_id, GLuint service_id); + void DoFenceSync(GLuint client_id, GLuint service_id); + void SetBucketData(uint32_t bucket_id, const void* data, uint32_t data_size); void SetBucketAsCString(uint32 bucket_id, const char* str); + // If we want a valid bucket, just set |count_in_header| as |count|, + // and set |str_end| as 0. + void SetBucketAsCStrings(uint32 bucket_id, GLsizei count, const char** str, + GLsizei count_in_header, char str_end); void set_memory_tracker(MemoryTracker* memory_tracker) { memory_tracker_ = memory_tracker; @@ -182,6 +211,10 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { return *group_.get(); } + void LoseContexts(error::ContextLostReason reason) const { + group_->LoseContexts(reason); + } + ::testing::StrictMock< ::gfx::MockGLInterface>* GetGLMock() const { return gl_.get(); } @@ -200,7 +233,7 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { GLuint vertex_shader_client_id, GLuint vertex_shader_service_id, GLuint fragment_shader_client_id, GLuint fragment_shader_service_id); - void SetupInitCapabilitiesExpectations(); + void SetupInitCapabilitiesExpectations(bool es3_capable); void SetupInitStateExpectations(); void ExpectEnableDisable(GLenum cap, bool enable); @@ -254,6 +287,7 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLint border, GLsizei size, uint32 bucket_id); + void DoBindTexImage2DCHROMIUM(GLenum target, GLint image_id); void DoTexImage2D( GLenum target, GLint level, GLenum internal_format, GLsizei width, GLsizei height, GLint border, @@ -423,10 +457,13 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { static const GLuint kServiceRenderbufferId = 303; static const GLuint kServiceTextureId = 304; static const GLuint kServiceProgramId = 305; - static const GLuint kServiceShaderId = 306; + static const GLuint kServiceSamplerId = 306; + static const GLuint kServiceShaderId = 307; static const GLuint kServiceElementBufferId = 308; static const GLuint kServiceQueryId = 309; static const GLuint kServiceVertexArrayId = 310; + static const GLuint kServiceTransformFeedbackId = 311; + static const GLuint kServiceSyncId = 312; static const int32 kSharedMemoryId = 401; static const size_t kSharedBufferSize = 2048; @@ -507,7 +544,7 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { // Use StrictMock to make 100% sure we know how GL will be called. scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; scoped_refptr<gfx::GLSurfaceStub> surface_; - scoped_refptr<gfx::GLContextStubWithExtensions> context_; + scoped_refptr<GLContextMock> context_; scoped_ptr<MockGLES2Decoder> mock_decoder_; scoped_ptr<GLES2Decoder> decoder_; MemoryTracker* memory_tracker_; @@ -516,6 +553,7 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { GLuint client_framebuffer_id_; GLuint client_program_id_; GLuint client_renderbuffer_id_; + GLuint client_sampler_id_; GLuint client_shader_id_; GLuint client_texture_id_; GLuint client_element_buffer_id_; @@ -524,6 +562,8 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { GLuint client_query_id_; GLuint client_vertexarray_id_; GLuint client_valuebuffer_id_; + GLuint client_transformfeedback_id_; + GLuint client_sync_id_; uint32 shared_memory_id_; uint32 shared_memory_offset_; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc new file mode 100644 index 00000000000..389c78fe1dc --- /dev/null +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc @@ -0,0 +1,471 @@ +// Copyright 2015 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 "gpu/command_buffer/service/gles2_cmd_decoder.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" + +using ::gfx::MockGLInterface; +using ::testing::_; +using ::testing::Return; +using ::testing::SetArgPointee; + +namespace gpu { +namespace gles2 { + +using namespace cmds; + +namespace { + +} // namespace anonymous + +TEST_P(GLES2DecoderTest, MapBufferRangeUnmapBufferReadSucceeds) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_READ_BIT; + + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + // uint32_t is Result for both MapBufferRange and UnmapBuffer commands. + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t); + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + + { // MapBufferRange + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(false); + *result = 0; + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); + EXPECT_EQ(0u, *result); + decoder_->set_unsafe_es3_apis_enabled(true); + *result = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + EXPECT_EQ(0, memcmp(&data[0], mem, kSize)); + EXPECT_EQ(1u, *result); + } + + { // UnmapBuffer + EXPECT_CALL(*gl_, UnmapBuffer(kTarget)) + .WillOnce(Return(GL_TRUE)) + .RetiresOnSaturation(); + + UnmapBuffer cmd; + cmd.Init(kTarget); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + } + + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeUnmapBufferWriteSucceeds) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_WRITE_BIT; + const GLbitfield kMappedAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; + + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + // uint32_t is Result for both MapBufferRange and UnmapBuffer commands. + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t); + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + + { // MapBufferRange succeeds + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kMappedAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(false); + *result = 0; + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); + EXPECT_EQ(0u, *result); + decoder_->set_unsafe_es3_apis_enabled(true); + *result = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + EXPECT_EQ(0, memcmp(&data[0], mem, kSize)); + EXPECT_EQ(1u, *result); + } + + { // UnmapBuffer succeeds + EXPECT_CALL(*gl_, UnmapBuffer(kTarget)) + .WillOnce(Return(GL_TRUE)) + .RetiresOnSaturation(); + + UnmapBuffer cmd; + cmd.Init(kTarget); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + } + + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeNotInitFails) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_READ_BIT; + std::vector<int8_t> data(kSize); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 1; // Any value other than 0. + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeWriteInvalidateRangeSucceeds) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + // With MAP_INVALIDATE_RANGE_BIT, no need to append MAP_READ_BIT. + const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT; + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + memset(mem, 72, kSize); // Init to a random value other than 0. + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeWriteInvalidateBufferSucceeds) { + // Test INVALIDATE_BUFFER_BIT is mapped to INVALIDATE_RANGE_BIT. + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; + // With MAP_INVALIDATE_BUFFER_BIT, no need to append MAP_READ_BIT. + const GLbitfield kFilteredAccess = + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT; + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kFilteredAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + memset(mem, 72, kSize); // Init to a random value other than 0. + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeWriteUnsynchronizedBit) { + // Test UNSYNCHRONIZED_BIT is filtered out. + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + const GLbitfield kFilteredAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kFilteredAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + memset(mem, 72, kSize); // Init to a random value other than 0. + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, memcmp(&data[0], mem, kSize)); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeWithError) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_READ_BIT; + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kAccess)) + .WillOnce(Return(nullptr)) // Return nullptr to indicate a GL error. + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + memset(mem, 72, kSize); // Init to a random value other than 0. + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + memset(&data[0], 72, kSize); + // Mem is untouched. + EXPECT_EQ(0, memcmp(&data[0], mem, kSize)); + EXPECT_EQ(0u, *result); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeBadSharedMemoryFails) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_READ_BIT; + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + decoder_->set_unsafe_es3_apis_enabled(true); + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, + kInvalidSharedMemoryId, data_shm_offset, + result_shm_id, result_shm_offset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kTarget, kOffset, kSize, kAccess, + data_shm_id, data_shm_offset, + kInvalidSharedMemoryId, result_shm_offset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kTarget, kOffset, kSize, kAccess, + data_shm_id, kInvalidSharedMemoryOffset, + result_shm_id, result_shm_offset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kTarget, kOffset, kSize, kAccess, + data_shm_id, data_shm_offset, + result_shm_id, kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest, UnmapBufferWriteNotMappedFails) { + const GLenum kTarget = GL_ARRAY_BUFFER; + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + UnmapBuffer cmd; + cmd.Init(kTarget); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderTest, UnmapBufferWriteNoBoundBufferFails) { + const GLenum kTarget = GL_ARRAY_BUFFER; + + UnmapBuffer cmd; + cmd.Init(kTarget); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderTest, BufferDataDestroysDataStore) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_WRITE_BIT; + const GLbitfield kFilteredAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; + + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + // uint32_t is Result for both MapBufferRange and UnmapBuffer commands. + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t); + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + + decoder_->set_unsafe_es3_apis_enabled(true); + + { // MapBufferRange succeeds + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kFilteredAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + *result = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(1u, *result); + } + + { // BufferData unmaps the data store. + DoBufferData(kTarget, kSize * 2); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + } + + { // UnmapBuffer fails. + UnmapBuffer cmd; + cmd.Init(kTarget); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } +} + +TEST_P(GLES2DecoderTest, DeleteBuffersDestroysDataStore) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_WRITE_BIT; + const GLbitfield kFilteredAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; + + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + // uint32_t is Result for both MapBufferRange and UnmapBuffer commands. + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t); + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + + decoder_->set_unsafe_es3_apis_enabled(true); + + { // MapBufferRange succeeds + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kFilteredAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + *result = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(1u, *result); + } + + { // DeleteBuffers unmaps the data store. + DoDeleteBuffer(client_buffer_id_, kServiceBufferId); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + } + + { // UnmapBuffer fails. + UnmapBuffer cmd; + cmd.Init(kTarget); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } +} + +} // namespace gles2 +} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc new file mode 100644 index 00000000000..3fe88b907fb --- /dev/null +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc @@ -0,0 +1,273 @@ +// Copyright 2015 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 "gpu/command_buffer/service/gles2_cmd_decoder.h" + +#include "base/command_line.h" +#include "base/strings/string_number_conversions.h" +#include "gpu/command_buffer/common/gles2_cmd_format.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/cmd_buffer_engine.h" +#include "gpu/command_buffer/service/context_group.h" +#include "gpu/command_buffer/service/gl_surface_mock.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" +#include "gpu/command_buffer/service/gpu_switches.h" +#include "gpu/command_buffer/service/mocks.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gl/gl_mock.h" + +using ::gfx::MockGLInterface; +using ::testing::_; +using ::testing::DoAll; +using ::testing::InSequence; +using ::testing::Invoke; +using ::testing::MatcherCast; +using ::testing::Mock; +using ::testing::Pointee; +using ::testing::Return; +using ::testing::SaveArg; +using ::testing::SetArrayArgument; +using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; +using ::testing::StrEq; +using ::testing::StrictMock; + +namespace gpu { +namespace gles2 { + +using namespace cmds; + +class GLES2DecoderDrawOOMTest : public GLES2DecoderManualInitTest { + protected: + void Init(bool has_robustness) { + InitState init; + init.lose_context_when_out_of_memory = true; + if (has_robustness) + init.extensions = "GL_ARB_robustness"; + InitDecoder(init); + SetupDefaultProgram(); + } + + void Draw(GLenum reset_status, + error::ContextLostReason expected_other_reason) { + const GLsizei kFakeLargeCount = 0x1234; + SetupTexture(); + if (context_->WasAllocatedUsingRobustnessExtension()) { + EXPECT_CALL(*gl_, GetGraphicsResetStatusARB()) + .WillOnce(Return(reset_status)); + } + AddExpectationsForSimulatedAttrib0WithError(kFakeLargeCount, 0, + GL_OUT_OF_MEMORY); + EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0).RetiresOnSaturation(); + // Other contexts in the group should be lost also. + EXPECT_CALL(*mock_decoder_, MarkContextLost(expected_other_reason)) + .Times(1) + .RetiresOnSaturation(); + DrawArrays cmd; + cmd.Init(GL_TRIANGLES, 0, kFakeLargeCount); + EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd)); + } +}; + +// Test that we lose context. +TEST_P(GLES2DecoderDrawOOMTest, ContextLostReasonOOM) { + Init(false); // without robustness + const error::ContextLostReason expected_reason_for_other_contexts = + error::kOutOfMemory; + Draw(GL_NO_ERROR, expected_reason_for_other_contexts); + EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_EQ(error::kOutOfMemory, decoder_->GetContextLostReason()); +} + +TEST_P(GLES2DecoderDrawOOMTest, ContextLostReasonWhenStatusIsNoError) { + Init(true); // with robustness + // If the reset status is NO_ERROR, we should be signaling kOutOfMemory. + const error::ContextLostReason expected_reason_for_other_contexts = + error::kOutOfMemory; + Draw(GL_NO_ERROR, expected_reason_for_other_contexts); + EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_EQ(error::kOutOfMemory, decoder_->GetContextLostReason()); +} + +TEST_P(GLES2DecoderDrawOOMTest, ContextLostReasonWhenStatusIsGuilty) { + Init(true); + // If there was a reset, it should override kOutOfMemory. + const error::ContextLostReason expected_reason_for_other_contexts = + error::kUnknown; + Draw(GL_GUILTY_CONTEXT_RESET_ARB, expected_reason_for_other_contexts); + EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_EQ(error::kGuilty, decoder_->GetContextLostReason()); +} + +TEST_P(GLES2DecoderDrawOOMTest, ContextLostReasonWhenStatusIsUnknown) { + Init(true); + // If there was a reset, it should override kOutOfMemory. + const error::ContextLostReason expected_reason_for_other_contexts = + error::kUnknown; + Draw(GL_UNKNOWN_CONTEXT_RESET_ARB, expected_reason_for_other_contexts); + EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_EQ(error::kUnknown, decoder_->GetContextLostReason()); +} + +INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderDrawOOMTest, ::testing::Bool()); + +class GLES2DecoderLostContextTest : public GLES2DecoderManualInitTest { + protected: + void Init(bool has_robustness) { + InitState init; + init.gl_version = "opengl es 2.0"; + if (has_robustness) + init.extensions = "GL_KHR_robustness"; + InitDecoder(init); + } + + void InitWithVirtualContextsAndRobustness() { + base::CommandLine command_line(0, NULL); + command_line.AppendSwitchASCII( + switches::kGpuDriverBugWorkarounds, + base::IntToString(USE_VIRTUALIZED_GL_CONTEXTS)); + InitState init; + init.gl_version = "opengl es 2.0"; + init.extensions = "GL_KHR_robustness"; + InitDecoderWithCommandLine(init, &command_line); + } + + void DoGetErrorWithContextLost(GLenum reset_status) { + DCHECK(context_->HasExtension("GL_KHR_robustness")); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_CONTEXT_LOST_KHR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetGraphicsResetStatusARB()) + .WillOnce(Return(reset_status)); + cmds::GetError cmd; + cmd.Init(shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd)); + EXPECT_EQ(static_cast<GLuint>(GL_NO_ERROR), *GetSharedMemoryAs<GLenum*>()); + } + + void ClearCurrentDecoderError() { + DCHECK(decoder_->WasContextLost()); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_CONTEXT_LOST_KHR)) + .RetiresOnSaturation(); + cmds::GetError cmd; + cmd.Init(shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd)); + } +}; + +TEST_P(GLES2DecoderLostContextTest, LostFromMakeCurrent) { + Init(false); // without robustness + EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(false)); + // Expect the group to be lost. + EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)).Times(1); + decoder_->MakeCurrent(); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_EQ(error::kMakeCurrentFailed, decoder_->GetContextLostReason()); + + // We didn't process commands, so we need to clear the decoder error, + // so that we can shut down cleanly. + ClearCurrentDecoderError(); +} + +TEST_P(GLES2DecoderLostContextTest, LostFromMakeCurrentWithRobustness) { + Init(true); // with robustness + // If we can't make the context current, we cannot query the robustness + // extension. + EXPECT_CALL(*gl_, GetGraphicsResetStatusARB()).Times(0); + EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(false)); + // Expect the group to be lost. + EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)).Times(1); + decoder_->MakeCurrent(); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_FALSE(decoder_->WasContextLostByRobustnessExtension()); + EXPECT_EQ(error::kMakeCurrentFailed, decoder_->GetContextLostReason()); + + // We didn't process commands, so we need to clear the decoder error, + // so that we can shut down cleanly. + ClearCurrentDecoderError(); +} + +TEST_P(GLES2DecoderLostContextTest, LostFromResetAfterMakeCurrent) { + Init(true); // with robustness + InSequence seq; + EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(true)); + EXPECT_CALL(*gl_, GetGraphicsResetStatusARB()) + .WillOnce(Return(GL_GUILTY_CONTEXT_RESET_KHR)); + // Expect the group to be lost. + EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)).Times(1); + decoder_->MakeCurrent(); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension()); + EXPECT_EQ(error::kGuilty, decoder_->GetContextLostReason()); + + // We didn't process commands, so we need to clear the decoder error, + // so that we can shut down cleanly. + ClearCurrentDecoderError(); +} + +TEST_P(GLES2DecoderLostContextTest, LoseGuiltyFromGLError) { + Init(true); + // Always expect other contexts to be signaled as 'kUnknown' since we can't + // query their status without making them current. + EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)) + .Times(1); + DoGetErrorWithContextLost(GL_GUILTY_CONTEXT_RESET_KHR); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension()); + EXPECT_EQ(error::kGuilty, decoder_->GetContextLostReason()); +} + +TEST_P(GLES2DecoderLostContextTest, LoseInnocentFromGLError) { + Init(true); + // Always expect other contexts to be signaled as 'kUnknown' since we can't + // query their status without making them current. + EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)) + .Times(1); + DoGetErrorWithContextLost(GL_INNOCENT_CONTEXT_RESET_KHR); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension()); + EXPECT_EQ(error::kInnocent, decoder_->GetContextLostReason()); +} + +TEST_P(GLES2DecoderLostContextTest, LoseVirtualContextWithRobustness) { + InitWithVirtualContextsAndRobustness(); + EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)) + .Times(1); + // Signal guilty.... + DoGetErrorWithContextLost(GL_GUILTY_CONTEXT_RESET_KHR); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension()); + // ...but make sure we don't pretend, since for virtual contexts we don't + // know if this was really the guilty client. + EXPECT_EQ(error::kUnknown, decoder_->GetContextLostReason()); +} + +TEST_P(GLES2DecoderLostContextTest, LoseGroupFromRobustness) { + // If one context in a group is lost through robustness, + // the other ones should also get lost and query the reset status. + Init(true); + EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)) + .Times(1); + // There should be no GL calls, since we might not have a current context. + EXPECT_CALL(*gl_, GetGraphicsResetStatusARB()).Times(0); + LoseContexts(error::kUnknown); + EXPECT_TRUE(decoder_->WasContextLost()); + EXPECT_EQ(error::kUnknown, decoder_->GetContextLostReason()); + + // We didn't process commands, so we need to clear the decoder error, + // so that we can shut down cleanly. + ClearCurrentDecoderError(); +} + +INSTANTIATE_TEST_CASE_P(Service, + GLES2DecoderLostContextTest, + ::testing::Bool()); + +} // namespace gles2 +} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc index 74149ef24d6..3578b5b0bc8 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc @@ -99,7 +99,6 @@ void GLES2DecoderRestoreStateTest::InitializeContextState( TEST_P(GLES2DecoderRestoreStateTest, NullPreviousStateBGR) { InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); SetupTexture(); @@ -128,7 +127,6 @@ TEST_P(GLES2DecoderRestoreStateTest, NullPreviousStateBGR) { TEST_P(GLES2DecoderRestoreStateTest, NullPreviousState) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); SetupTexture(); @@ -153,7 +151,6 @@ TEST_P(GLES2DecoderRestoreStateTest, NullPreviousState) { TEST_P(GLES2DecoderRestoreStateTest, WithPreviousStateBGR) { InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); SetupTexture(); @@ -178,7 +175,6 @@ TEST_P(GLES2DecoderRestoreStateTest, WithPreviousStateBGR) { TEST_P(GLES2DecoderRestoreStateTest, WithPreviousState) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); SetupTexture(); @@ -202,7 +198,6 @@ TEST_P(GLES2DecoderRestoreStateTest, WithPreviousState) { TEST_P(GLES2DecoderRestoreStateTest, ActiveUnit1) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); // Bind a non-default texture to GL_TEXTURE1 unit. @@ -233,7 +228,6 @@ TEST_P(GLES2DecoderRestoreStateTest, ActiveUnit1) { TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit0BGR) { InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); @@ -272,7 +266,6 @@ TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit0BGR) { TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit1BGR) { InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); @@ -305,7 +298,6 @@ TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit1BGR) { TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit0) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); // Bind a non-default texture to GL_TEXTURE1 unit. @@ -342,7 +334,6 @@ TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit0) { TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit1) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); // Bind a non-default texture to GL_TEXTURE0 unit. @@ -391,7 +382,6 @@ TEST_P(GLES2DecoderManualInitTest, ContextStateCapabilityCaching) { {0, false, false}}; InitState init; - init.gl_version = "2.1"; InitDecoder(init); for (int i = 0; test[i].gl_enum; i++) { diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc index 0bfefd4fdf4..bb0286d2a83 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc @@ -17,12 +17,12 @@ #include "gpu/command_buffer/service/gl_surface_mock.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" -#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/program_manager.h" #include "gpu/command_buffer/service/test_helper.h" +#include "gpu/config/gpu_switches.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_mock.h" @@ -60,7 +60,10 @@ class GLES2DecoderGeometryInstancingTest : public GLES2DecoderWithShaderTest { void SetUp() override { InitState init; init.extensions = "GL_ANGLE_instanced_arrays"; - init.gl_version = "opengl es 2.0"; + // Most of the tests in this file assume they're running on + // desktop OpenGL, and large portions of the tests will become + // no-ops if they aren't. + init.gl_version = "opengl 2.1"; init.has_alpha = true; init.has_depth = true; init.request_alpha = true; @@ -391,7 +394,6 @@ TEST_P(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMaskFBO) { TEST_P(GLES2DecoderManualInitTest, DepthEnableWithDepth) { InitState init; - init.gl_version = "3.0"; init.has_depth = true; init.request_depth = true; init.bind_generates_resource = true; @@ -444,7 +446,6 @@ TEST_P(GLES2DecoderManualInitTest, DepthEnableWithDepth) { TEST_P(GLES2DecoderManualInitTest, DepthEnableWithoutRequestedDepth) { InitState init; - init.gl_version = "3.0"; init.has_depth = true; init.bind_generates_resource = true; InitDecoder(init); @@ -496,7 +497,6 @@ TEST_P(GLES2DecoderManualInitTest, DepthEnableWithoutRequestedDepth) { TEST_P(GLES2DecoderManualInitTest, StencilEnableWithStencil) { InitState init; - init.gl_version = "3.0"; init.has_stencil = true; init.request_stencil = true; init.bind_generates_resource = true; @@ -550,7 +550,6 @@ TEST_P(GLES2DecoderManualInitTest, StencilEnableWithStencil) { TEST_P(GLES2DecoderManualInitTest, StencilEnableWithoutRequestedStencil) { InitState init; - init.gl_version = "3.0"; init.has_stencil = true; init.bind_generates_resource = true; InitDecoder(init); @@ -602,7 +601,6 @@ TEST_P(GLES2DecoderManualInitTest, StencilEnableWithoutRequestedStencil) { TEST_P(GLES2DecoderManualInitTest, CachedColorMask) { InitState init; - init.gl_version = "3.0"; init.has_alpha = true; init.has_depth = true; init.has_stencil = true; @@ -630,7 +628,6 @@ TEST_P(GLES2DecoderManualInitTest, CachedColorMask) { TEST_P(GLES2DecoderManualInitTest, CachedDepthMask) { InitState init; - init.gl_version = "3.0"; init.has_alpha = true; init.has_depth = true; init.has_stencil = true; @@ -657,7 +654,6 @@ TEST_P(GLES2DecoderManualInitTest, CachedDepthMask) { TEST_P(GLES2DecoderManualInitTest, CachedStencilMask) { InitState init; - init.gl_version = "3.0"; init.has_alpha = true; init.has_depth = true; init.has_stencil = true; @@ -743,36 +739,6 @@ TEST_P(GLES2DecoderWithShaderTest, DrawArraysSimulatedAttrib0OOMFails) { EXPECT_FALSE(GetDecoder()->WasContextLost()); } -// Test that we lose context. -TEST_P(GLES2DecoderManualInitTest, LoseContextWhenOOM) { - InitState init; - init.gl_version = "3.0"; - init.has_alpha = true; - init.has_depth = true; - init.request_alpha = true; - init.request_depth = true; - init.bind_generates_resource = true; - init.lose_context_when_out_of_memory = true; - InitDecoder(init); - SetupDefaultProgram(); - - const GLsizei kFakeLargeCount = 0x1234; - SetupTexture(); - AddExpectationsForSimulatedAttrib0WithError( - kFakeLargeCount, 0, GL_OUT_OF_MEMORY); - EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0).RetiresOnSaturation(); - // Other contexts in the group should be lost also. - EXPECT_CALL(*mock_decoder_, LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB)) - .Times(1) - .RetiresOnSaturation(); - DrawArrays cmd; - cmd.Init(GL_TRIANGLES, 0, kFakeLargeCount); - // This context should be lost. - EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd)); - EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); - EXPECT_TRUE(decoder_->WasContextLost()); -} - TEST_P(GLES2DecoderWithShaderTest, DrawArraysBadTextureUsesBlack) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); // This is an NPOT texture. As the default filtering requires mips @@ -858,12 +824,11 @@ TEST_P(GLES2DecoderWithShaderTest, DrawArraysValidAttributesSucceeds) { // Same as DrawArraysValidAttributesSucceeds, but with workaround // |init_vertex_attributes|. TEST_P(GLES2DecoderManualInitTest, InitVertexAttributes) { - CommandLine command_line(0, NULL); + base::CommandLine command_line(0, NULL); command_line.AppendSwitchASCII( switches::kGpuDriverBugWorkarounds, base::IntToString(gpu::INIT_VERTEX_ATTRIBUTES)); InitState init; - init.gl_version = "3.0"; init.has_alpha = true; init.has_depth = true; init.request_alpha = true; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc index d555f2836c4..4255ffaa180 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc @@ -644,11 +644,10 @@ TEST_P(GLES2DecoderTest, ReadPixelsOutOfRange) { TEST_P(GLES2DecoderTest, ReadPixelsInvalidArgs) { typedef ReadPixels::Result Result; - Result* result = GetSharedMemoryAs<Result*>(); uint32 result_shm_id = kSharedMemoryId; uint32 result_shm_offset = kSharedMemoryOffset; uint32 pixels_shm_id = kSharedMemoryId; - uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result); + uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0); ReadPixels cmd; cmd.Init(0, @@ -750,14 +749,13 @@ TEST_P(GLES2DecoderManualInitTest, ReadPixelsAsyncError) { InitDecoder(init); typedef ReadPixels::Result Result; - Result* result = GetSharedMemoryAs<Result*>(); const GLsizei kWidth = 4; const GLsizei kHeight = 4; uint32 result_shm_id = kSharedMemoryId; uint32 result_shm_offset = kSharedMemoryOffset; uint32 pixels_shm_id = kSharedMemoryId; - uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result); + uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); EXPECT_CALL(*gl_, GetError()) // first error check must pass to get to the test @@ -772,6 +770,7 @@ TEST_P(GLES2DecoderManualInitTest, ReadPixelsAsyncError) { ReadPixels(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, _)) .Times(1); EXPECT_CALL(*gl_, GenBuffersARB(1, _)).Times(1); + EXPECT_CALL(*gl_, DeleteBuffersARB(1, _)).Times(1); EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, _)).Times(2); EXPECT_CALL(*gl_, BufferData(GL_PIXEL_PACK_BUFFER_ARB, _, NULL, GL_STREAM_READ)) @@ -928,7 +927,6 @@ TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearDepthStencil) { TEST_P(GLES2DecoderManualInitTest, ActualAlphaMatchesRequestedAlpha) { InitState init; - init.gl_version = "3.0"; init.has_alpha = true; init.request_alpha = true; init.bind_generates_resource = true; @@ -955,7 +953,6 @@ TEST_P(GLES2DecoderManualInitTest, ActualAlphaMatchesRequestedAlpha) { TEST_P(GLES2DecoderManualInitTest, ActualAlphaDoesNotMatchRequestedAlpha) { InitState init; - init.gl_version = "3.0"; init.has_alpha = true; init.bind_generates_resource = true; InitDecoder(init); @@ -981,7 +978,6 @@ TEST_P(GLES2DecoderManualInitTest, ActualAlphaDoesNotMatchRequestedAlpha) { TEST_P(GLES2DecoderManualInitTest, ActualDepthMatchesRequestedDepth) { InitState init; - init.gl_version = "3.0"; init.has_depth = true; init.request_depth = true; init.bind_generates_resource = true; @@ -1008,7 +1004,6 @@ TEST_P(GLES2DecoderManualInitTest, ActualDepthMatchesRequestedDepth) { TEST_P(GLES2DecoderManualInitTest, ActualDepthDoesNotMatchRequestedDepth) { InitState init; - init.gl_version = "3.0"; init.has_depth = true; init.bind_generates_resource = true; InitDecoder(init); @@ -1034,7 +1029,6 @@ TEST_P(GLES2DecoderManualInitTest, ActualDepthDoesNotMatchRequestedDepth) { TEST_P(GLES2DecoderManualInitTest, ActualStencilMatchesRequestedStencil) { InitState init; - init.gl_version = "3.0"; init.has_stencil = true; init.request_stencil = true; init.bind_generates_resource = true; @@ -1061,7 +1055,6 @@ TEST_P(GLES2DecoderManualInitTest, ActualStencilMatchesRequestedStencil) { TEST_P(GLES2DecoderManualInitTest, ActualStencilDoesNotMatchRequestedStencil) { InitState init; - init.gl_version = "3.0"; init.has_stencil = true; init.bind_generates_resource = true; InitDecoder(init); @@ -1405,7 +1398,6 @@ TEST_P(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleCHROMIUMGLError) { InitState init; init.extensions = "GL_EXT_framebuffer_multisample"; - init.gl_version = "2.1"; init.bind_generates_resource = true; InitDecoder(init); DoBindRenderbuffer( @@ -1430,7 +1422,6 @@ TEST_P(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleCHROMIUMBadArgs) { InitState init; init.extensions = "GL_EXT_framebuffer_multisample"; - init.gl_version = "2.1"; init.bind_generates_resource = true; InitDecoder(init); DoBindRenderbuffer( @@ -1465,7 +1456,6 @@ TEST_P(GLES2DecoderManualInitTest, TEST_P(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleCHROMIUM) { InitState init; init.extensions = "GL_EXT_framebuffer_multisample"; - init.gl_version = "2.1"; InitDecoder(init); DoBindRenderbuffer( GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId); @@ -1483,7 +1473,6 @@ TEST_P(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleCHROMIUMRebindRenderbuffer) { InitState init; init.extensions = "GL_EXT_framebuffer_multisample"; - init.gl_version = "2.1"; InitDecoder(init); DoBindRenderbuffer( GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId); @@ -1502,7 +1491,6 @@ TEST_P(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleEXTNotSupported) { InitState init; init.extensions = "GL_EXT_framebuffer_multisample"; - init.gl_version = "2.1"; init.bind_generates_resource = true; InitDecoder(init); DoBindRenderbuffer( @@ -1555,7 +1543,7 @@ class GLES2DecoderMultisampledRenderToTextureTest *gl_, RenderbufferStorageMultisampleIMG(GL_RENDERBUFFER, TestHelper::kMaxSamples, - GL_RGBA, + GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1)) .Times(1) @@ -1565,7 +1553,7 @@ class GLES2DecoderMultisampledRenderToTextureTest *gl_, RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, TestHelper::kMaxSamples, - GL_RGBA, + GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1)) .Times(1) @@ -1636,11 +1624,10 @@ TEST_P(GLES2DecoderTest, ReadPixelsGLError) { GLsizei width = 2; GLsizei height = 4; typedef ReadPixels::Result Result; - Result* result = GetSharedMemoryAs<Result*>(); uint32 result_shm_id = kSharedMemoryId; uint32 result_shm_offset = kSharedMemoryOffset; uint32 pixels_shm_id = kSharedMemoryId; - uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result); + uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); EXPECT_CALL(*gl_, GetError()) .WillOnce(Return(GL_NO_ERROR)) .WillOnce(Return(GL_OUT_OF_MEMORY)) @@ -1764,11 +1751,10 @@ TEST_P(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnReadPixels) { .Times(1) .RetiresOnSaturation(); typedef ReadPixels::Result Result; - Result* result = GetSharedMemoryAs<Result*>(); uint32 result_shm_id = kSharedMemoryId; uint32 result_shm_offset = kSharedMemoryOffset; uint32 pixels_shm_id = kSharedMemoryId; - uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result); + uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); ReadPixels cmd; cmd.Init(0, 0, @@ -1789,7 +1775,6 @@ TEST_P(GLES2DecoderManualInitTest, UnClearedAttachmentsGetClearedOnReadPixelsAndDrawBufferGetsRestored) { InitState init; init.extensions = "GL_EXT_framebuffer_multisample"; - init.gl_version = "2.1"; init.bind_generates_resource = true; InitDecoder(init); const GLuint kFBOClientTextureId = 4100; @@ -2123,7 +2108,7 @@ TEST_P(GLES2DecoderManualInitTest, InvalidateFramebufferBinding) { // EXPECT_EQ can't be used to compare function pointers EXPECT_TRUE( - gfx::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") == + gfx::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") != gfx::g_driver_gl.fn.glDiscardFramebufferEXTFn); EXPECT_TRUE( gfx::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") != @@ -2280,7 +2265,6 @@ TEST_P(GLES2DecoderManualInitTest, TEST_P(GLES2DecoderManualInitTest, ReadFormatExtension) { InitState init; init.extensions = "GL_OES_read_format"; - init.gl_version = "2.1"; init.bind_generates_resource = true; InitDecoder(init); @@ -2339,7 +2323,6 @@ TEST_P(GLES2DecoderManualInitTest, ReadFormatExtension) { TEST_P(GLES2DecoderManualInitTest, NoReadFormatExtension) { InitState init; - init.gl_version = "2.1"; init.bind_generates_resource = true; InitDecoder(init); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc index 05cb9ff170f..9c3d775f360 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc @@ -16,13 +16,12 @@ #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/gl_surface_mock.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" - -#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/program_manager.h" #include "gpu/command_buffer/service/test_helper.h" +#include "gpu/config/gpu_switches.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_mock.h" @@ -43,7 +42,6 @@ using ::testing::Pointee; using ::testing::Return; using ::testing::SaveArg; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; using ::testing::SetArgPointee; using ::testing::StrEq; using ::testing::StrictMock; @@ -81,6 +79,134 @@ TEST_P(GLES2DecoderWithShaderTest, GetProgramInfoCHROMIUMInvalidArgs) { EXPECT_EQ(0u, info->num_uniforms); } +TEST_P(GLES2DecoderWithShaderTest, GetUniformBlocksCHROMIUMValidArgs) { + const uint32 kBucketId = 123; + GetUniformBlocksCHROMIUM cmd; + cmd.Init(client_program_id_, kBucketId); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_BLOCKS, _)) + .WillOnce(SetArgPointee<2>(0)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + EXPECT_EQ(sizeof(UniformBlocksHeader), bucket->size()); + UniformBlocksHeader* header = + bucket->GetDataAs<UniformBlocksHeader*>(0, sizeof(UniformBlocksHeader)); + EXPECT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_uniform_blocks); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformBlocksCHROMIUMInvalidArgs) { + const uint32 kBucketId = 123; + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + EXPECT_TRUE(bucket == NULL); + GetUniformBlocksCHROMIUM cmd; + cmd.Init(kInvalidClientId, kBucketId); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + bucket = decoder_->GetBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + EXPECT_EQ(sizeof(UniformBlocksHeader), bucket->size()); + UniformBlocksHeader* header = + bucket->GetDataAs<UniformBlocksHeader*>(0, sizeof(UniformBlocksHeader)); + ASSERT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_uniform_blocks); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformsES3CHROMIUMValidArgs) { + const uint32 kBucketId = 123; + GetUniformsES3CHROMIUM cmd; + cmd.Init(client_program_id_, kBucketId); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgPointee<2>(0)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + EXPECT_EQ(sizeof(UniformsES3Header), bucket->size()); + UniformsES3Header* header = + bucket->GetDataAs<UniformsES3Header*>(0, sizeof(UniformsES3Header)); + EXPECT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_uniforms); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformsES3CHROMIUMInvalidArgs) { + const uint32 kBucketId = 123; + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + EXPECT_TRUE(bucket == NULL); + GetUniformsES3CHROMIUM cmd; + cmd.Init(kInvalidClientId, kBucketId); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + bucket = decoder_->GetBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + EXPECT_EQ(sizeof(UniformsES3Header), bucket->size()); + UniformsES3Header* header = + bucket->GetDataAs<UniformsES3Header*>(0, sizeof(UniformsES3Header)); + ASSERT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_uniforms); +} + +TEST_P(GLES2DecoderWithShaderTest, + GetTransformFeedbackVaryingsCHROMIUMValidArgs) { + const uint32 kBucketId = 123; + GetTransformFeedbackVaryingsCHROMIUM cmd; + cmd.Init(client_program_id_, kBucketId); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetProgramiv( + kServiceProgramId, GL_TRANSFORM_FEEDBACK_VARYINGS, _)) + .WillOnce(SetArgPointee<2>(0)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader), bucket->size()); + TransformFeedbackVaryingsHeader* header = + bucket->GetDataAs<TransformFeedbackVaryingsHeader*>( + 0, sizeof(TransformFeedbackVaryingsHeader)); + EXPECT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_transform_feedback_varyings); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, + GetTransformFeedbackVaryingsCHROMIUMInvalidArgs) { + const uint32 kBucketId = 123; + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + EXPECT_TRUE(bucket == NULL); + GetTransformFeedbackVaryingsCHROMIUM cmd; + cmd.Init(kInvalidClientId, kBucketId); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + bucket = decoder_->GetBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader), bucket->size()); + TransformFeedbackVaryingsHeader* header = + bucket->GetDataAs<TransformFeedbackVaryingsHeader*>( + 0, sizeof(TransformFeedbackVaryingsHeader)); + ASSERT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_transform_feedback_varyings); +} + TEST_P(GLES2DecoderWithShaderTest, GetUniformivSucceeds) { GetUniformiv::Result* result = static_cast<GetUniformiv::Result*>(shared_memory_address_); @@ -93,8 +219,8 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformivSucceeds) { EXPECT_CALL(*gl_, GetUniformiv(kServiceProgramId, kUniform2RealLocation, _)) .Times(1); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type), - result->size); + EXPECT_EQ(GLES2Util::GetElementCountForUniformType(kUniform2Type), + static_cast<uint32>(result->GetNumResults())); } TEST_P(GLES2DecoderWithShaderTest, GetUniformivArrayElementSucceeds) { @@ -110,8 +236,8 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformivArrayElementSucceeds) { GetUniformiv(kServiceProgramId, kUniform2ElementRealLocation, _)) .Times(1); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type), - result->size); + EXPECT_EQ(GLES2Util::GetElementCountForUniformType(kUniform2Type), + static_cast<uint32>(result->GetNumResults())); } TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) { @@ -189,6 +315,121 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadSharedMemoryFails) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); }; +TEST_P(GLES2DecoderWithShaderTest, GetUniformuivSucceeds) { + GetUniformuiv::Result* result = + static_cast<GetUniformuiv::Result*>(shared_memory_address_); + result->size = 0; + GetUniformuiv cmd; + cmd.Init(client_program_id_, + kUniform2FakeLocation, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformuiv(kServiceProgramId, kUniform2RealLocation, _)) + .Times(1); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GLES2Util::GetElementCountForUniformType(kUniform2Type), + static_cast<uint32>(result->GetNumResults())); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformuivArrayElementSucceeds) { + GetUniformuiv::Result* result = + static_cast<GetUniformuiv::Result*>(shared_memory_address_); + result->size = 0; + GetUniformuiv cmd; + cmd.Init(client_program_id_, + kUniform2ElementFakeLocation, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_CALL(*gl_, + GetUniformuiv(kServiceProgramId, kUniform2ElementRealLocation, _)) + .Times(1); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GLES2Util::GetElementCountForUniformType(kUniform2Type), + static_cast<uint32>(result->GetNumResults())); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformuivBadProgramFails) { + GetUniformuiv::Result* result = + static_cast<GetUniformuiv::Result*>(shared_memory_address_); + result->size = 0; + GetUniformuiv cmd; + // non-existant program + cmd.Init(kInvalidClientId, + kUniform2FakeLocation, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformuiv(_, _, _)).Times(0); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0U, result->size); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +// Valid id that is not a program. The GL spec requires a different error for +// this case. +#if GLES2_TEST_SHADER_VS_PROGRAM_IDS + result->size = kInitialResult; + cmd.Init(client_shader_id_, + kUniform2FakeLocation, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0U, result->size); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +#endif // GLES2_TEST_SHADER_VS_PROGRAM_IDS + // Unlinked program + EXPECT_CALL(*gl_, CreateProgram()) + .Times(1) + .WillOnce(Return(kNewServiceId)) + .RetiresOnSaturation(); + CreateProgram cmd2; + cmd2.Init(kNewClientId); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); + result->size = kInitialResult; + cmd.Init(kNewClientId, + kUniform2FakeLocation, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0U, result->size); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformuivBadLocationFails) { + GetUniformuiv::Result* result = + static_cast<GetUniformuiv::Result*>(shared_memory_address_); + result->size = 0; + GetUniformuiv cmd; + // invalid location + cmd.Init(client_program_id_, + kInvalidUniformLocation, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformuiv(_, _, _)).Times(0); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0U, result->size); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformuivBadSharedMemoryFails) { + GetUniformuiv cmd; + cmd.Init(client_program_id_, + kUniform2FakeLocation, + kInvalidSharedMemoryId, + kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformuiv(_, _, _)).Times(0); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + decoder_->set_unsafe_es3_apis_enabled(true); + cmd.Init(client_program_id_, + kUniform2FakeLocation, + kSharedMemoryId, + kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +}; + TEST_P(GLES2DecoderWithShaderTest, GetUniformfvSucceeds) { GetUniformfv::Result* result = static_cast<GetUniformfv::Result*>(shared_memory_address_); @@ -201,8 +442,8 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformfvSucceeds) { EXPECT_CALL(*gl_, GetUniformfv(kServiceProgramId, kUniform2RealLocation, _)) .Times(1); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type), - result->size); + EXPECT_EQ(GLES2Util::GetElementCountForUniformType(kUniform2Type), + static_cast<uint32>(result->GetNumResults())); } TEST_P(GLES2DecoderWithShaderTest, GetUniformfvArrayElementSucceeds) { @@ -218,8 +459,8 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformfvArrayElementSucceeds) { GetUniformfv(kServiceProgramId, kUniform2ElementRealLocation, _)) .Times(1); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type), - result->size); + EXPECT_EQ(GLES2Util::GetElementCountForUniformType(kUniform2Type), + static_cast<uint32>(result->GetNumResults())); } TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) { @@ -303,7 +544,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetAttachedShadersSucceeds) { Result* result = static_cast<Result*>(shared_memory_address_); result->size = 0; EXPECT_CALL(*gl_, GetAttachedShaders(kServiceProgramId, 1, _, _)).WillOnce( - DoAll(SetArgumentPointee<2>(1), SetArgumentPointee<3>(kServiceShaderId))); + DoAll(SetArgPointee<2>(1), SetArgPointee<3>(kServiceShaderId))); cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_, @@ -368,7 +609,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatSucceeds) { const GLint precision = 16; EXPECT_CALL(*gl_, GetShaderPrecisionFormat(_, _, _, _)) .WillOnce(DoAll(SetArrayArgument<2>(range, range + 2), - SetArgumentPointee<3>(precision))) + SetArgPointee<3>(precision))) .RetiresOnSaturation(); cmd.Init(GL_VERTEX_SHADER, GL_HIGH_FLOAT, @@ -530,6 +771,285 @@ TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBadSharedMemoryFails) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockNameSucceeds) { + const uint32 kBucketId = 123; + GetActiveUniformBlockName cmd; + typedef GetActiveUniformBlockName::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + *result = 0; + cmd.Init(client_program_id_, + 0, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + const char kName[] = "HolyCow"; + const GLsizei kMaxLength = strlen(kName) + 1; + EXPECT_CALL(*gl_, + GetProgramiv(kServiceProgramId, + GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, _)) + .WillOnce(SetArgPointee<2>(kMaxLength)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetActiveUniformBlockName(kServiceProgramId, 0, _, _, _)) + .WillOnce(DoAll(SetArgPointee<3>(strlen(kName)), + SetArrayArgument<4>(kName, kName + strlen(kName) + 1))) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_NE(0, *result); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + EXPECT_EQ(0, + memcmp(bucket->GetData(0, bucket->size()), kName, bucket->size())); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockNameUnlinkedProgram) { + const uint32 kBucketId = 123; + GetActiveUniformBlockName cmd; + typedef GetActiveUniformBlockName::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + *result = 0; + cmd.Init(client_program_id_, + 0, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_FALSE)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, *result); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, + GetActiveUniformBlockNameResultNotInitFails) { + const uint32 kBucketId = 123; + GetActiveUniformBlockName cmd; + typedef GetActiveUniformBlockName::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + *result = 1; + cmd.Init(client_program_id_, + 0, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockNameBadProgramFails) { + const uint32 kBucketId = 123; + GetActiveUniformBlockName cmd; + typedef GetActiveUniformBlockName::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + *result = 0; + cmd.Init(kInvalidClientId, + 0, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, *result); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, + GetActiveUniformBlockNameBadSharedMemoryFails) { + const uint32 kBucketId = 123; + GetActiveUniformBlockName cmd; + decoder_->set_unsafe_es3_apis_enabled(true); + cmd.Init(client_program_id_, + 0, + kBucketId, + kInvalidSharedMemoryId, + shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, + 0, + kBucketId, + shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockivSucceeds) { + GetActiveUniformBlockiv cmd; + typedef GetActiveUniformBlockiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + GLenum kPname[] { + GL_UNIFORM_BLOCK_BINDING, + GL_UNIFORM_BLOCK_DATA_SIZE, + GL_UNIFORM_BLOCK_NAME_LENGTH, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, + GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, + }; + for (size_t ii = 0; ii < arraysize(kPname); ++ii) { + result->SetNumResults(0); + cmd.Init(client_program_id_, + 0, + kPname[ii], + shared_memory_id_, + shared_memory_offset_); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + if (kPname[ii] == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetActiveUniformBlockiv(kServiceProgramId, 0, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgPointee<3>(1)) + .RetiresOnSaturation(); + } + EXPECT_CALL(*gl_, + GetActiveUniformBlockiv( + kServiceProgramId, 0, kPname[ii], _)) + .WillOnce(SetArgPointee<3>(1976)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(1, result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_EQ(1976, result->GetData()[0]); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); + } +} + +TEST_P(GLES2DecoderWithShaderTest, + GetActiveUniformBlockivSucceedsZeroUniforms) { + GetActiveUniformBlockiv cmd; + typedef GetActiveUniformBlockiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->SetNumResults(0); + cmd.Init(client_program_id_, + 0, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + shared_memory_id_, + shared_memory_offset_); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetActiveUniformBlockiv( + kServiceProgramId, 0, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgPointee<3>(0)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetActiveUniformBlockiv(kServiceProgramId, 0, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, _)) + .Times(1) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockivUnlinkedProgram) { + GetActiveUniformBlockiv cmd; + typedef GetActiveUniformBlockiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->SetNumResults(0); + cmd.Init(client_program_id_, + 0, + GL_UNIFORM_BLOCK_BINDING, + shared_memory_id_, + shared_memory_offset_); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_FALSE)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, + GetActiveUniformBlockivResultNotInitFails) { + GetActiveUniformBlockiv cmd; + typedef GetActiveUniformBlockiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->SetNumResults(1); // Should be initialized to 0. + cmd.Init(client_program_id_, + 0, + GL_UNIFORM_BLOCK_BINDING, + shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBlockivBadProgramFails) { + GetActiveUniformBlockiv cmd; + typedef GetActiveUniformBlockiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->SetNumResults(0); + cmd.Init(kInvalidClientId, + 0, + GL_UNIFORM_BLOCK_BINDING, + shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, + GetActiveUniformBlockivBadSharedMemoryFails) { + GetActiveUniformBlockiv cmd; + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + cmd.Init(client_program_id_, + 0, + GL_UNIFORM_BLOCK_BINDING, + kInvalidSharedMemoryId, + shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, + 0, + GL_UNIFORM_BLOCK_BINDING, + shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribSucceeds) { const GLuint kAttribIndex = 1; const uint32 kBucketId = 123; @@ -631,6 +1151,306 @@ TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribBadSharedMemoryFails) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } +TEST_P(GLES2DecoderWithShaderTest, GetUniformIndicesSucceeds) { + const uint32 kBucketId = 123; + const char kName0[] = "Cow"; + const char kName1[] = "Chicken"; + const char* kNames[] = { kName0, kName1 }; + const size_t kCount = arraysize(kNames); + const char kValidStrEnd = 0; + const GLuint kIndices[] = { 1, 2 }; + SetBucketAsCStrings(kBucketId, kCount, kNames, kCount, kValidStrEnd); + GetUniformIndices::Result* result = + static_cast<GetUniformIndices::Result*>(shared_memory_address_); + GetUniformIndices cmd; + cmd.Init(client_program_id_, + kBucketId, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformIndices(kServiceProgramId, kCount, _, _)) + .WillOnce(SetArrayArgument<3>(kIndices, kIndices + kCount)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + result->size = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(kCount, static_cast<size_t>(result->GetNumResults())); + for (size_t ii = 0; ii < kCount; ++ii) { + EXPECT_EQ(kIndices[ii], result->GetData()[ii]); + } + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformIndicesBadProgramFails) { + const uint32 kBucketId = 123; + const char kName0[] = "Cow"; + const char kName1[] = "Chicken"; + const char* kNames[] = { kName0, kName1 }; + const size_t kCount = arraysize(kNames); + const char kValidStrEnd = 0; + SetBucketAsCStrings(kBucketId, kCount, kNames, kCount, kValidStrEnd); + GetUniformIndices::Result* result = + static_cast<GetUniformIndices::Result*>(shared_memory_address_); + decoder_->set_unsafe_es3_apis_enabled(true); + GetUniformIndices cmd; + // None-existant program + cmd.Init(kInvalidClientId, + kBucketId, + kSharedMemoryId, + kSharedMemoryOffset); + result->size = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + // Unlinked program. + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_FALSE)) + .RetiresOnSaturation(); + cmd.Init(client_program_id_, + kBucketId, + kSharedMemoryId, + kSharedMemoryOffset); + result->size = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformIndicesBadParamsFails) { + const uint32 kBucketId = 123; + const char kName0[] = "Cow"; + const char kName1[] = "Chicken"; + const char* kNames[] = { kName0, kName1 }; + const size_t kCount = arraysize(kNames); + const char kValidStrEnd = 0; + const GLuint kIndices[] = { 1, 2 }; + SetBucketAsCStrings(kBucketId, kCount, kNames, kCount, kValidStrEnd); + GetUniformIndices::Result* result = + static_cast<GetUniformIndices::Result*>(shared_memory_address_); + GetUniformIndices cmd; + cmd.Init(client_program_id_, + kBucketId, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformIndices(kServiceProgramId, kCount, _, _)) + .WillOnce(SetArrayArgument<3>(kIndices, kIndices + kCount)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_INVALID_VALUE)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + result->size = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformIndicesResultNotInitFails) { + const uint32 kBucketId = 123; + const char kName0[] = "Cow"; + const char kName1[] = "Chicken"; + const char* kNames[] = { kName0, kName1 }; + const size_t kCount = arraysize(kNames); + const char kValidStrEnd = 0; + SetBucketAsCStrings(kBucketId, kCount, kNames, kCount, kValidStrEnd); + GetUniformIndices::Result* result = + static_cast<GetUniformIndices::Result*>(shared_memory_address_); + decoder_->set_unsafe_es3_apis_enabled(true); + GetUniformIndices cmd; + result->size = 1976; // Any value other than 0. + cmd.Init(kInvalidClientId, + kBucketId, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformIndicesBadSharedMemoryFails) { + const uint32 kBucketId = 123; + const char kName0[] = "Cow"; + const char kName1[] = "Chicken"; + const char* kNames[] = { kName0, kName1 }; + const size_t kCount = arraysize(kNames); + const char kValidStrEnd = 0; + SetBucketAsCStrings(kBucketId, kCount, kNames, kCount, kValidStrEnd); + GetUniformIndices::Result* result = + static_cast<GetUniformIndices::Result*>(shared_memory_address_); + decoder_->set_unsafe_es3_apis_enabled(true); + GetUniformIndices cmd; + cmd.Init(client_program_id_, + kBucketId, + kInvalidSharedMemoryId, + kSharedMemoryOffset); + result->size = 0; + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, + kBucketId, + kSharedMemoryId, + kInvalidSharedMemoryOffset); + result->size = 0; + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformsivSucceeds) { + const uint32 kBucketId = 123; + const GLuint kIndices[] = { 1, 2 }; + const GLint kResults[] = { 1976, 321 }; + const size_t kCount = arraysize(kIndices); + SetBucketData(kBucketId, kIndices, sizeof(GLuint) * kCount); + GetActiveUniformsiv::Result* result = + static_cast<GetActiveUniformsiv::Result*>(shared_memory_address_); + GetActiveUniformsiv cmd; + cmd.Init(client_program_id_, + kBucketId, + GL_UNIFORM_TYPE, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_CALL(*gl_, + GetActiveUniformsiv( + kServiceProgramId, kCount, _, GL_UNIFORM_TYPE, _)) + .WillOnce(SetArrayArgument<4>(kResults, kResults + kCount)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + result->size = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(kCount, static_cast<size_t>(result->GetNumResults())); + for (size_t ii = 0; ii < kCount; ++ii) { + EXPECT_EQ(kResults[ii], result->GetData()[ii]); + } + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformsivBadProgramFails) { + const uint32 kBucketId = 123; + const GLuint kIndices[] = { 1, 2 }; + const size_t kCount = arraysize(kIndices); + SetBucketData(kBucketId, kIndices, sizeof(GLuint) * kCount); + GetActiveUniformsiv::Result* result = + static_cast<GetActiveUniformsiv::Result*>(shared_memory_address_); + decoder_->set_unsafe_es3_apis_enabled(true); + GetActiveUniformsiv cmd; + // None-existant program + cmd.Init(kInvalidClientId, + kBucketId, + GL_UNIFORM_TYPE, + kSharedMemoryId, + kSharedMemoryOffset); + result->size = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + // Unlinked program. + cmd.Init(client_program_id_, + kBucketId, + GL_UNIFORM_TYPE, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_FALSE)) + .RetiresOnSaturation(); + result->size = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformsivBadParamsFails) { + const uint32 kBucketId = 123; + const GLuint kIndices[] = { 1, 2 }; + const GLint kResults[] = { 1976, 321 }; + const size_t kCount = arraysize(kIndices); + SetBucketData(kBucketId, kIndices, sizeof(GLuint) * kCount); + GetActiveUniformsiv::Result* result = + static_cast<GetActiveUniformsiv::Result*>(shared_memory_address_); + GetActiveUniformsiv cmd; + cmd.Init(client_program_id_, + kBucketId, + GL_UNIFORM_TYPE, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_CALL(*gl_, + GetActiveUniformsiv( + kServiceProgramId, kCount, _, GL_UNIFORM_TYPE, _)) + .WillOnce(SetArrayArgument<4>(kResults, kResults + kCount)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_INVALID_VALUE)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + result->size = 0; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->GetNumResults()); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformsivResultNotInitFails) { + const uint32 kBucketId = 123; + const GLuint kIndices[] = { 1, 2 }; + const size_t kCount = arraysize(kIndices); + SetBucketData(kBucketId, kIndices, sizeof(GLuint) * kCount); + GetActiveUniformsiv::Result* result = + static_cast<GetActiveUniformsiv::Result*>(shared_memory_address_); + GetActiveUniformsiv cmd; + cmd.Init(client_program_id_, + kBucketId, + GL_UNIFORM_TYPE, + kSharedMemoryId, + kSharedMemoryOffset); + decoder_->set_unsafe_es3_apis_enabled(true); + result->size = 1976; // Any value other than 0. + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformsivBadSharedMemoryFails) { + const uint32 kBucketId = 123; + const GLuint kIndices[] = { 1, 2 }; + const size_t kCount = arraysize(kIndices); + SetBucketData(kBucketId, kIndices, sizeof(GLuint) * kCount); + GetActiveUniformsiv::Result* result = + static_cast<GetActiveUniformsiv::Result*>(shared_memory_address_); + GetActiveUniformsiv cmd; + decoder_->set_unsafe_es3_apis_enabled(true); + result->size = 0; + cmd.Init(client_program_id_, + kBucketId, + GL_UNIFORM_TYPE, + kInvalidSharedMemoryId, + kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + result->size = 0; + cmd.Init(client_program_id_, + kBucketId, + GL_UNIFORM_TYPE, + kSharedMemoryId, + kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderWithShaderTest, GetShaderInfoLogValidArgs) { const char* kInfo = "hello"; const uint32 kBucketId = 123; @@ -639,13 +1459,13 @@ TEST_P(GLES2DecoderWithShaderTest, GetShaderInfoLogValidArgs) { EXPECT_CALL(*gl_, ShaderSource(kServiceShaderId, 1, _, _)); EXPECT_CALL(*gl_, CompileShader(kServiceShaderId)); EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_COMPILE_STATUS, _)) - .WillOnce(SetArgumentPointee<2>(GL_FALSE)) + .WillOnce(SetArgPointee<2>(GL_FALSE)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_INFO_LOG_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(strlen(kInfo) + 1)) + .WillOnce(SetArgPointee<2>(strlen(kInfo) + 1)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, GetShaderInfoLog(kServiceShaderId, strlen(kInfo) + 1, _, _)) - .WillOnce(DoAll(SetArgumentPointee<2>(strlen(kInfo)), + .WillOnce(DoAll(SetArgPointee<2>(strlen(kInfo)), SetArrayArgument<3>(kInfo, kInfo + strlen(kInfo) + 1))); compile_cmd.Init(client_shader_id_); cmd.Init(client_shader_id_, kBucketId); @@ -667,15 +1487,168 @@ TEST_P(GLES2DecoderWithShaderTest, GetShaderInfoLogInvalidArgs) { EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); } +TEST_P(GLES2DecoderWithShaderTest, GetTransformFeedbackVaryingSucceeds) { + const GLuint kIndex = 1; + const uint32 kBucketId = 123; + const char kName[] = "HolyCow"; + const GLsizei kBufferSize = static_cast<GLsizei>(strlen(kName) + 1); + const GLsizei kSize = 2; + const GLenum kType = GL_FLOAT_VEC2; + GetTransformFeedbackVarying cmd; + typedef GetTransformFeedbackVarying::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, + GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, _)) + .WillOnce(SetArgPointee<2>(kBufferSize)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetTransformFeedbackVarying( + kServiceProgramId, kIndex, _, _, _, _, _)) + .WillOnce(DoAll(SetArgPointee<3>(kBufferSize - 1), + SetArgPointee<4>(kSize), + SetArgPointee<5>(kType), + SetArrayArgument<6>(kName, kName + kBufferSize))) + .RetiresOnSaturation(); + cmd.Init(client_program_id_, + kIndex, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_NE(0, result->success); + EXPECT_EQ(kSize, static_cast<GLsizei>(result->size)); + EXPECT_EQ(kType, static_cast<GLenum>(result->type)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + EXPECT_EQ( + 0, memcmp(bucket->GetData(0, bucket->size()), kName, bucket->size())); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetTransformFeedbackVaryingNotInitFails) { + const GLuint kIndex = 1; + const uint32 kBucketId = 123; + GetTransformFeedbackVarying cmd; + typedef GetTransformFeedbackVarying::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 1; + cmd.Init(client_program_id_, + kIndex, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetTransformFeedbackVaryingBadProgramFails) { + const GLuint kIndex = 1; + const uint32 kBucketId = 123; + GetTransformFeedbackVarying cmd; + typedef GetTransformFeedbackVarying::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; + cmd.Init(kInvalidClientId, + kIndex, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->success); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, GetTransformFeedbackVaryingBadParamsFails) { + const GLuint kIndex = 1; + const uint32 kBucketId = 123; + const GLsizei kBufferSize = 10; + GetTransformFeedbackVarying cmd; + typedef GetTransformFeedbackVarying::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; + cmd.Init(client_program_id_, + kIndex, + kBucketId, + shared_memory_id_, + shared_memory_offset_); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, + GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, _)) + .WillOnce(SetArgPointee<2>(kBufferSize)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_INVALID_VALUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetTransformFeedbackVarying( + kServiceProgramId, kIndex, _, _, _, _, _)) + .Times(1) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->success); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderWithShaderTest, + GetTransformFeedbackVaryingBadSharedMemoryFails) { + const GLuint kIndex = 1; + const uint32 kBucketId = 123; + GetTransformFeedbackVarying cmd; + typedef GetTransformFeedbackVarying::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->success = 0; + decoder_->set_unsafe_es3_apis_enabled(true); + cmd.Init(client_program_id_, + kIndex, + kBucketId, + kInvalidSharedMemoryId, + shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, + kIndex, + kBucketId, + shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest, CompileShaderValidArgs) { + // Compile shader should not actually call any GL calls yet. + CompileShader cmd; + cmd.Init(client_shader_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + + // Getting the shader compilation state should trigger the actual GL calls. EXPECT_CALL(*gl_, ShaderSource(kServiceShaderId, 1, _, _)); EXPECT_CALL(*gl_, CompileShader(kServiceShaderId)); EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_COMPILE_STATUS, _)) - .WillOnce(SetArgumentPointee<2>(GL_TRUE)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) .RetiresOnSaturation(); - CompileShader cmd; - cmd.Init(client_shader_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + + GetShaderiv status_cmd; + status_cmd.Init(client_shader_id_, GL_COMPILE_STATUS, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(status_cmd)); } TEST_P(GLES2DecoderTest, CompileShaderInvalidArgs) { @@ -693,9 +1666,10 @@ TEST_P(GLES2DecoderTest, CompileShaderInvalidArgs) { TEST_P(GLES2DecoderTest, ShaderSourceBucketAndGetShaderSourceValidArgs) { const uint32 kInBucketId = 123; const uint32 kOutBucketId = 125; - const char kSource[] = "hello"; - const uint32 kSourceSize = sizeof(kSource) - 1; - SetBucketAsCString(kInBucketId, kSource); + const char kSource0[] = "hello"; + const char* kSource[] = { kSource0 }; + const char kValidStrEnd = 0; + SetBucketAsCStrings(kInBucketId, 1, kSource, 1, kValidStrEnd); ShaderSourceBucket cmd; cmd.Init(client_shader_id_, kInBucketId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -705,38 +1679,31 @@ TEST_P(GLES2DecoderTest, ShaderSourceBucketAndGetShaderSourceValidArgs) { EXPECT_EQ(error::kNoError, ExecuteCmd(get_cmd)); CommonDecoder::Bucket* bucket = decoder_->GetBucket(kOutBucketId); ASSERT_TRUE(bucket != NULL); - EXPECT_EQ(kSourceSize + 1, bucket->size()); - EXPECT_EQ( - 0, memcmp(bucket->GetData(0, bucket->size()), kSource, bucket->size())); + EXPECT_EQ(sizeof(kSource0), bucket->size()); + EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), + kSource0, bucket->size())); } -TEST_P(GLES2DecoderTest, ShaderSourceBucketInvalidArgs) { +#if GLES2_TEST_SHADER_VS_PROGRAM_IDS +TEST_P(GLES2DecoderTest, ShaderSourceBucketWithProgramId) { const uint32 kBucketId = 123; - const char kSource[] = "hello"; - const uint32 kSourceSize = sizeof(kSource) - 1; - memcpy(shared_memory_address_, kSource, kSourceSize); + const char kSource0[] = "hello"; + const char* kSource[] = { kSource0 }; + const char kValidStrEnd = 0; + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kValidStrEnd); ShaderSourceBucket cmd; - // Test no bucket. - cmd.Init(client_texture_id_, kBucketId); - EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - // Test invalid client. - SetBucketAsCString(kBucketId, kSource); - cmd.Init(kInvalidClientId, kBucketId); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); -#if GLES2_TEST_SHADER_VS_PROGRAM_IDS - SetBucketAsCString(kBucketId, kSource); - cmd.Init( - client_program_id_, kBucketId); + cmd.Init(client_program_id_, kBucketId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); -#endif // GLES2_TEST_SHADER_VS_PROGRAM_IDS } +#endif // GLES2_TEST_SHADER_VS_PROGRAM_IDS TEST_P(GLES2DecoderTest, ShaderSourceStripComments) { const uint32 kInBucketId = 123; - const char kSource[] = "hello/*te\ast*/world//a\ab"; - SetBucketAsCString(kInBucketId, kSource); + const char kSource0[] = "hello/*te\ast*/world//a\ab"; + const char* kSource[] = { kSource0 }; + const char kValidStrEnd = 0; + SetBucketAsCStrings(kInBucketId, 1, kSource, 1, kValidStrEnd); ShaderSourceBucket cmd; cmd.Init(client_shader_id_, kInBucketId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -881,6 +1848,110 @@ TEST_P(GLES2DecoderWithShaderTest, GetAttribLocationInvalidArgs) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } +TEST_P(GLES2DecoderWithShaderTest, GetFragDataLocation) { + const uint32 kBucketId = 123; + const GLint kLocation = 10; + const char* kName = "color"; + typedef GetFragDataLocation::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + SetBucketAsCString(kBucketId, kName); + *result = -1; + GetFragDataLocation cmd; + cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetFragDataLocation(kServiceProgramId, StrEq(kName))) + .WillOnce(Return(kLocation)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(kLocation, *result); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetFragDataLocationInvalidArgs) { + const uint32 kBucketId = 123; + typedef GetFragDataLocation::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = -1; + GetFragDataLocation cmd; + decoder_->set_unsafe_es3_apis_enabled(true); + // Check no bucket + cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(-1, *result); + // Check bad program id. + const char* kName = "color"; + SetBucketAsCString(kBucketId, kName); + cmd.Init(kInvalidClientId, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + *result = -1; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(-1, *result); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + // Check bad memory + cmd.Init(client_program_id_, + kBucketId, + kInvalidSharedMemoryId, + kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, + kBucketId, + kSharedMemoryId, + kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformBlockIndex) { + const uint32 kBucketId = 123; + const GLuint kIndex = 10; + const char* kName = "color"; + typedef GetUniformBlockIndex::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + SetBucketAsCString(kBucketId, kName); + *result = GL_INVALID_INDEX; + GetUniformBlockIndex cmd; + cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformBlockIndex(kServiceProgramId, StrEq(kName))) + .WillOnce(Return(kIndex)) + .RetiresOnSaturation(); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(kIndex, *result); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderWithShaderTest, GetUniformBlockIndexInvalidArgs) { + const uint32 kBucketId = 123; + typedef GetUniformBlockIndex::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = GL_INVALID_INDEX; + GetUniformBlockIndex cmd; + decoder_->set_unsafe_es3_apis_enabled(true); + // Check no bucket + cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_INDEX, *result); + // Check bad program id. + const char* kName = "color"; + SetBucketAsCString(kBucketId, kName); + cmd.Init(kInvalidClientId, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + *result = GL_INVALID_INDEX; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_INDEX, *result); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + // Check bad memory + cmd.Init(client_program_id_, + kBucketId, + kInvalidSharedMemoryId, + kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, + kBucketId, + kSharedMemoryId, + kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderWithShaderTest, GetUniformLocation) { const uint32 kBucketId = 123; const char* kNonExistentName = "foobar"; @@ -929,6 +2000,18 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformLocationInvalidArgs) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } +TEST_P(GLES2DecoderWithShaderTest, UniformBlockBindingValidArgs) { + EXPECT_CALL(*gl_, UniformBlockBinding(kServiceProgramId, 2, 3)); + SpecializedSetup<cmds::UniformBlockBinding, 0>(true); + cmds::UniformBlockBinding cmd; + cmd.Init(client_program_id_, 2, 3); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderWithShaderTest, BindUniformLocationCHROMIUMBucket) { const uint32 kBucketId = 123; const GLint kLocation = 2; @@ -981,12 +2064,11 @@ TEST_P(GLES2DecoderWithShaderTest, BindUniformLocationCHROMIUMBucket) { } TEST_P(GLES2DecoderManualInitTest, ClearUniformsBeforeFirstProgramUse) { - CommandLine command_line(0, NULL); + base::CommandLine command_line(0, NULL); command_line.AppendSwitchASCII( switches::kGpuDriverBugWorkarounds, base::IntToString(gpu::CLEAR_UNIFORMS_BEFORE_FIRST_PROGRAM_USE)); InitState init; - init.gl_version = "3.0"; init.has_alpha = true; init.request_alpha = true; init.bind_generates_resource = true; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc index 82d5653b572..2d1330111b6 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc @@ -17,13 +17,12 @@ #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/gl_surface_mock.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" - -#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/program_manager.h" #include "gpu/command_buffer/service/test_helper.h" +#include "gpu/config/gpu_switches.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_image_stub.h" #include "ui/gl/gl_implementation.h" @@ -74,7 +73,8 @@ TEST_P(GLES2DecoderTest, GenerateMipmapHandlesOutOfMemory) { Texture* texture = texture_ref->texture(); GLint width = 0; GLint height = 0; - EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 2, &width, &height)); + EXPECT_FALSE( + texture->GetLevelSize(GL_TEXTURE_2D, 2, &width, &height, nullptr)); DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, @@ -94,7 +94,8 @@ TEST_P(GLES2DecoderTest, GenerateMipmapHandlesOutOfMemory) { cmd.Init(GL_TEXTURE_2D); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); - EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 2, &width, &height)); + EXPECT_FALSE( + texture->GetLevelSize(GL_TEXTURE_2D, 2, &width, &height, nullptr)); } TEST_P(GLES2DecoderTest, GenerateMipmapClearsUnclearedTexture) { @@ -126,12 +127,11 @@ TEST_P(GLES2DecoderTest, GenerateMipmapClearsUnclearedTexture) { // Same as GenerateMipmapClearsUnclearedTexture, but with workaround // |set_texture_filters_before_generating_mipmap|. TEST_P(GLES2DecoderManualInitTest, SetTextureFiltersBeforeGenerateMipmap) { - CommandLine command_line(0, NULL); + base::CommandLine command_line(0, NULL); command_line.AppendSwitchASCII( switches::kGpuDriverBugWorkarounds, base::IntToString(gpu::SET_TEXTURE_FILTER_BEFORE_GENERATING_MIPMAP)); InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoderWithCommandLine(init, &command_line); @@ -577,7 +577,8 @@ TEST_P(GLES2DecoderTest, TexImage2DGLError) { TextureRef* texture_ref = manager->GetTexture(client_texture_id_); ASSERT_TRUE(texture_ref != NULL); Texture* texture = texture_ref->texture(); - EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height)); + EXPECT_FALSE( + texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height, nullptr)); EXPECT_CALL(*gl_, GetError()) .WillOnce(Return(GL_NO_ERROR)) .WillOnce(Return(GL_OUT_OF_MEMORY)) @@ -606,7 +607,8 @@ TEST_P(GLES2DecoderTest, TexImage2DGLError) { kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); - EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height)); + EXPECT_FALSE( + texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height, nullptr)); } TEST_P(GLES2DecoderTest, CopyTexImage2DGLError) { @@ -621,7 +623,8 @@ TEST_P(GLES2DecoderTest, CopyTexImage2DGLError) { TextureRef* texture_ref = manager->GetTexture(client_texture_id_); ASSERT_TRUE(texture_ref != NULL); Texture* texture = texture_ref->texture(); - EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height)); + EXPECT_FALSE( + texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height, nullptr)); EXPECT_CALL(*gl_, GetError()) .WillOnce(Return(GL_NO_ERROR)) .WillOnce(Return(GL_OUT_OF_MEMORY)) @@ -635,13 +638,281 @@ TEST_P(GLES2DecoderTest, CopyTexImage2DGLError) { cmd.Init(target, level, internal_format, 0, 0, width, height); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); - EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height)); + EXPECT_FALSE( + texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height, nullptr)); +} + +TEST_P(GLES3DecoderTest, CompressedTexImage3DBucket) { + const uint32 kBucketId = 123; + const uint32 kBadBucketId = 99; + const GLenum kTarget = GL_TEXTURE_2D_ARRAY; + const GLint kLevel = 0; + const GLenum kInternalFormat = GL_COMPRESSED_R11_EAC; + const GLsizei kWidth = 4; + const GLsizei kHeight = 4; + const GLsizei kDepth = 4; + const GLint kBorder = 0; + CommonDecoder::Bucket* bucket = decoder_->CreateBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + const GLsizei kImageSize = 32; + bucket->SetSize(kImageSize); + + DoBindTexture(kTarget, client_texture_id_, kServiceTextureId); + + CompressedTexImage3DBucket cmd; + cmd.Init(kTarget, + kLevel, + kInternalFormat, + kWidth, + kHeight, + kDepth, + kBadBucketId); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + + cmd.Init(kTarget, + kLevel, + kInternalFormat, + kWidth, + kHeight, + kDepth, + kBucketId); + EXPECT_CALL(*gl_, + CompressedTexImage3D(kTarget, kLevel, kInternalFormat, kWidth, + kHeight, kDepth, kBorder, kImageSize, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest, CompressedTexImage3DFailsOnES2) { + const uint32 kBucketId = 123; + const GLenum kTarget = GL_TEXTURE_2D_ARRAY; + const GLint kLevel = 0; + const GLenum kInternalFormat = GL_COMPRESSED_R11_EAC; + const GLsizei kWidth = 4; + const GLsizei kHeight = 4; + const GLsizei kDepth = 4; + CommonDecoder::Bucket* bucket = decoder_->CreateBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + const GLsizei kImageSize = 32; + bucket->SetSize(kImageSize); + + { + CompressedTexImage3DBucket cmd; + cmd.Init(kTarget, + kLevel, + kInternalFormat, + kWidth, + kHeight, + kDepth, + kBucketId); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); + } + + { + CompressedTexSubImage3DBucket cmd; + cmd.Init(kTarget, + kLevel, + 0, 0, 0, + kWidth, + kHeight, + kDepth, + kInternalFormat, + kBucketId); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); + } +} + +TEST_P(GLES3DecoderTest, CompressedTexImage3DFailsWithBadImageSize) { + const uint32 kBucketId = 123; + const GLenum kTarget = GL_TEXTURE_2D_ARRAY; + const GLint kLevel = 0; + const GLenum kInternalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC; + const GLsizei kWidth = 4; + const GLsizei kHeight = 8; + const GLsizei kDepth = 4; + CommonDecoder::Bucket* bucket = decoder_->CreateBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + const GLsizei kBadImageSize = 64; + bucket->SetSize(kBadImageSize); + + DoBindTexture(kTarget, client_texture_id_, kServiceTextureId); + + CompressedTexImage3DBucket cmd; + cmd.Init(kTarget, + kLevel, + kInternalFormat, + kWidth, + kHeight, + kDepth, + kBucketId); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES3DecoderTest, CompressedTexSubImage3DFails) { + const uint32 kBucketId = 123; + const GLenum kTarget = GL_TEXTURE_2D_ARRAY; + const GLint kLevel = 0; + const GLenum kInternalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC; + const GLsizei kWidth = 4; + const GLsizei kHeight = 8; + const GLsizei kDepth = 4; + const GLint kBorder = 0; + CommonDecoder::Bucket* bucket = decoder_->CreateBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + const GLsizei kImageSize = 128; + bucket->SetSize(kImageSize); + + DoBindTexture(kTarget, client_texture_id_, kServiceTextureId); + + CompressedTexImage3DBucket tex_cmd; + tex_cmd.Init(kTarget, + kLevel, + kInternalFormat, + kWidth, + kHeight, + kDepth, + kBucketId); + EXPECT_CALL(*gl_, + CompressedTexImage3D(kTarget, kLevel, kInternalFormat, kWidth, + kHeight, kDepth, kBorder, kImageSize, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + const GLint kXOffset = 0; + const GLint kYOffset = 0; + const GLint kZOffset = 0; + const GLint kSubWidth = 4; + const GLint kSubHeight = 4; + const GLint kSubDepth = 4; + const GLenum kFormat = kInternalFormat; + CompressedTexSubImage3DBucket cmd; + + // Incorrect image size. + cmd.Init(kTarget, + kLevel, + kXOffset, + kYOffset, + kZOffset, + kSubWidth, + kSubHeight, + kSubDepth, + kFormat, + kBucketId); + const GLsizei kBadSubImageSize = 32; + const GLsizei kSubImageSize = 64; + bucket->SetSize(kBadSubImageSize); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + + // Incorrect format. + const GLenum kBadFormat = GL_COMPRESSED_R11_EAC; + cmd.Init(kTarget, + kLevel, + kXOffset, + kYOffset, + kZOffset, + kSubWidth, + kSubHeight, + kSubDepth, + kBadFormat, + kBucketId); + bucket->SetSize(kSubImageSize); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + + // Negative offset. + cmd.Init(kTarget, + kLevel, + kXOffset, + -4, + kZOffset, + kSubWidth, + kSubHeight, + kSubDepth, + kFormat, + kBucketId); + bucket->SetSize(kSubImageSize); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + + // offset + size > texture size + cmd.Init(kTarget, + kLevel, + kXOffset, + kYOffset + 8, + kZOffset, + kSubWidth, + kSubHeight, + kSubDepth, + kFormat, + kBucketId); + bucket->SetSize(kSubImageSize); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + + // offset not a multiple of 4. + cmd.Init(kTarget, + kLevel, + kXOffset, + kYOffset + 1, + kZOffset, + kSubWidth, + kSubHeight, + kSubDepth, + kFormat, + kBucketId); + bucket->SetSize(kSubImageSize); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + + // offset + width not a multlple of 4 . + cmd.Init(kTarget, + kLevel, + kXOffset, + kYOffset, + kZOffset, + kSubWidth, + kSubHeight + 3, + kSubDepth, + kFormat, + kBucketId); + const GLsizei kSubImageSize2 = 128; + bucket->SetSize(kSubImageSize2); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + + // Bad bucket id. + const uint32 kBadBucketId = 444; + cmd.Init(kTarget, + kLevel, + kXOffset, + kYOffset, + kZOffset, + kSubWidth, + kSubHeight, + kSubDepth, + kFormat, + kBadBucketId); + bucket->SetSize(kSubImageSize); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } TEST_P(GLES2DecoderManualInitTest, CompressedTexImage2DBucketBadBucket) { InitState init; init.extensions = "GL_EXT_texture_compression_s3tc"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); @@ -679,7 +950,6 @@ struct S3TCTestData { TEST_P(GLES2DecoderManualInitTest, CompressedTexImage2DS3TC) { InitState init; init.extensions = "GL_EXT_texture_compression_s3tc"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); const uint32 kBucketId = 123; @@ -911,6 +1181,8 @@ TEST_P(GLES2DecoderManualInitTest, CompressedTexImage2DETC1) { EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } + + TEST_P(GLES2DecoderManualInitTest, EGLImageExternalBindTexture) { InitState init; init.extensions = "GL_OES_EGL_image_external"; @@ -1090,7 +1362,6 @@ TEST_P(GLES2DecoderManualInitTest, EGLImageExternalTexImage2DError) { TEST_P(GLES2DecoderManualInitTest, DefaultTextureZero) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); BindTexture cmd1; @@ -1108,7 +1379,6 @@ TEST_P(GLES2DecoderManualInitTest, DefaultTextureZero) { TEST_P(GLES2DecoderManualInitTest, DefaultTextureBGR) { InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); @@ -1131,7 +1401,6 @@ TEST_P(GLES2DecoderManualInitTest, DefaultTextureBGR) { // Test that default texture 0 is immutable. TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameterf) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); { @@ -1163,7 +1432,6 @@ TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameterf) { TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameteri) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); { @@ -1195,7 +1463,6 @@ TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameteri) { TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameterfv) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); { @@ -1235,7 +1502,6 @@ TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameterfv) { TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameteriv) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); { @@ -1275,7 +1541,6 @@ TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameteriv) { TEST_P(GLES2DecoderManualInitTest, NoDefaultTexImage2D) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); BindTexture cmd1; @@ -1300,7 +1565,6 @@ TEST_P(GLES2DecoderManualInitTest, NoDefaultTexImage2D) { TEST_P(GLES2DecoderManualInitTest, NoDefaultTexSubImage2D) { InitState init; - init.gl_version = "3.0"; InitDecoder(init); BindTexture cmd1; @@ -1328,7 +1592,6 @@ TEST_P(GLES2DecoderManualInitTest, NoDefaultTexSubImage2D) { TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleBindTexture) { InitState init; init.extensions = "GL_ARB_texture_rectangle"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_RECTANGLE_ARB, kNewServiceId)); @@ -1346,7 +1609,6 @@ TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleBindTexture) { TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleGetBinding) { InitState init; init.extensions = "GL_ARB_texture_rectangle"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); DoBindTexture( @@ -1377,7 +1639,6 @@ TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleGetBinding) { TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTextureDefaults) { InitState init; init.extensions = "GL_ARB_texture_rectangle"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); DoBindTexture( @@ -1394,7 +1655,6 @@ TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTextureDefaults) { TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParam) { InitState init; init.extensions = "GL_ARB_texture_rectangle"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); @@ -1443,7 +1703,6 @@ TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParam) { TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParamInvalid) { InitState init; init.extensions = "GL_ARB_texture_rectangle"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); @@ -1476,7 +1735,6 @@ TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParamInvalid) { TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTexImage2DError) { InitState init; init.extensions = "GL_ARB_texture_rectangle"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); @@ -1627,12 +1885,11 @@ TEST_P(GLES2DecoderTest, TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) { TEST_P( GLES2DecoderManualInitTest, TexSubImage2DDoesNotClearAfterTexImage2DNULLThenDataWithTexImage2DIsFaster) { - CommandLine command_line(0, NULL); + base::CommandLine command_line(0, NULL); command_line.AppendSwitchASCII( switches::kGpuDriverBugWorkarounds, base::IntToString(gpu::TEXSUBIMAGE2D_FASTER_THAN_TEXIMAGE2D)); InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoderWithCommandLine(init, &command_line); DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); @@ -1803,12 +2060,37 @@ TEST_P(GLES2DecoderTest, CopyTexSubImage2DClearsUnclearedTexture) { CopyTexSubImage2D cmd; cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + + TextureManager* manager = group().texture_manager(); + TextureRef* texture_ref = manager->GetTexture(client_texture_id_); + ASSERT_TRUE(texture_ref != NULL); + Texture* texture = texture_ref->texture(); + EXPECT_TRUE(texture->SafeToRenderFrom()); +} + +TEST_P(GLES2DecoderTest, CopyTexSubImage2DClearsUnclearedBackBufferSizedTexture) { + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kBackBufferWidth, kBackBufferHeight, + 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); + + EXPECT_CALL(*gl_, CopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, + kBackBufferWidth, kBackBufferHeight)) + .Times(1) + .RetiresOnSaturation(); + CopyTexSubImage2D cmd; + cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kBackBufferWidth, kBackBufferHeight); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + + TextureManager* manager = group().texture_manager(); + TextureRef* texture_ref = manager->GetTexture(client_texture_id_); + ASSERT_TRUE(texture_ref != NULL); + Texture* texture = texture_ref->texture(); + EXPECT_TRUE(texture->SafeToRenderFrom()); } TEST_P(GLES2DecoderManualInitTest, CompressedImage2DMarksTextureAsCleared) { InitState init; init.extensions = "GL_EXT_texture_compression_s3tc"; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); @@ -1877,14 +2159,16 @@ TEST_P(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) { GLenum type; GLenum internal_format; - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); EXPECT_EQ(3, width); EXPECT_EQ(1, height); EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format)); EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format); EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height, nullptr)); EXPECT_EQ(2, width); EXPECT_EQ(4, height); EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format)); @@ -1914,14 +2198,16 @@ TEST_P(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); // Texture is redefined. - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); EXPECT_EQ(3, width); EXPECT_EQ(1, height); EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format)); EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format); EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height, nullptr)); EXPECT_EQ(2, width); EXPECT_EQ(4, height); EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format)); @@ -1959,14 +2245,16 @@ TEST_P(GLES2DecoderTest, ProduceAndConsumeDirectTextureCHROMIUM) { GLenum type; GLenum internal_format; - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); EXPECT_EQ(3, width); EXPECT_EQ(1, height); EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format)); EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format); EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height, nullptr)); EXPECT_EQ(2, width); EXPECT_EQ(4, height); EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format)); @@ -1994,14 +2282,16 @@ TEST_P(GLES2DecoderTest, ProduceAndConsumeDirectTextureCHROMIUM) { DoBindTexture(GL_TEXTURE_2D, kNewClientId, kServiceTextureId); // Texture is redefined. - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); EXPECT_EQ(3, width); EXPECT_EQ(1, height); EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format)); EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format); EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height, nullptr)); EXPECT_EQ(2, width); EXPECT_EQ(4, height); EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format)); @@ -2032,6 +2322,95 @@ TEST_P(GLES2DecoderTest, ProduceTextureCHROMIUMInvalidTarget) { EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } +TEST_P(GLES2DecoderTest, CreateAndConsumeTextureCHROMIUMInvalidMailbox) { + // Attempt to consume the mailbox when no texture has been produced with it. + Mailbox mailbox = Mailbox::Generate(); + GLuint new_texture_id = kNewClientId; + + EXPECT_CALL(*gl_, GenTextures(1, _)) + .WillOnce(SetArgumentPointee<1>(kNewServiceId)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, _)) + .Times(2) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)) + .Times(1) + .RetiresOnSaturation(); + + CreateAndConsumeTextureCHROMIUMImmediate& consume_cmd = + *GetImmediateAs<CreateAndConsumeTextureCHROMIUMImmediate>(); + consume_cmd.Init(GL_TEXTURE_2D, new_texture_id, mailbox.name); + EXPECT_EQ(error::kNoError, + ExecuteImmediateCmd(consume_cmd, sizeof(mailbox.name))); + + // CreateAndConsumeTexture should fail if the mailbox isn't associated with a + // texture. + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + + // Make sure the new client_id is associated with a texture ref even though + // CreateAndConsumeTexture failed. + TextureRef* texture_ref = + group().texture_manager()->GetTexture(new_texture_id); + ASSERT_TRUE(texture_ref != NULL); + Texture* texture = texture_ref->texture(); + // New texture should have the correct target type. + EXPECT_TRUE(texture->target() == GL_TEXTURE_2D); + // New texture should have a valid service_id. + EXPECT_EQ(kNewServiceId, texture->service_id()); +} + +TEST_P(GLES2DecoderTest, CreateAndConsumeTextureCHROMIUMInvalidTarget) { + Mailbox mailbox = Mailbox::Generate(); + + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + TextureRef* texture_ref = + group().texture_manager()->GetTexture(client_texture_id_); + ASSERT_TRUE(texture_ref != NULL); + + ProduceTextureDirectCHROMIUMImmediate& produce_cmd = + *GetImmediateAs<ProduceTextureDirectCHROMIUMImmediate>(); + produce_cmd.Init(client_texture_id_, GL_TEXTURE_2D, mailbox.name); + EXPECT_EQ(error::kNoError, + ExecuteImmediateCmd(produce_cmd, sizeof(mailbox.name))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, GenTextures(1, _)) + .WillOnce(SetArgumentPointee<1>(kNewServiceId)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, _)) + .Times(2) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)) + .Times(1) + .RetiresOnSaturation(); + + // Attempt to consume the mailbox with a different target. + GLuint new_texture_id = kNewClientId; + CreateAndConsumeTextureCHROMIUMImmediate& consume_cmd = + *GetImmediateAs<CreateAndConsumeTextureCHROMIUMImmediate>(); + consume_cmd.Init(GL_TEXTURE_CUBE_MAP, new_texture_id, mailbox.name); + EXPECT_EQ(error::kNoError, + ExecuteImmediateCmd(consume_cmd, sizeof(mailbox.name))); + + // CreateAndConsumeTexture should fail if the produced texture had a different + // target. + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + + // Make sure the new client_id is associated with a texture ref even though + // CreateAndConsumeTexture failed. + texture_ref = group().texture_manager()->GetTexture(new_texture_id); + ASSERT_TRUE(texture_ref != NULL); + Texture* texture = texture_ref->texture(); + // New texture should have the correct target type. + EXPECT_TRUE(texture->target() == GL_TEXTURE_CUBE_MAP); + // New texture should have a valid service_id. + EXPECT_EQ(kNewServiceId, texture->service_id()); + + // Make sure the client_id did not become associated with the produced texture + // service_id. + EXPECT_NE(kServiceTextureId, texture->service_id()); +} + TEST_P(GLES2DecoderManualInitTest, DepthTextureBadArgs) { InitState init; init.extensions = "GL_ANGLE_depth_texture"; @@ -2157,7 +2536,8 @@ TEST_P(GLES2DecoderTest, BindTexImage2DCHROMIUM) { GLenum type; GLenum internal_format; - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); EXPECT_EQ(3, width); EXPECT_EQ(1, height); EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format)); @@ -2167,21 +2547,17 @@ TEST_P(GLES2DecoderTest, BindTexImage2DCHROMIUM) { // Bind image to texture. // ScopedGLErrorSuppressor calls GetError on its constructor and destructor. - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - BindTexImage2DCHROMIUM bind_tex_image_2d_cmd; - bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1); - EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd)); - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + DoBindTexImage2DCHROMIUM(GL_TEXTURE_2D, 1); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); // Image should now be set. EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL); // Define new texture image. DoTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); // Image should no longer be set. EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL); } @@ -2200,20 +2576,113 @@ TEST_P(GLES2DecoderTest, BindTexImage2DCHROMIUMCubeMapNotAllowed) { TEST_P(GLES2DecoderTest, OrphanGLImageWithTexImage2D) { scoped_refptr<gfx::GLImage> image(new gfx::GLImageStub); GetImageManager()->AddImage(image.get(), 1); - DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId); + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); - BindTexImage2DCHROMIUM bind_tex_image_2d_cmd; - bind_tex_image_2d_cmd.Init(GL_TEXTURE_CUBE_MAP, 1); - EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); + DoBindTexImage2DCHROMIUM(GL_TEXTURE_2D, 1); + + TextureRef* texture_ref = + group().texture_manager()->GetTexture(client_texture_id_); + ASSERT_TRUE(texture_ref != NULL); + Texture* texture = texture_ref->texture(); + EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == image.get()); DoTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); + EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL); +} + +TEST_P(GLES2DecoderTest, GLImageAttachedAfterSubTexImage2D) { + // Specifically tests that TexSubImage2D is not optimized to TexImage2D + // in the presence of image attachments. + ASSERT_FALSE( + feature_info()->workarounds().texsubimage2d_faster_than_teximage2d); + + scoped_refptr<gfx::GLImage> image(new gfx::GLImageStub); + GetImageManager()->AddImage(image.get(), 1); + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + + GLenum target = GL_TEXTURE_2D; + GLint level = 0; + GLint xoffset = 0; + GLint yoffset = 0; + GLsizei width = 1; + GLsizei height = 1; + GLint border = 0; + GLenum format = GL_RGBA; + GLenum type = GL_UNSIGNED_BYTE; + uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_offset = kSharedMemoryOffset; + GLboolean internal = 0; + + // Define texture first. + DoTexImage2D(target, level, format, width, height, border, format, type, + pixels_shm_id, pixels_shm_offset); + + // Bind texture to GLImage. + DoBindTexImage2DCHROMIUM(GL_TEXTURE_2D, 1); + + // Check binding. TextureRef* texture_ref = group().texture_manager()->GetTexture(client_texture_id_); ASSERT_TRUE(texture_ref != NULL); Texture* texture = texture_ref->texture(); - EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL); + EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == image.get()); + + // TexSubImage2D should not unbind GLImage. + EXPECT_CALL(*gl_, TexSubImage2D(target, level, xoffset, yoffset, width, + height, format, type, _)) + .Times(1) + .RetiresOnSaturation(); + cmds::TexSubImage2D tex_sub_image_2d_cmd; + tex_sub_image_2d_cmd.Init(target, level, xoffset, yoffset, width, height, + format, type, pixels_shm_id, pixels_shm_offset, + internal); + EXPECT_EQ(error::kNoError, ExecuteCmd(tex_sub_image_2d_cmd)); + EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == image.get()); +} + +TEST_P(GLES2DecoderTest, GLImageAttachedAfterClearLevel) { + scoped_refptr<gfx::GLImage> image(new gfx::GLImageStub); + GetImageManager()->AddImage(image.get(), 1); + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + + GLenum target = GL_TEXTURE_2D; + GLint level = 0; + GLint xoffset = 0; + GLint yoffset = 0; + GLsizei width = 1; + GLsizei height = 1; + GLint border = 0; + GLenum format = GL_RGBA; + GLenum type = GL_UNSIGNED_BYTE; + uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_offset = kSharedMemoryOffset; + + // Define texture first. + DoTexImage2D(target, level, format, width, height, border, format, type, + pixels_shm_id, pixels_shm_offset); + + // Bind texture to GLImage. + DoBindTexImage2DCHROMIUM(GL_TEXTURE_2D, 1); + + // Check binding. + TextureRef* texture_ref = + group().texture_manager()->GetTexture(client_texture_id_); + ASSERT_TRUE(texture_ref != NULL); + Texture* texture = texture_ref->texture(); + EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == image.get()); + + // ClearLevel should use glTexSubImage2D to avoid unbinding GLImage. + EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId)) + .Times(2) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, TexSubImage2D(target, level, xoffset, yoffset, width, + height, format, type, _)) + .Times(1) + .RetiresOnSaturation(); + GetDecoder()->ClearLevel(texture, target, level, format, format, type, width, + height, false); + EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == image.get()); } TEST_P(GLES2DecoderTest, ReleaseTexImage2DCHROMIUM) { @@ -2235,7 +2704,8 @@ TEST_P(GLES2DecoderTest, ReleaseTexImage2DCHROMIUM) { GLenum type; GLenum internal_format; - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); EXPECT_EQ(3, width); EXPECT_EQ(1, height); EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format)); @@ -2245,14 +2715,9 @@ TEST_P(GLES2DecoderTest, ReleaseTexImage2DCHROMIUM) { // Bind image to texture. // ScopedGLErrorSuppressor calls GetError on its constructor and destructor. - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - BindTexImage2DCHROMIUM bind_tex_image_2d_cmd; - bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1); - EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd)); - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + DoBindTexImage2DCHROMIUM(GL_TEXTURE_2D, 1); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); // Image should now be set. EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL); @@ -2265,7 +2730,8 @@ TEST_P(GLES2DecoderTest, ReleaseTexImage2DCHROMIUM) { ReleaseTexImage2DCHROMIUM release_tex_image_2d_cmd; release_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1); EXPECT_EQ(error::kNoError, ExecuteCmd(release_tex_image_2d_cmd)); - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_TRUE( + texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr)); // Image should no longer be set. EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL); } @@ -2327,13 +2793,7 @@ TEST_P(GLES2DecoderWithShaderTest, UseTexImage) { .WillOnce(Return(gfx::Size(1, 1))) .RetiresOnSaturation(); // ScopedGLErrorSuppressor calls GetError on its constructor and destructor. - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - BindTexImage2DCHROMIUM bind_tex_image_2d_cmd; - bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, kImageId); - EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd)); + DoBindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId); AddExpectationsForSimulatedAttrib0(kNumVertices, 0); SetupExpectationsForApplyingDefaultDirtyState(); @@ -2637,7 +3097,6 @@ TEST_P(GLES2DecoderManualInitTest, TexSubImage2DFloatDoesClearOnGLES3) { TEST_P(GLES2DecoderManualInitTest, TexImage2DFloatConvertsFormatDesktop) { InitState init; init.extensions = "GL_ARB_texture_float"; - init.gl_version = "2.1"; InitDecoder(init); DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); DoTexImage2D( @@ -2716,7 +3175,6 @@ class GLES2DecoderCompressedFormatsTest : public GLES2DecoderManualInitTest { void CheckFormats(const char* extension, const GLenum* formats, int count) { InitState init; init.extensions = extension; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); @@ -2788,7 +3246,6 @@ TEST_P(GLES2DecoderCompressedFormatsTest, GetCompressedTextureFormatsETC1) { TEST_P(GLES2DecoderManualInitTest, GetNoCompressedTextureFormats) { InitState init; - init.gl_version = "3.0"; init.bind_generates_resource = true; InitDecoder(init); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_valuebuffer.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_valuebuffer.cc index 012d5041755..47e6a6b8a7a 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_valuebuffer.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_valuebuffer.cc @@ -8,7 +8,6 @@ #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" - #include "gpu/command_buffer/service/test_helper.h" #include "gpu/command_buffer/service/valuebuffer_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,7 +29,7 @@ TEST_P(GLES2DecoderWithShaderTest, ValuebufferBasic) { valuestate.int_value[0] = 111; valuestate.int_value[1] = 222; valuebuffer_manager()->CreateValuebuffer(kBufferId); - valuebuffer_manager()->UpdateValueState( + pending_valuebuffer_state()->UpdateState( GL_MOUSE_POSITION_CHROMIUM, valuestate); BindValuebufferCHROMIUM cmd1; cmd1.Init(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, kBufferId); @@ -54,7 +53,7 @@ TEST_P(GLES2DecoderWithShaderTest, SubscribeValuebufferNotBound) { valuestate.int_value[0] = 111; valuestate.int_value[1] = 222; valuebuffer_manager()->CreateValuebuffer(kBufferId); - valuebuffer_manager()->UpdateValueState( + pending_valuebuffer_state()->UpdateState( GL_MOUSE_POSITION_CHROMIUM, valuestate); SubscribeValueCHROMIUM cmd1; cmd1.Init(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, GL_MOUSE_POSITION_CHROMIUM); @@ -68,7 +67,7 @@ TEST_P(GLES2DecoderWithShaderTest, PopulateValuebufferNoSubscription) { valuestate.int_value[0] = 111; valuestate.int_value[1] = 222; valuebuffer_manager()->CreateValuebuffer(kBufferId); - valuebuffer_manager()->UpdateValueState( + pending_valuebuffer_state()->UpdateState( GL_MOUSE_POSITION_CHROMIUM, valuestate); BindValuebufferCHROMIUM cmd1; cmd1.Init(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, kBufferId); @@ -85,7 +84,7 @@ TEST_P(GLES2DecoderWithShaderTest, UniformValuebufferNoState) { valuestate.int_value[0] = 111; valuestate.int_value[1] = 222; valuebuffer_manager()->CreateValuebuffer(kBufferId); - valuebuffer_manager()->UpdateValueState( + pending_valuebuffer_state()->UpdateState( GL_MOUSE_POSITION_CHROMIUM, valuestate); BindValuebufferCHROMIUM cmd1; cmd1.Init(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, kBufferId); @@ -107,7 +106,7 @@ TEST_P(GLES2DecoderWithShaderTest, UniformValuebufferInvalidLocation) { valuestate.int_value[0] = 111; valuestate.int_value[1] = 222; valuebuffer_manager()->CreateValuebuffer(kBufferId); - valuebuffer_manager()->UpdateValueState( + pending_valuebuffer_state()->UpdateState( GL_MOUSE_POSITION_CHROMIUM, valuestate); BindValuebufferCHROMIUM cmd1; cmd1.Init(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, kBufferId); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_validation.h b/chromium/gpu/command_buffer/service/gles2_cmd_validation.h index 22ee2da0d0d..f4059edb1b4 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_validation.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_validation.h @@ -22,9 +22,7 @@ class ValueValidator { ValueValidator() {} ValueValidator(const T* valid_values, int num_values) { - for (int ii = 0; ii < num_values; ++ii) { - AddValue(valid_values[ii]); - } + AddValues(valid_values, num_values); } void AddValue(const T value) { @@ -33,6 +31,23 @@ class ValueValidator { } } + void AddValues(const T* valid_values, int num_values) { + for (int ii = 0; ii < num_values; ++ii) { + AddValue(valid_values[ii]); + } + } + + void RemoveValues(const T* invalid_values, int num_values) { + for (int ii = 0; ii < num_values; ++ii) { + auto iter = std::find( + valid_values_.begin(), valid_values_.end(), invalid_values[ii]); + if (iter != valid_values_.end()) { + valid_values_.erase(iter); + DCHECK(!IsValid(invalid_values[ii])); + } + } + } + bool IsValid(const T value) const { return std::find(valid_values_.begin(), valid_values_.end(), value) != valid_values_.end(); @@ -48,6 +63,9 @@ class ValueValidator { struct Validators { Validators(); + + void UpdateValuesES3(); + #include "gpu/command_buffer/service/gles2_cmd_validation_autogen.h" }; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index c72bcf81835..ec96c6b70a7 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_validation_autogen.h @@ -14,9 +14,14 @@ ValueValidator<GLenum> attachment; ValueValidator<GLenum> backbuffer_attachment; ValueValidator<GLenum> blit_filter; +ValueValidator<GLenum> buffer_mode; ValueValidator<GLenum> buffer_parameter; ValueValidator<GLenum> buffer_target; ValueValidator<GLenum> buffer_usage; +ValueValidator<GLenum> bufferfi; +ValueValidator<GLenum> bufferfv; +ValueValidator<GLenum> bufferiv; +ValueValidator<GLenum> bufferuiv; ValueValidator<GLenum> capability; ValueValidator<GLenum> cmp_function; ValueValidator<GLenum> compressed_texture_format; @@ -35,6 +40,11 @@ ValueValidator<GLenum> hint_target; ValueValidator<GLenum> image_internal_format; ValueValidator<GLenum> image_usage; ValueValidator<GLenum> index_type; +ValueValidator<GLenum> indexed_buffer_target; +ValueValidator<GLenum> indexed_g_l_state; +ValueValidator<GLenum> internal_format_parameter; +ValueValidator<GLenum> invalidate_frame_buffer_target; +ValueValidator<GLenum> map_buffer_access; ValueValidator<GLenum> matrix_mode; ValueValidator<GLenum> pixel_store; ValueValidator<GLint> pixel_store_alignment; @@ -49,6 +59,7 @@ ValueValidator<GLenum> render_buffer_format; ValueValidator<GLenum> render_buffer_parameter; ValueValidator<GLenum> render_buffer_target; ValueValidator<GLenum> reset_status; +ValueValidator<GLenum> sampler_parameter; ValueValidator<GLenum> shader_binary_format; ValueValidator<GLenum> shader_parameter; ValueValidator<GLenum> shader_precision; @@ -57,7 +68,12 @@ ValueValidator<GLenum> src_blend_factor; ValueValidator<GLenum> stencil_op; ValueValidator<GLenum> string_type; ValueValidator<GLenum> subscription_target; +ValueValidator<GLbitfield> sync_flush_flags; +ValueValidator<GLenum> sync_parameter; +ValueValidator<GLenum> texture_3_d_target; ValueValidator<GLenum> texture_bind_target; +ValueValidator<GLenum> texture_compare_func; +ValueValidator<GLenum> texture_compare_mode; ValueValidator<GLenum> texture_format; ValueValidator<GLenum> texture_internal_format; ValueValidator<GLenum> texture_internal_format_storage; @@ -68,7 +84,12 @@ ValueValidator<GLenum> texture_pool; ValueValidator<GLenum> texture_target; ValueValidator<GLenum> texture_usage; ValueValidator<GLenum> texture_wrap_mode; +ValueValidator<GLenum> transform_feedback_bind_target; +ValueValidator<GLenum> transform_feedback_primitive_mode; +ValueValidator<GLenum> uniform_block_parameter; +ValueValidator<GLenum> uniform_parameter; ValueValidator<GLenum> value_buffer_target; +ValueValidator<GLenum> vertex_attrib_i_type; ValueValidator<GLint> vertex_attrib_size; ValueValidator<GLenum> vertex_attrib_type; ValueValidator<GLenum> vertex_attribute; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 6a646ac5067..69cf3c4c7f1 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -17,6 +17,10 @@ static const GLenum valid_attachment_table[] = { GL_STENCIL_ATTACHMENT, }; +static const GLenum valid_attachment_table_es3[] = { + GL_DEPTH_STENCIL_ATTACHMENT, +}; + static const GLenum valid_backbuffer_attachment_table[] = { GL_COLOR_EXT, GL_DEPTH_EXT, @@ -28,22 +32,70 @@ static const GLenum valid_blit_filter_table[] = { GL_LINEAR, }; +static const GLenum valid_buffer_mode_table[] = { + GL_INTERLEAVED_ATTRIBS, + GL_SEPARATE_ATTRIBS, +}; + static const GLenum valid_buffer_parameter_table[] = { GL_BUFFER_SIZE, GL_BUFFER_USAGE, }; +static const GLenum valid_buffer_parameter_table_es3[] = { + GL_BUFFER_ACCESS_FLAGS, + GL_BUFFER_MAPPED, + GL_BUFFER_MAP_LENGTH, + GL_BUFFER_MAP_OFFSET, +}; + static const GLenum valid_buffer_target_table[] = { GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, }; +static const GLenum valid_buffer_target_table_es3[] = { + GL_COPY_READ_BUFFER, + GL_COPY_WRITE_BUFFER, + GL_PIXEL_PACK_BUFFER, + GL_PIXEL_UNPACK_BUFFER, + GL_TRANSFORM_FEEDBACK_BUFFER, + GL_UNIFORM_BUFFER, +}; + static const GLenum valid_buffer_usage_table[] = { GL_STREAM_DRAW, GL_STATIC_DRAW, GL_DYNAMIC_DRAW, }; +static const GLenum valid_buffer_usage_table_es3[] = { + GL_STREAM_READ, + GL_STREAM_COPY, + GL_STATIC_READ, + GL_STATIC_COPY, + GL_DYNAMIC_READ, + GL_DYNAMIC_COPY, +}; + +static const GLenum valid_bufferfi_table[] = { + GL_DEPTH_STENCIL, +}; + +static const GLenum valid_bufferfv_table[] = { + GL_COLOR, + GL_DEPTH, +}; + +static const GLenum valid_bufferiv_table[] = { + GL_COLOR, + GL_STENCIL, +}; + +static const GLenum valid_bufferuiv_table[] = { + GL_COLOR, +}; + static const GLenum valid_capability_table[] = { GL_BLEND, GL_CULL_FACE, @@ -56,6 +108,11 @@ static const GLenum valid_capability_table[] = { GL_STENCIL_TEST, }; +static const GLenum valid_capability_table_es3[] = { + GL_RASTERIZER_DISCARD, + GL_PRIMITIVE_RESTART_FIXED_INDEX, +}; + static const GLenum valid_cmp_function_table[] = { GL_NEVER, GL_LESS, @@ -67,6 +124,19 @@ static const GLenum valid_cmp_function_table[] = { GL_ALWAYS, }; +static const GLenum valid_compressed_texture_format_table_es3[] = { + GL_COMPRESSED_R11_EAC, + GL_COMPRESSED_SIGNED_R11_EAC, + GL_COMPRESSED_RG11_EAC, + GL_COMPRESSED_SIGNED_RG11_EAC, + GL_COMPRESSED_RGB8_ETC2, + GL_COMPRESSED_SRGB8_ETC2, + GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + GL_COMPRESSED_RGBA8_ETC2_EAC, + GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, +}; + static const GLenum valid_draw_mode_table[] = { GL_POINTS, GL_LINE_STRIP, @@ -100,6 +170,11 @@ static const GLenum valid_equation_table[] = { GL_FUNC_REVERSE_SUBTRACT, }; +static const GLenum valid_equation_table_es3[] = { + GL_MIN, + GL_MAX, +}; + static const GLenum valid_face_mode_table[] = { GL_CW, GL_CCW, @@ -118,10 +193,27 @@ static const GLenum valid_frame_buffer_parameter_table[] = { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, }; +static const GLenum valid_frame_buffer_parameter_table_es3[] = { + GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, + GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, + GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, + GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, + GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, + GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, +}; + static const GLenum valid_frame_buffer_target_table[] = { GL_FRAMEBUFFER, }; +static const GLenum valid_frame_buffer_target_table_es3[] = { + GL_DRAW_FRAMEBUFFER, + GL_READ_FRAMEBUFFER, +}; + static const GLenum valid_g_l_state_table[] = { GL_ACTIVE_TEXTURE, GL_ALIASED_LINE_WIDTH_RANGE, @@ -214,6 +306,88 @@ static const GLenum valid_g_l_state_table[] = { GL_SAMPLE_COVERAGE, GL_SCISSOR_TEST, GL_STENCIL_TEST, + GL_RASTERIZER_DISCARD, + GL_PRIMITIVE_RESTART_FIXED_INDEX, +}; + +static const GLenum valid_g_l_state_table_es3[] = { + GL_COPY_READ_BUFFER_BINDING, + GL_COPY_WRITE_BUFFER_BINDING, + GL_DRAW_BUFFER0, + GL_DRAW_BUFFER1, + GL_DRAW_BUFFER2, + GL_DRAW_BUFFER3, + GL_DRAW_BUFFER4, + GL_DRAW_BUFFER5, + GL_DRAW_BUFFER6, + GL_DRAW_BUFFER7, + GL_DRAW_BUFFER8, + GL_DRAW_BUFFER9, + GL_DRAW_BUFFER10, + GL_DRAW_BUFFER11, + GL_DRAW_BUFFER12, + GL_DRAW_BUFFER13, + GL_DRAW_BUFFER14, + GL_DRAW_BUFFER15, + GL_DRAW_FRAMEBUFFER_BINDING, + GL_FRAGMENT_SHADER_DERIVATIVE_HINT, + GL_MAJOR_VERSION, + GL_MAX_3D_TEXTURE_SIZE, + GL_MAX_ARRAY_TEXTURE_LAYERS, + GL_MAX_COLOR_ATTACHMENTS, + GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, + GL_MAX_COMBINED_UNIFORM_BLOCKS, + GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, + GL_MAX_DRAW_BUFFERS, + GL_MAX_ELEMENT_INDEX, + GL_MAX_ELEMENTS_INDICES, + GL_MAX_ELEMENTS_VERTICES, + GL_MAX_FRAGMENT_INPUT_COMPONENTS, + GL_MAX_FRAGMENT_UNIFORM_BLOCKS, + GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, + GL_MAX_PROGRAM_TEXEL_OFFSET, + GL_MAX_SAMPLES, + GL_MAX_SERVER_WAIT_TIMEOUT, + GL_MAX_TEXTURE_LOD_BIAS, + GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, + GL_MAX_UNIFORM_BLOCK_SIZE, + GL_MAX_UNIFORM_BUFFER_BINDINGS, + GL_MAX_VARYING_COMPONENTS, + GL_MAX_VERTEX_OUTPUT_COMPONENTS, + GL_MAX_VERTEX_UNIFORM_BLOCKS, + GL_MAX_VERTEX_UNIFORM_COMPONENTS, + GL_MIN_PROGRAM_TEXEL_OFFSET, + GL_MINOR_VERSION, + GL_NUM_EXTENSIONS, + GL_NUM_PROGRAM_BINARY_FORMATS, + GL_PACK_ROW_LENGTH, + GL_PACK_SKIP_PIXELS, + GL_PACK_SKIP_ROWS, + GL_PIXEL_PACK_BUFFER_BINDING, + GL_PIXEL_UNPACK_BUFFER_BINDING, + GL_PROGRAM_BINARY_FORMATS, + GL_READ_BUFFER, + GL_READ_FRAMEBUFFER_BINDING, + GL_SAMPLER_BINDING, + GL_TEXTURE_BINDING_2D_ARRAY, + GL_TEXTURE_BINDING_3D, + GL_TRANSFORM_FEEDBACK_BINDING, + GL_TRANSFORM_FEEDBACK_ACTIVE, + GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, + GL_TRANSFORM_FEEDBACK_PAUSED, + GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, + GL_TRANSFORM_FEEDBACK_BUFFER_START, + GL_UNIFORM_BUFFER_BINDING, + GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, + GL_UNIFORM_BUFFER_SIZE, + GL_UNIFORM_BUFFER_START, + GL_UNPACK_IMAGE_HEIGHT, + GL_UNPACK_ROW_LENGTH, + GL_UNPACK_SKIP_IMAGES, + GL_UNPACK_SKIP_PIXELS, + GL_UNPACK_SKIP_ROWS, }; static const GLenum valid_get_max_index_type_table[] = { @@ -227,6 +401,11 @@ static const GLenum valid_get_tex_param_target_table[] = { GL_TEXTURE_CUBE_MAP, }; +static const GLenum valid_get_tex_param_target_table_es3[] = { + GL_TEXTURE_2D_ARRAY, + GL_TEXTURE_3D, +}; + static const GLenum valid_hint_mode_table[] = { GL_FASTEST, GL_NICEST, @@ -237,8 +416,13 @@ static const GLenum valid_hint_target_table[] = { GL_GENERATE_MIPMAP_HINT, }; +static const GLenum valid_hint_target_table_es3[] = { + GL_FRAGMENT_SHADER_DERIVATIVE_HINT, +}; + static const GLenum valid_image_internal_format_table[] = { GL_RGB, + GL_RGB_YUV_420_CHROMIUM, GL_RGBA, }; @@ -252,6 +436,42 @@ static const GLenum valid_index_type_table[] = { GL_UNSIGNED_SHORT, }; +static const GLenum valid_index_type_table_es3[] = { + GL_UNSIGNED_INT, +}; + +static const GLenum valid_indexed_buffer_target_table[] = { + GL_TRANSFORM_FEEDBACK_BUFFER, + GL_UNIFORM_BUFFER, +}; + +static const GLenum valid_indexed_g_l_state_table[] = { + GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, + GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, + GL_TRANSFORM_FEEDBACK_BUFFER_START, + GL_UNIFORM_BUFFER_BINDING, + GL_UNIFORM_BUFFER_SIZE, + GL_UNIFORM_BUFFER_START, +}; + +static const GLenum valid_internal_format_parameter_table[] = { + GL_NUM_SAMPLE_COUNTS, + GL_SAMPLES, +}; + +static const GLenum valid_invalidate_frame_buffer_target_table[] = { + GL_FRAMEBUFFER, +}; + +static const GLenum valid_map_buffer_access_table[] = { + GL_MAP_READ_BIT, + GL_MAP_WRITE_BIT, + GL_MAP_INVALIDATE_RANGE_BIT, + GL_MAP_INVALIDATE_BUFFER_BIT, + GL_MAP_FLUSH_EXPLICIT_BIT, + GL_MAP_UNSYNCHRONIZED_BIT, +}; + static const GLenum valid_matrix_mode_table[] = { GL_PATH_PROJECTION_CHROMIUM, GL_PATH_MODELVIEW_CHROMIUM, @@ -265,6 +485,17 @@ static const GLenum valid_pixel_store_table[] = { GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, }; +static const GLenum valid_pixel_store_table_es3[] = { + GL_PACK_ROW_LENGTH, + GL_PACK_SKIP_PIXELS, + GL_PACK_SKIP_ROWS, + GL_UNPACK_ROW_LENGTH, + GL_UNPACK_IMAGE_HEIGHT, + GL_UNPACK_SKIP_PIXELS, + GL_UNPACK_SKIP_ROWS, + GL_UNPACK_SKIP_IMAGES, +}; + static const GLint valid_pixel_store_alignment_table[] = { 1, 2, @@ -279,6 +510,21 @@ static const GLenum valid_pixel_type_table[] = { GL_UNSIGNED_SHORT_5_5_5_1, }; +static const GLenum valid_pixel_type_table_es3[] = { + GL_BYTE, + GL_UNSIGNED_SHORT, + GL_SHORT, + GL_UNSIGNED_INT, + GL_INT, + GL_HALF_FLOAT, + GL_FLOAT, + GL_UNSIGNED_INT_2_10_10_10_REV, + GL_UNSIGNED_INT_10F_11F_11F_REV, + GL_UNSIGNED_INT_5_9_9_9_REV, + GL_UNSIGNED_INT_24_8, + GL_FLOAT_32_UNSIGNED_INT_24_8_REV, +}; + static const GLenum valid_program_parameter_table[] = { GL_DELETE_STATUS, GL_LINK_STATUS, @@ -291,6 +537,14 @@ static const GLenum valid_program_parameter_table[] = { GL_ACTIVE_UNIFORM_MAX_LENGTH, }; +static const GLenum valid_program_parameter_table_es3[] = { + GL_ACTIVE_UNIFORM_BLOCKS, + GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, + GL_TRANSFORM_FEEDBACK_BUFFER_MODE, + GL_TRANSFORM_FEEDBACK_VARYINGS, + GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, +}; + static const GLenum valid_query_object_parameter_table[] = { GL_QUERY_RESULT_EXT, GL_QUERY_RESULT_AVAILABLE_EXT, @@ -316,6 +570,15 @@ static const GLenum valid_read_pixel_format_table[] = { GL_RGBA, }; +static const GLenum valid_read_pixel_format_table_es3[] = { + GL_RGBA_INTEGER, +}; + +static const GLenum deprecated_read_pixel_format_table_es3[] = { + GL_ALPHA, + GL_RGB, +}; + static const GLenum valid_read_pixel_type_table[] = { GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, @@ -323,6 +586,18 @@ static const GLenum valid_read_pixel_type_table[] = { GL_UNSIGNED_SHORT_5_5_5_1, }; +static const GLenum valid_read_pixel_type_table_es3[] = { + GL_UNSIGNED_INT, + GL_INT, + GL_FLOAT, +}; + +static const GLenum deprecated_read_pixel_type_table_es3[] = { + GL_UNSIGNED_SHORT_5_6_5, + GL_UNSIGNED_SHORT_4_4_4_4, + GL_UNSIGNED_SHORT_5_5_5_1, +}; + static const GLenum valid_render_buffer_format_table[] = { GL_RGBA4, GL_RGB565, @@ -331,6 +606,38 @@ static const GLenum valid_render_buffer_format_table[] = { GL_STENCIL_INDEX8, }; +static const GLenum valid_render_buffer_format_table_es3[] = { + GL_R8, + GL_R8UI, + GL_R8I, + GL_R16UI, + GL_R16I, + GL_R32UI, + GL_R32I, + GL_RG8, + GL_RG8UI, + GL_RG8I, + GL_RG16UI, + GL_RG16I, + GL_RG32UI, + GL_RG32I, + GL_RGB8, + GL_RGBA8, + GL_SRGB8_ALPHA8, + GL_RGB10_A2, + GL_RGBA8UI, + GL_RGBA8I, + GL_RGB10_A2UI, + GL_RGBA16UI, + GL_RGBA16I, + GL_RGBA32UI, + GL_RGBA32I, + GL_DEPTH_COMPONENT24, + GL_DEPTH_COMPONENT32F, + GL_DEPTH24_STENCIL8, + GL_DEPTH32F_STENCIL8, +}; + static const GLenum valid_render_buffer_parameter_table[] = { GL_RENDERBUFFER_RED_SIZE, GL_RENDERBUFFER_GREEN_SIZE, @@ -343,6 +650,10 @@ static const GLenum valid_render_buffer_parameter_table[] = { GL_RENDERBUFFER_INTERNAL_FORMAT, }; +static const GLenum valid_render_buffer_parameter_table_es3[] = { + GL_RENDERBUFFER_SAMPLES, +}; + static const GLenum valid_render_buffer_target_table[] = { GL_RENDERBUFFER, }; @@ -353,6 +664,18 @@ static const GLenum valid_reset_status_table[] = { GL_UNKNOWN_CONTEXT_RESET_ARB, }; +static const GLenum valid_sampler_parameter_table[] = { + GL_TEXTURE_MAG_FILTER, + GL_TEXTURE_MIN_FILTER, + GL_TEXTURE_MIN_LOD, + GL_TEXTURE_MAX_LOD, + GL_TEXTURE_WRAP_S, + GL_TEXTURE_WRAP_T, + GL_TEXTURE_WRAP_R, + GL_TEXTURE_COMPARE_MODE, + GL_TEXTURE_COMPARE_FUNC, +}; + static const GLenum valid_shader_parameter_table[] = { GL_SHADER_TYPE, GL_DELETE_STATUS, @@ -417,11 +740,49 @@ static const GLenum valid_subscription_target_table[] = { GL_MOUSE_POSITION_CHROMIUM, }; +static const GLbitfield valid_sync_flush_flags_table[] = { + GL_SYNC_FLUSH_COMMANDS_BIT, + 0, +}; + +static const GLenum valid_sync_parameter_table[] = { + GL_SYNC_STATUS, + GL_OBJECT_TYPE, + GL_SYNC_CONDITION, + GL_SYNC_FLAGS, +}; + +static const GLenum valid_texture_3_d_target_table[] = { + GL_TEXTURE_3D, + GL_TEXTURE_2D_ARRAY, +}; + static const GLenum valid_texture_bind_target_table[] = { GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, }; +static const GLenum valid_texture_bind_target_table_es3[] = { + GL_TEXTURE_3D, + GL_TEXTURE_2D_ARRAY, +}; + +static const GLenum valid_texture_compare_func_table[] = { + GL_LEQUAL, + GL_GEQUAL, + GL_LESS, + GL_GREATER, + GL_EQUAL, + GL_NOTEQUAL, + GL_ALWAYS, + GL_NEVER, +}; + +static const GLenum valid_texture_compare_mode_table[] = { + GL_NONE, + GL_COMPARE_REF_TO_TEXTURE, +}; + static const GLenum valid_texture_format_table[] = { GL_ALPHA, GL_LUMINANCE, @@ -430,6 +791,17 @@ static const GLenum valid_texture_format_table[] = { GL_RGBA, }; +static const GLenum valid_texture_format_table_es3[] = { + GL_RED, + GL_RED_INTEGER, + GL_RG, + GL_RG_INTEGER, + GL_RGB_INTEGER, + GL_RGBA_INTEGER, + GL_DEPTH_COMPONENT, + GL_DEPTH_STENCIL, +}; + static const GLenum valid_texture_internal_format_table[] = { GL_ALPHA, GL_LUMINANCE, @@ -438,6 +810,63 @@ static const GLenum valid_texture_internal_format_table[] = { GL_RGBA, }; +static const GLenum valid_texture_internal_format_table_es3[] = { + GL_R8, + GL_R8_SNORM, + GL_R16F, + GL_R32F, + GL_R8UI, + GL_R8I, + GL_R16UI, + GL_R16I, + GL_R32UI, + GL_R32I, + GL_RG8, + GL_RG8_SNORM, + GL_RG16F, + GL_RG32F, + GL_RG8UI, + GL_RG8I, + GL_RG16UI, + GL_RG16I, + GL_RG32UI, + GL_RG32I, + GL_RGB8, + GL_SRGB8, + GL_RGB565, + GL_RGB8_SNORM, + GL_R11F_G11F_B10F, + GL_RGB9_E5, + GL_RGB16F, + GL_RGB32F, + GL_RGB8UI, + GL_RGB8I, + GL_RGB16UI, + GL_RGB16I, + GL_RGB32UI, + GL_RGB32I, + GL_RGBA8, + GL_SRGB8_ALPHA8, + GL_RGBA8_SNORM, + GL_RGB5_A1, + GL_RGBA4, + GL_RGB10_A2, + GL_RGBA16F, + GL_RGBA32F, + GL_RGBA8UI, + GL_RGBA8I, + GL_RGB10_A2UI, + GL_RGBA16UI, + GL_RGBA16I, + GL_RGBA32UI, + GL_RGBA32I, + GL_DEPTH_COMPONENT16, + GL_DEPTH_COMPONENT24, + GL_DEPTH_COMPONENT32F, + GL_DEPTH24_STENCIL8, + GL_DEPTH32F_STENCIL8, +}; + static const GLenum valid_texture_internal_format_storage_table[] = { GL_RGB565, GL_RGBA4, @@ -449,6 +878,80 @@ static const GLenum valid_texture_internal_format_storage_table[] = { GL_RGBA8_OES, }; +static const GLenum valid_texture_internal_format_storage_table_es3[] = { + GL_R8, + GL_R8_SNORM, + GL_R16F, + GL_R32F, + GL_R8UI, + GL_R8I, + GL_R16UI, + GL_R16I, + GL_R32UI, + GL_R32I, + GL_RG8, + GL_RG8_SNORM, + GL_RG16F, + GL_RG32F, + GL_RG8UI, + GL_RG8I, + GL_RG16UI, + GL_RG16I, + GL_RG32UI, + GL_RG32I, + GL_SRGB8, + GL_RGB8_SNORM, + GL_R11F_G11F_B10F, + GL_RGB9_E5, + GL_RGB16F, + GL_RGB32F, + GL_RGB8UI, + GL_RGB8I, + GL_RGB16UI, + GL_RGB16I, + GL_RGB32UI, + GL_RGB32I, + GL_SRGB8_ALPHA8, + GL_RGBA8_SNORM, + GL_RGB10_A2, + GL_RGBA16F, + GL_RGBA32F, + GL_RGBA8UI, + GL_RGBA8I, + GL_RGB10_A2UI, + GL_RGBA16UI, + GL_RGBA16I, + GL_RGBA32UI, + GL_RGBA32I, + GL_DEPTH_COMPONENT16, + GL_DEPTH_COMPONENT24, + GL_DEPTH_COMPONENT32F, + GL_DEPTH24_STENCIL8, + GL_DEPTH32F_STENCIL8, + GL_COMPRESSED_R11_EAC, + GL_COMPRESSED_SIGNED_R11_EAC, + GL_COMPRESSED_RG11_EAC, + GL_COMPRESSED_SIGNED_RG11_EAC, + GL_COMPRESSED_RGB8_ETC2, + GL_COMPRESSED_SRGB8_ETC2, + GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + GL_COMPRESSED_RGBA8_ETC2_EAC, + GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, +}; + +static const GLenum deprecated_texture_internal_format_storage_table_es3[] = { + GL_ALPHA8_EXT, + GL_LUMINANCE8_EXT, + GL_LUMINANCE8_ALPHA8_EXT, + GL_ALPHA16F_EXT, + GL_LUMINANCE16F_EXT, + GL_LUMINANCE_ALPHA16F_EXT, + GL_ALPHA32F_EXT, + GL_LUMINANCE32F_EXT, + GL_LUMINANCE_ALPHA32F_EXT, +}; + static const GLenum valid_texture_mag_filter_mode_table[] = { GL_NEAREST, GL_LINEAR, @@ -471,6 +974,18 @@ static const GLenum valid_texture_parameter_table[] = { GL_TEXTURE_WRAP_T, }; +static const GLenum valid_texture_parameter_table_es3[] = { + GL_TEXTURE_BASE_LEVEL, + GL_TEXTURE_COMPARE_FUNC, + GL_TEXTURE_COMPARE_MODE, + GL_TEXTURE_IMMUTABLE_FORMAT, + GL_TEXTURE_IMMUTABLE_LEVELS, + GL_TEXTURE_MAX_LEVEL, + GL_TEXTURE_MAX_LOD, + GL_TEXTURE_MIN_LOD, + GL_TEXTURE_WRAP_R, +}; + static const GLenum valid_texture_pool_table[] = { GL_TEXTURE_POOL_MANAGED_CHROMIUM, GL_TEXTURE_POOL_UNMANAGED_CHROMIUM, @@ -497,10 +1012,50 @@ static const GLenum valid_texture_wrap_mode_table[] = { GL_REPEAT, }; +static const GLenum valid_transform_feedback_bind_target_table[] = { + GL_TRANSFORM_FEEDBACK, +}; + +static const GLenum valid_transform_feedback_primitive_mode_table[] = { + GL_POINTS, + GL_LINES, + GL_TRIANGLES, +}; + +static const GLenum valid_uniform_block_parameter_table[] = { + GL_UNIFORM_BLOCK_BINDING, + GL_UNIFORM_BLOCK_DATA_SIZE, + GL_UNIFORM_BLOCK_NAME_LENGTH, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, + GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, +}; + +static const GLenum valid_uniform_parameter_table[] = { + GL_UNIFORM_SIZE, + GL_UNIFORM_TYPE, + GL_UNIFORM_NAME_LENGTH, + GL_UNIFORM_BLOCK_INDEX, + GL_UNIFORM_OFFSET, + GL_UNIFORM_ARRAY_STRIDE, + GL_UNIFORM_MATRIX_STRIDE, + GL_UNIFORM_IS_ROW_MAJOR, +}; + static const GLenum valid_value_buffer_target_table[] = { GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, }; +static const GLenum valid_vertex_attrib_i_type_table[] = { + GL_BYTE, + GL_UNSIGNED_BYTE, + GL_SHORT, + GL_UNSIGNED_SHORT, + GL_INT, + GL_UNSIGNED_INT, +}; + static const GLint valid_vertex_attrib_size_table[] = { 1, 2, @@ -516,6 +1071,14 @@ static const GLenum valid_vertex_attrib_type_table[] = { GL_FLOAT, }; +static const GLenum valid_vertex_attrib_type_table_es3[] = { + GL_INT, + GL_UNSIGNED_INT, + GL_HALF_FLOAT, + GL_INT_2_10_10_10_REV, + GL_UNSIGNED_INT_2_10_10_10_REV, +}; + static const GLenum valid_vertex_attribute_table[] = { GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, @@ -526,6 +1089,11 @@ static const GLenum valid_vertex_attribute_table[] = { GL_CURRENT_VERTEX_ATTRIB, }; +static const GLenum valid_vertex_attribute_table_es3[] = { + GL_VERTEX_ATTRIB_ARRAY_INTEGER, + GL_VERTEX_ATTRIB_ARRAY_DIVISOR, +}; + static const GLenum valid_vertex_pointer_table[] = { GL_VERTEX_ATTRIB_ARRAY_POINTER, }; @@ -535,12 +1103,17 @@ Validators::Validators() backbuffer_attachment(valid_backbuffer_attachment_table, arraysize(valid_backbuffer_attachment_table)), blit_filter(valid_blit_filter_table, arraysize(valid_blit_filter_table)), + buffer_mode(valid_buffer_mode_table, arraysize(valid_buffer_mode_table)), buffer_parameter(valid_buffer_parameter_table, arraysize(valid_buffer_parameter_table)), buffer_target(valid_buffer_target_table, arraysize(valid_buffer_target_table)), buffer_usage(valid_buffer_usage_table, arraysize(valid_buffer_usage_table)), + bufferfi(valid_bufferfi_table, arraysize(valid_bufferfi_table)), + bufferfv(valid_bufferfv_table, arraysize(valid_bufferfv_table)), + bufferiv(valid_bufferiv_table, arraysize(valid_bufferiv_table)), + bufferuiv(valid_bufferuiv_table, arraysize(valid_bufferuiv_table)), capability(valid_capability_table, arraysize(valid_capability_table)), cmp_function(valid_cmp_function_table, arraysize(valid_cmp_function_table)), @@ -566,6 +1139,18 @@ Validators::Validators() arraysize(valid_image_internal_format_table)), image_usage(valid_image_usage_table, arraysize(valid_image_usage_table)), index_type(valid_index_type_table, arraysize(valid_index_type_table)), + indexed_buffer_target(valid_indexed_buffer_target_table, + arraysize(valid_indexed_buffer_target_table)), + indexed_g_l_state(valid_indexed_g_l_state_table, + arraysize(valid_indexed_g_l_state_table)), + internal_format_parameter( + valid_internal_format_parameter_table, + arraysize(valid_internal_format_parameter_table)), + invalidate_frame_buffer_target( + valid_invalidate_frame_buffer_target_table, + arraysize(valid_invalidate_frame_buffer_target_table)), + map_buffer_access(valid_map_buffer_access_table, + arraysize(valid_map_buffer_access_table)), matrix_mode(valid_matrix_mode_table, arraysize(valid_matrix_mode_table)), pixel_store(valid_pixel_store_table, arraysize(valid_pixel_store_table)), pixel_store_alignment(valid_pixel_store_alignment_table, @@ -591,6 +1176,8 @@ Validators::Validators() arraysize(valid_render_buffer_target_table)), reset_status(valid_reset_status_table, arraysize(valid_reset_status_table)), + sampler_parameter(valid_sampler_parameter_table, + arraysize(valid_sampler_parameter_table)), shader_binary_format(), shader_parameter(valid_shader_parameter_table, arraysize(valid_shader_parameter_table)), @@ -603,8 +1190,18 @@ Validators::Validators() string_type(valid_string_type_table, arraysize(valid_string_type_table)), subscription_target(valid_subscription_target_table, arraysize(valid_subscription_target_table)), + sync_flush_flags(valid_sync_flush_flags_table, + arraysize(valid_sync_flush_flags_table)), + sync_parameter(valid_sync_parameter_table, + arraysize(valid_sync_parameter_table)), + texture_3_d_target(valid_texture_3_d_target_table, + arraysize(valid_texture_3_d_target_table)), texture_bind_target(valid_texture_bind_target_table, arraysize(valid_texture_bind_target_table)), + texture_compare_func(valid_texture_compare_func_table, + arraysize(valid_texture_compare_func_table)), + texture_compare_mode(valid_texture_compare_mode_table, + arraysize(valid_texture_compare_mode_table)), texture_format(valid_texture_format_table, arraysize(valid_texture_format_table)), texture_internal_format(valid_texture_internal_format_table, @@ -626,8 +1223,20 @@ Validators::Validators() arraysize(valid_texture_usage_table)), texture_wrap_mode(valid_texture_wrap_mode_table, arraysize(valid_texture_wrap_mode_table)), + transform_feedback_bind_target( + valid_transform_feedback_bind_target_table, + arraysize(valid_transform_feedback_bind_target_table)), + transform_feedback_primitive_mode( + valid_transform_feedback_primitive_mode_table, + arraysize(valid_transform_feedback_primitive_mode_table)), + uniform_block_parameter(valid_uniform_block_parameter_table, + arraysize(valid_uniform_block_parameter_table)), + uniform_parameter(valid_uniform_parameter_table, + arraysize(valid_uniform_parameter_table)), value_buffer_target(valid_value_buffer_target_table, arraysize(valid_value_buffer_target_table)), + vertex_attrib_i_type(valid_vertex_attrib_i_type_table, + arraysize(valid_vertex_attrib_i_type_table)), vertex_attrib_size(valid_vertex_attrib_size_table, arraysize(valid_vertex_attrib_size_table)), vertex_attrib_type(valid_vertex_attrib_type_table, @@ -638,4 +1247,76 @@ Validators::Validators() arraysize(valid_vertex_pointer_table)) { } +void Validators::UpdateValuesES3() { + attachment.AddValues(valid_attachment_table_es3, + arraysize(valid_attachment_table_es3)); + buffer_parameter.AddValues(valid_buffer_parameter_table_es3, + arraysize(valid_buffer_parameter_table_es3)); + buffer_target.AddValues(valid_buffer_target_table_es3, + arraysize(valid_buffer_target_table_es3)); + buffer_usage.AddValues(valid_buffer_usage_table_es3, + arraysize(valid_buffer_usage_table_es3)); + capability.AddValues(valid_capability_table_es3, + arraysize(valid_capability_table_es3)); + compressed_texture_format.AddValues( + valid_compressed_texture_format_table_es3, + arraysize(valid_compressed_texture_format_table_es3)); + equation.AddValues(valid_equation_table_es3, + arraysize(valid_equation_table_es3)); + frame_buffer_parameter.AddValues( + valid_frame_buffer_parameter_table_es3, + arraysize(valid_frame_buffer_parameter_table_es3)); + frame_buffer_target.AddValues(valid_frame_buffer_target_table_es3, + arraysize(valid_frame_buffer_target_table_es3)); + g_l_state.AddValues(valid_g_l_state_table_es3, + arraysize(valid_g_l_state_table_es3)); + get_tex_param_target.AddValues( + valid_get_tex_param_target_table_es3, + arraysize(valid_get_tex_param_target_table_es3)); + hint_target.AddValues(valid_hint_target_table_es3, + arraysize(valid_hint_target_table_es3)); + index_type.AddValues(valid_index_type_table_es3, + arraysize(valid_index_type_table_es3)); + pixel_store.AddValues(valid_pixel_store_table_es3, + arraysize(valid_pixel_store_table_es3)); + pixel_type.AddValues(valid_pixel_type_table_es3, + arraysize(valid_pixel_type_table_es3)); + program_parameter.AddValues(valid_program_parameter_table_es3, + arraysize(valid_program_parameter_table_es3)); + read_pixel_format.RemoveValues( + deprecated_read_pixel_format_table_es3, + arraysize(deprecated_read_pixel_format_table_es3)); + read_pixel_format.AddValues(valid_read_pixel_format_table_es3, + arraysize(valid_read_pixel_format_table_es3)); + read_pixel_type.RemoveValues(deprecated_read_pixel_type_table_es3, + arraysize(deprecated_read_pixel_type_table_es3)); + read_pixel_type.AddValues(valid_read_pixel_type_table_es3, + arraysize(valid_read_pixel_type_table_es3)); + render_buffer_format.AddValues( + valid_render_buffer_format_table_es3, + arraysize(valid_render_buffer_format_table_es3)); + render_buffer_parameter.AddValues( + valid_render_buffer_parameter_table_es3, + arraysize(valid_render_buffer_parameter_table_es3)); + texture_bind_target.AddValues(valid_texture_bind_target_table_es3, + arraysize(valid_texture_bind_target_table_es3)); + texture_format.AddValues(valid_texture_format_table_es3, + arraysize(valid_texture_format_table_es3)); + texture_internal_format.AddValues( + valid_texture_internal_format_table_es3, + arraysize(valid_texture_internal_format_table_es3)); + texture_internal_format_storage.RemoveValues( + deprecated_texture_internal_format_storage_table_es3, + arraysize(deprecated_texture_internal_format_storage_table_es3)); + texture_internal_format_storage.AddValues( + valid_texture_internal_format_storage_table_es3, + arraysize(valid_texture_internal_format_storage_table_es3)); + texture_parameter.AddValues(valid_texture_parameter_table_es3, + arraysize(valid_texture_parameter_table_es3)); + vertex_attrib_type.AddValues(valid_vertex_attrib_type_table_es3, + arraysize(valid_vertex_attrib_type_table_es3)); + vertex_attribute.AddValues(valid_vertex_attribute_table_es3, + arraysize(valid_vertex_attribute_table_es3)); +} + #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_IMPLEMENTATION_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/service/gpu_scheduler.cc b/chromium/gpu/command_buffer/service/gpu_scheduler.cc index 48df8dd98c4..8570fcded91 100644 --- a/chromium/gpu/command_buffer/service/gpu_scheduler.cc +++ b/chromium/gpu/command_buffer/service/gpu_scheduler.cc @@ -7,9 +7,9 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/compiler_specific.h" -#include "base/debug/trace_event.h" #include "base/message_loop/message_loop.h" #include "base/time/time.h" +#include "base/trace_event/trace_event.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_fence.h" #include "ui/gl/gl_switches.h" @@ -22,8 +22,6 @@ using ::base::SharedMemory; namespace gpu { -const int64 kUnscheduleFenceTimeOutDelay = 10000; - #if defined(OS_WIN) const int64 kRescheduleTimeOutDelay = 1000; #endif @@ -59,15 +57,11 @@ void GpuScheduler::PutChanged() { if (state.error != error::kNoError) return; - // Check that the GPU has passed all fences. - if (!PollUnscheduleFences()) - return; - // One of the unschedule fence tasks might have unscheduled us. if (!IsScheduled()) return; - base::TimeTicks begin_time(base::TimeTicks::HighResNow()); + base::TimeTicks begin_time(base::TimeTicks::Now()); error::Error error = error::kNoError; if (decoder_) decoder_->BeginDecoding(); @@ -76,7 +70,6 @@ void GpuScheduler::PutChanged() { break; DCHECK(IsScheduled()); - DCHECK(unschedule_fences_.empty()); error = parser_->ProcessCommands(CommandParser::kParseCommandsSlice); @@ -109,8 +102,7 @@ void GpuScheduler::PutChanged() { command_buffer_->SetParseError(error::kLostContext); } decoder_->EndDecoding(); - decoder_->AddProcessingCommandsTime( - base::TimeTicks::HighResNow() - begin_time); + decoder_->AddProcessingCommandsTime(base::TimeTicks::Now() - begin_time); } } @@ -169,8 +161,7 @@ bool GpuScheduler::IsScheduled() { } bool GpuScheduler::HasMoreWork() { - return !unschedule_fences_.empty() || - (decoder_ && decoder_->ProcessPendingQueries(false)) || + return (decoder_ && decoder_->ProcessPendingQueries(false)) || HasMoreIdleWork(); } @@ -222,45 +213,6 @@ void GpuScheduler::SetCommandProcessedCallback( command_processed_callback_ = callback; } -void GpuScheduler::DeferToFence(base::Closure task) { - unschedule_fences_.push(make_linked_ptr( - new UnscheduleFence(gfx::GLFence::Create(), task))); - SetScheduled(false); -} - -bool GpuScheduler::PollUnscheduleFences() { - if (unschedule_fences_.empty()) - return true; - - if (unschedule_fences_.front()->fence.get()) { - base::Time now = base::Time::Now(); - base::TimeDelta timeout = - base::TimeDelta::FromMilliseconds(kUnscheduleFenceTimeOutDelay); - - while (!unschedule_fences_.empty()) { - const UnscheduleFence& fence = *unschedule_fences_.front(); - if (fence.fence->HasCompleted() || - now - fence.issue_time > timeout) { - unschedule_fences_.front()->task.Run(); - unschedule_fences_.pop(); - SetScheduled(true); - } else { - return false; - } - } - } else { - glFinish(); - - while (!unschedule_fences_.empty()) { - unschedule_fences_.front()->task.Run(); - unschedule_fences_.pop(); - SetScheduled(true); - } - } - - return true; -} - bool GpuScheduler::IsPreempted() { if (!preemption_flag_.get()) return false; @@ -297,14 +249,4 @@ void GpuScheduler::RescheduleTimeOut() { rescheduled_count_ = new_count; } -GpuScheduler::UnscheduleFence::UnscheduleFence(gfx::GLFence* fence_, - base::Closure task_) - : fence(fence_), - issue_time(base::Time::Now()), - task(task_) { -} - -GpuScheduler::UnscheduleFence::~UnscheduleFence() { -} - } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/gpu_scheduler.h b/chromium/gpu/command_buffer/service/gpu_scheduler.h index 5e47d4a316b..b0b26303f71 100644 --- a/chromium/gpu/command_buffer/service/gpu_scheduler.h +++ b/chromium/gpu/command_buffer/service/gpu_scheduler.h @@ -91,12 +91,6 @@ class GPU_EXPORT GpuScheduler void SetCommandProcessedCallback(const base::Closure& callback); - void DeferToFence(base::Closure task); - - // Polls the fences, invoking callbacks that were waiting to be triggered - // by them and returns whether all fences were complete. - bool PollUnscheduleFences(); - bool HasMoreIdleWork(); void PerformIdleWork(); @@ -136,18 +130,6 @@ class GPU_EXPORT GpuScheduler // account of a timeout. int rescheduled_count_; - // The GpuScheduler will unschedule itself in the event that further GL calls - // are issued to it before all these fences have been crossed by the GPU. - struct UnscheduleFence { - UnscheduleFence(gfx::GLFence* fence, base::Closure task); - ~UnscheduleFence(); - - scoped_ptr<gfx::GLFence> fence; - base::Time issue_time; - base::Closure task; - }; - std::queue<linked_ptr<UnscheduleFence> > unschedule_fences_; - SchedulingChangedCallback scheduling_changed_callback_; base::Closure descheduled_callback_; base::Closure command_processed_callback_; diff --git a/chromium/gpu/command_buffer/service/gpu_scheduler_mock.h b/chromium/gpu/command_buffer/service/gpu_scheduler_mock.h deleted file mode 100644 index ed308e09582..00000000000 --- a/chromium/gpu/command_buffer/service/gpu_scheduler_mock.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 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. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_SCHEDULER_MOCK_H_ -#define GPU_COMMAND_BUFFER_SERVICE_GPU_SCHEDULER_MOCK_H_ - -#include "gpu/command_buffer/service/gpu_scheduler.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace gpu { - -class MockGpuScheduler : public GpuScheduler { - public: - explicit MockGpuScheduler(CommandBuffer* command_buffer) - : GpuScheduler(command_buffer) { - } - - MOCK_METHOD1(GetSharedMemoryBuffer, Buffer(int32 shm_id)); - MOCK_METHOD1(set_token, void(int32 token)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockGpuScheduler); -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_SCHEDULER_MOCK_H_ diff --git a/chromium/gpu/command_buffer/service/gpu_scheduler_unittest.cc b/chromium/gpu/command_buffer/service/gpu_scheduler_unittest.cc index c1c0d1c3609..c1c2ef7f2d2 100644 --- a/chromium/gpu/command_buffer/service/gpu_scheduler_unittest.cc +++ b/chromium/gpu/command_buffer/service/gpu_scheduler_unittest.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/message_loop/message_loop.h" #include "gpu/command_buffer/common/command_buffer_mock.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" @@ -11,10 +10,6 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#if defined(OS_MACOSX) -#include "base/mac/scoped_nsautorelease_pool.h" -#endif - using testing::_; using testing::DoAll; using testing::Invoke; @@ -72,10 +67,6 @@ class GpuSchedulerTest : public testing::Test { return command_buffer_->GetLastState().error; } -#if defined(OS_MACOSX) - base::mac::ScopedNSAutoreleasePool autorelease_pool_; -#endif - base::MessageLoop message_loop; scoped_ptr<MockCommandBuffer> command_buffer_; scoped_refptr<Buffer> shared_memory_buffer_; int32* buffer_; diff --git a/chromium/gpu/command_buffer/service/gpu_service_test.cc b/chromium/gpu/command_buffer/service/gpu_service_test.cc index a7c9db12521..d0b91175247 100644 --- a/chromium/gpu/command_buffer/service/gpu_service_test.cc +++ b/chromium/gpu/command_buffer/service/gpu_service_test.cc @@ -38,7 +38,7 @@ void GpuServiceTest::SetUpWithGLVersion(const char* gl_version, } void GpuServiceTest::SetUp() { - SetUpWithGLVersion("2.0", NULL); + SetUpWithGLVersion("2.0", "GL_EXT_framebuffer_object"); } void GpuServiceTest::TearDown() { @@ -51,5 +51,8 @@ void GpuServiceTest::TearDown() { testing::Test::TearDown(); } +gfx::GLContext* GpuServiceTest::GetGLContext() { + return context_.get(); +} } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/gpu_service_test.h b/chromium/gpu/command_buffer/service/gpu_service_test.h index 539d6ba7f3f..7c9c9782f32 100644 --- a/chromium/gpu/command_buffer/service/gpu_service_test.h +++ b/chromium/gpu/command_buffer/service/gpu_service_test.h @@ -28,6 +28,7 @@ class GpuServiceTest : public testing::Test { void SetUpWithGLVersion(const char* gl_version, const char* gl_extensions); void SetUp() override; void TearDown() override; + gfx::GLContext* GetGLContext(); scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; @@ -40,4 +41,4 @@ class GpuServiceTest : public testing::Test { } // namespace gles2 } // namespace gpu -#endif // GPU_COMMAND_BUFFER_SERVICE_MAILBOX_SYNCHRONIZER_H_ +#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_SERVICE_TEST_H_ diff --git a/chromium/gpu/command_buffer/service/gpu_state_tracer.cc b/chromium/gpu/command_buffer/service/gpu_state_tracer.cc index 51b0eba141f..9b8db2a489a 100644 --- a/chromium/gpu/command_buffer/service/gpu_state_tracer.cc +++ b/chromium/gpu/command_buffer/service/gpu_state_tracer.cc @@ -5,7 +5,7 @@ #include "gpu/command_buffer/service/gpu_state_tracer.h" #include "base/base64.h" -#include "base/debug/trace_event.h" +#include "base/trace_event/trace_event.h" #include "context_state.h" #include "ui/gfx/codec/png_codec.h" #include "ui/gl/gl_bindings.h" @@ -16,14 +16,14 @@ namespace { const int kBytesPerPixel = 4; -class Snapshot : public base::debug::ConvertableToTraceFormat { +class Snapshot : public base::trace_event::ConvertableToTraceFormat { public: static scoped_refptr<Snapshot> Create(const ContextState* state); // Save a screenshot of the currently bound framebuffer. bool SaveScreenshot(const gfx::Size& size); - // base::debug::ConvertableToTraceFormat implementation. + // base::trace_event::ConvertableToTraceFormat implementation. void AppendAsTraceFormat(std::string* out) const override; private: @@ -125,7 +125,7 @@ void GPUStateTracer::TakeSnapshotWithCurrentFramebuffer(const gfx::Size& size) { TRACE_DISABLED_BY_DEFAULT("gpu.debug"), "gpu::State", state_, - scoped_refptr<base::debug::ConvertableToTraceFormat>(snapshot)); + scoped_refptr<base::trace_event::ConvertableToTraceFormat>(snapshot)); } } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/gpu_switches.cc b/chromium/gpu/command_buffer/service/gpu_switches.cc index 8f5bc35cf40..d2ca49018b7 100644 --- a/chromium/gpu/command_buffer/service/gpu_switches.cc +++ b/chromium/gpu/command_buffer/service/gpu_switches.cc @@ -3,7 +3,8 @@ // found in the LICENSE file. #include "gpu/command_buffer/service/gpu_switches.h" -#include "base/basictypes.h" + +#include "base/macros.h" namespace switches { @@ -43,9 +44,6 @@ const char kEnforceGLMinimums[] = "enforce-gl-minimums"; // Sets the total amount of memory that may be allocated for GPU resources const char kForceGpuMemAvailableMb[] = "force-gpu-mem-available-mb"; -// Pass a set of GpuDriverBugWorkaroundType ids, seperated by ','. -const char kGpuDriverBugWorkarounds[] = "gpu-driver-bug-workarounds"; - // Sets the maximum size of the in-memory gpu program cache, in kb const char kGpuProgramCacheSizeKb[] = "gpu-program-cache-size-kb"; @@ -56,11 +54,23 @@ const char kDisableGpuShaderDiskCache[] = "disable-gpu-shader-disk-cache"; const char kEnableShareGroupAsyncTextureUpload[] = "enable-share-group-async-texture-upload"; +// Enable WebGL subscribe uniform extension. +const char kEnableSubscribeUniformExtension[] = + "enable-subscribe-uniform-extension"; + // Simulates shared textures when share groups are not available. Not available // everywhere. const char kEnableThreadedTextureMailboxes[] = "enable-threaded-texture-mailboxes"; +// Include ANGLE's intermediate representation (AST) output in shader +// compilation info logs. +const char kGLShaderIntermOutput[] = "gl-shader-interm-output"; + +// Emulate ESSL lowp and mediump float precisions by mutating the shaders to +// round intermediate values in ANGLE. +const char kEmulateShaderPrecision[] = "emulate-shader-precision"; + const char* kGpuSwitches[] = { kCompileShaderAlwaysSucceeds, kDisableGLErrorLimit, @@ -77,6 +87,9 @@ const char* kGpuSwitches[] = { kGpuProgramCacheSizeKb, kDisableGpuShaderDiskCache, kEnableShareGroupAsyncTextureUpload, + kEnableSubscribeUniformExtension, + kGLShaderIntermOutput, + kEmulateShaderPrecision, }; const int kNumGpuSwitches = arraysize(kGpuSwitches); diff --git a/chromium/gpu/command_buffer/service/gpu_switches.h b/chromium/gpu/command_buffer/service/gpu_switches.h index 26455432729..ac6883a4816 100644 --- a/chromium/gpu/command_buffer/service/gpu_switches.h +++ b/chromium/gpu/command_buffer/service/gpu_switches.h @@ -7,6 +7,7 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_SWITCHES_H_ #define GPU_COMMAND_BUFFER_SERVICE_GPU_SWITCHES_H_ +#include "gpu/config/gpu_switches.h" #include "gpu/gpu_export.h" namespace switches { @@ -22,11 +23,13 @@ GPU_EXPORT extern const char kEnableGPUServiceLoggingGPU[]; GPU_EXPORT extern const char kDisableGpuProgramCache[]; GPU_EXPORT extern const char kEnforceGLMinimums[]; GPU_EXPORT extern const char kForceGpuMemAvailableMb[]; -GPU_EXPORT extern const char kGpuDriverBugWorkarounds[]; GPU_EXPORT extern const char kGpuProgramCacheSizeKb[]; GPU_EXPORT extern const char kDisableGpuShaderDiskCache[]; GPU_EXPORT extern const char kEnableShareGroupAsyncTextureUpload[]; +GPU_EXPORT extern const char kEnableSubscribeUniformExtension[]; GPU_EXPORT extern const char kEnableThreadedTextureMailboxes[]; +GPU_EXPORT extern const char kGLShaderIntermOutput[]; +GPU_EXPORT extern const char kEmulateShaderPrecision[]; GPU_EXPORT extern const char* kGpuSwitches[]; GPU_EXPORT extern const int kNumGpuSwitches; @@ -34,4 +37,3 @@ GPU_EXPORT extern const int kNumGpuSwitches; } // namespace switches #endif // GPU_COMMAND_BUFFER_SERVICE_GPU_SWITCHES_H_ - diff --git a/chromium/gpu/command_buffer/service/gpu_tracer.cc b/chromium/gpu/command_buffer/service/gpu_tracer.cc index 024e4b6c5b2..e6c1e7fc8ac 100644 --- a/chromium/gpu/command_buffer/service/gpu_tracer.cc +++ b/chromium/gpu/command_buffer/service/gpu_tracer.cc @@ -7,19 +7,35 @@ #include <deque> #include "base/bind.h" -#include "base/debug/trace_event.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" #include "base/strings/string_util.h" +#include "base/thread_task_runner_handle.h" #include "base/time/time.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/context_group.h" +#include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_version_info.h" +#include "ui/gl/gpu_timing.h" namespace gpu { namespace gles2 { static const unsigned int kProcessInterval = 16; +static const char* kGpuTraceSourceNames[] = { + "GroupMarker", // kTraceGroupMarker = 0, + "TraceCHROMIUM", // kTraceCHROMIUM = 1, + "TraceCmd", // kTraceDecoder = 2, +}; +static_assert(NUM_TRACER_SOURCES == arraysize(kGpuTraceSourceNames), + "Trace source names must match enumeration."); + static TraceOutputter* g_outputter_thread = NULL; -TraceMarker::TraceMarker(const std::string& name) - : name_(name), +TraceMarker::TraceMarker(const std::string& category, const std::string& name) + : category_(category), + name_(name), trace_(NULL) { } @@ -34,144 +50,131 @@ scoped_refptr<TraceOutputter> TraceOutputter::Create(const std::string& name) { } TraceOutputter::TraceOutputter(const std::string& name) - : named_thread_(name.c_str()), local_trace_id_(0) { + : named_thread_(name.c_str()) { named_thread_.Start(); named_thread_.Stop(); } TraceOutputter::~TraceOutputter() { g_outputter_thread = NULL; } -void TraceOutputter::Trace(const std::string& name, - int64 start_time, - int64 end_time) { - TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0( +void TraceOutputter::TraceDevice(GpuTracerSource source, + const std::string& category, + const std::string& name, + int64 start_time, + int64 end_time) { + DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); + TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP2( TRACE_DISABLED_BY_DEFAULT("gpu.device"), name.c_str(), - local_trace_id_, + local_trace_device_id_, named_thread_.thread_id(), - start_time); - TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0( + start_time, + "gl_category", + category.c_str(), + "channel", + kGpuTraceSourceNames[source]); + TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP2( TRACE_DISABLED_BY_DEFAULT("gpu.device"), name.c_str(), - local_trace_id_, + local_trace_device_id_, named_thread_.thread_id(), - end_time); - ++local_trace_id_; + end_time, + "gl_category", + category.c_str(), + "channel", + kGpuTraceSourceNames[source]); + ++local_trace_device_id_; +} + +void TraceOutputter::TraceServiceBegin(GpuTracerSource source, + const std::string& category, + const std::string& name) { + DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); + TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TTS2( + TRACE_DISABLED_BY_DEFAULT("gpu.service"), + name.c_str(), local_trace_service_id_, + "gl_category", category.c_str(), + "channel", kGpuTraceSourceNames[source]); + + trace_service_id_stack_[source].push(local_trace_service_id_); + ++local_trace_service_id_; +} + +void TraceOutputter::TraceServiceEnd(GpuTracerSource source, + const std::string& category, + const std::string& name) { + DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); + DCHECK(!trace_service_id_stack_[source].empty()); + const uint64 local_trace_id = trace_service_id_stack_[source].top(); + trace_service_id_stack_[source].pop(); + + TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TTS2( + TRACE_DISABLED_BY_DEFAULT("gpu.service"), + name.c_str(), local_trace_id, + "gl_category", category.c_str(), + "channel", kGpuTraceSourceNames[source]); } GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter, + gfx::GPUTimingClient* gpu_timing_client, + const GpuTracerSource source, + const std::string& category, const std::string& name, - int64 offset, - GpuTracerType tracer_type) - : name_(name), + const bool tracing_service, + const bool tracing_device) + : source_(source), + category_(category), + name_(name), outputter_(outputter), - offset_(offset), - start_time_(0), - end_time_(0), - tracer_type_(tracer_type), - end_requested_(false) { - memset(queries_, 0, sizeof(queries_)); - switch (tracer_type_) { - case kTracerTypeARBTimer: - case kTracerTypeDisjointTimer: - glGenQueriesARB(2, queries_); - break; - - default: - tracer_type_ = kTracerTypeInvalid; + service_enabled_(tracing_service), + device_enabled_(tracing_device) { + if (tracing_device && + gpu_timing_client->IsAvailable() && + gpu_timing_client->IsTimerOffsetAvailable()) { + gpu_timer_ = gpu_timing_client->CreateGPUTimer(); } } GPUTrace::~GPUTrace() { - switch (tracer_type_) { - case kTracerTypeInvalid: - break; - - case kTracerTypeARBTimer: - case kTracerTypeDisjointTimer: - glDeleteQueriesARB(2, queries_); - break; +} + +void GPUTrace::Destroy(bool have_context) { + if (gpu_timer_.get()) { + gpu_timer_->Destroy(have_context); } } void GPUTrace::Start() { - TRACE_EVENT_COPY_ASYNC_BEGIN0( - TRACE_DISABLED_BY_DEFAULT("gpu.service"), name().c_str(), this); - - switch (tracer_type_) { - case kTracerTypeInvalid: - break; - - case kTracerTypeDisjointTimer: - // For the disjoint timer, GPU idle time does not seem to increment the - // internal counter. We must calculate the offset before any query. The - // good news is any device that supports disjoint timer will also support - // glGetInteger64v, so we can query it directly unlike the ARBTimer case. - // The "offset_" variable will always be 0 during normal use cases, only - // under the unit tests will it be set to specific test values. - if (offset_ == 0) { - GLint64 gl_now = 0; - glGetInteger64v(GL_TIMESTAMP, &gl_now); - offset_ = base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() - - gl_now / base::Time::kNanosecondsPerMicrosecond; - } - // Intentionally fall through to kTracerTypeARBTimer case.xs - case kTracerTypeARBTimer: - // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. - glQueryCounter(queries_[0], GL_TIMESTAMP); - break; + if (service_enabled_) { + outputter_->TraceServiceBegin(source_, category_, name_); + } + if (gpu_timer_.get()) { + gpu_timer_->Start(); } } void GPUTrace::End() { - end_requested_ = true; - switch (tracer_type_) { - case kTracerTypeInvalid: - break; - - case kTracerTypeARBTimer: - case kTracerTypeDisjointTimer: - // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. - glQueryCounter(queries_[1], GL_TIMESTAMP); - break; + if (gpu_timer_.get()) { + gpu_timer_->End(); + } + if (service_enabled_) { + outputter_->TraceServiceEnd(source_, category_, name_); } - - TRACE_EVENT_COPY_ASYNC_END0( - TRACE_DISABLED_BY_DEFAULT("gpu.service"), name().c_str(), this); } bool GPUTrace::IsAvailable() { - if (tracer_type_ != kTracerTypeInvalid) { - if (!end_requested_) - return false; - - GLint done = 0; - glGetQueryObjectiv(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done); - return !!done; - } - - return true; + return !gpu_timer_.get() || gpu_timer_->IsAvailable(); } void GPUTrace::Process() { - if (tracer_type_ == kTracerTypeInvalid) - return; - - DCHECK(IsAvailable()); - - GLuint64 begin_stamp = 0; - GLuint64 end_stamp = 0; + if (gpu_timer_.get()) { + DCHECK(IsAvailable()); - // TODO(dsinclair): It's possible for the timer to wrap during the start/end. - // We need to detect if the end is less then the start and correct for the - // wrapping. - glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp); - glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp); - - start_time_ = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) + - offset_; - end_time_ = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; - outputter_->Trace(name(), start_time_, end_time_); + int64 start = 0; + int64 end = 0; + gpu_timer_->GetStartEndTimestamps(&start, &end); + outputter_->TraceDevice(source_, category_, name_, start, end); + } } GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder) @@ -180,43 +183,61 @@ GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder) gpu_trace_dev_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( TRACE_DISABLED_BY_DEFAULT("gpu.device"))), decoder_(decoder), - timer_offset_(0), - last_tracer_source_(kTraceGroupInvalid), - tracer_type_(kTracerTypeInvalid), - gpu_timing_synced_(false), gpu_executing_(false), process_posted_(false) { - if (gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) { - tracer_type_ = kTracerTypeDisjointTimer; - outputter_ = TraceOutputter::Create("GL_EXT_disjoint_timer_query"); - } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) { - tracer_type_ = kTracerTypeARBTimer; - outputter_ = TraceOutputter::Create("GL_ARB_timer_query"); + DCHECK(decoder_); + gfx::GLContext* context = decoder_->GetGLContext(); + if (context) { + gpu_timing_client_ = context->CreateGPUTimingClient(); + } else { + gpu_timing_client_ = new gfx::GPUTimingClient(); } } GPUTracer::~GPUTracer() { } +void GPUTracer::Destroy(bool have_context) { + for (int n = 0; n < NUM_TRACER_SOURCES; n++) { + for (size_t i = 0; i < markers_[n].size(); i++) { + TraceMarker& marker = markers_[n][i]; + if (marker.trace_.get()) { + marker.trace_->Destroy(have_context); + marker.trace_ = 0; + } + } + } + + ClearFinishedTraces(have_context); +} + bool GPUTracer::BeginDecoding() { if (gpu_executing_) return false; - CalculateTimerOffset(); - gpu_executing_ = true; + if (!outputter_) { + outputter_ = CreateOutputter(gpu_timing_client_->GetTimerTypeName()); + } - if (IsTracing()) { - // Reset disjoint bit for the disjoint timer. - if (tracer_type_ == kTracerTypeDisjointTimer) { - GLint disjoint_value = 0; - glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); - } + if (*gpu_trace_dev_category == '\0') { + // If GPU device category is off, invalidate timing sync. + gpu_timing_client_->InvalidateTimerOffset(); + } + gpu_executing_ = true; + if (IsTracing()) { + gpu_timing_client_->CheckAndResetTimerErrors(); // Begin a Trace for all active markers for (int n = 0; n < NUM_TRACER_SOURCES; n++) { for (size_t i = 0; i < markers_[n].size(); i++) { - markers_[n][i].trace_ = CreateTrace(markers_[n][i].name_); - markers_[n][i].trace_->Start(); + TraceMarker& trace_marker = markers_[n][i]; + trace_marker.trace_ = + new GPUTrace(outputter_, gpu_timing_client_.get(), + static_cast<GpuTracerSource>(n), + trace_marker.category_, trace_marker.name_, + *gpu_trace_srv_category != 0, + *gpu_trace_dev_category != 0); + trace_marker.trace_->Start(); } } } @@ -230,12 +251,15 @@ bool GPUTracer::EndDecoding() { // End Trace for all active markers if (IsTracing()) { for (int n = 0; n < NUM_TRACER_SOURCES; n++) { - for (size_t i = 0; i < markers_[n].size(); i++) { - if (markers_[n][i].trace_.get()) { - markers_[n][i].trace_->End(); - if (markers_[n][i].trace_->IsEnabled()) - traces_.push_back(markers_[n][i].trace_); - markers_[n][i].trace_ = 0; + if (!markers_[n].empty()) { + for (int i = static_cast<int>(markers_[n].size()) - 1; i >= 0; --i) { + TraceMarker& marker = markers_[n][i]; + if (marker.trace_.get()) { + marker.trace_->End(); + + finished_traces_.push_back(marker.trace_); + marker.trace_ = 0; + } } } } @@ -249,19 +273,22 @@ bool GPUTracer::EndDecoding() { return true; } -bool GPUTracer::Begin(const std::string& name, GpuTracerSource source) { +bool GPUTracer::Begin(const std::string& category, const std::string& name, + GpuTracerSource source) { if (!gpu_executing_) return false; DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); // Push new marker from given 'source' - last_tracer_source_ = source; - markers_[source].push_back(TraceMarker(name)); + markers_[source].push_back(TraceMarker(category, name)); // Create trace if (IsTracing()) { - scoped_refptr<GPUTrace> trace = CreateTrace(name); + scoped_refptr<GPUTrace> trace = new GPUTrace( + outputter_, gpu_timing_client_.get(), source, category, name, + *gpu_trace_srv_category != 0, + *gpu_trace_dev_category != 0); trace->Start(); markers_[source].back().trace_ = trace; } @@ -277,14 +304,14 @@ bool GPUTracer::End(GpuTracerSource source) { // Pop last marker with matching 'source' if (!markers_[source].empty()) { - if (IsTracing()) { - scoped_refptr<GPUTrace> trace = markers_[source].back().trace_; - if (trace.get()) { + scoped_refptr<GPUTrace> trace = markers_[source].back().trace_; + if (trace.get()) { + if (IsTracing()) { trace->End(); - if (trace->IsEnabled()) - traces_.push_back(trace); - IssueProcessTask(); } + + finished_traces_.push_back(trace); + IssueProcessTask(); } markers_[source].pop_back(); @@ -297,20 +324,32 @@ bool GPUTracer::IsTracing() { return (*gpu_trace_srv_category != 0) || (*gpu_trace_dev_category != 0); } -const std::string& GPUTracer::CurrentName() const { - if (last_tracer_source_ >= 0 && - last_tracer_source_ < NUM_TRACER_SOURCES && - !markers_[last_tracer_source_].empty()) { - return markers_[last_tracer_source_].back().name_; +const std::string& GPUTracer::CurrentCategory(GpuTracerSource source) const { + if (source >= 0 && + source < NUM_TRACER_SOURCES && + !markers_[source].empty()) { + return markers_[source].back().category_; } return base::EmptyString(); } -scoped_refptr<GPUTrace> GPUTracer::CreateTrace(const std::string& name) { - GpuTracerType tracer_type = *gpu_trace_dev_category ? tracer_type_ : - kTracerTypeInvalid; +const std::string& GPUTracer::CurrentName(GpuTracerSource source) const { + if (source >= 0 && + source < NUM_TRACER_SOURCES && + !markers_[source].empty()) { + return markers_[source].back().name_; + } + return base::EmptyString(); +} - return new GPUTrace(outputter_, name, timer_offset_, tracer_type); +scoped_refptr<Outputter> GPUTracer::CreateOutputter(const std::string& name) { + return TraceOutputter::Create(name); +} + +void GPUTracer::PostTask() { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::Bind(&GPUTracer::Process, base::AsWeakPtr(this)), + base::TimeDelta::FromMilliseconds(kProcessInterval)); } void GPUTracer::Process() { @@ -320,8 +359,8 @@ void GPUTracer::Process() { } void GPUTracer::ProcessTraces() { - if (tracer_type_ == kTracerTypeInvalid) { - traces_.clear(); + if (!gpu_timing_client_->IsAvailable()) { + ClearFinishedTraces(false); return; } @@ -330,77 +369,46 @@ void GPUTracer::ProcessTraces() { // Make owning decoder's GL context current if (!decoder_->MakeCurrent()) { // Skip subsequent GL calls if MakeCurrent fails - traces_.clear(); + ClearFinishedTraces(false); return; } - // Check if disjoint operation has occurred, discard ongoing traces if so. - if (tracer_type_ == kTracerTypeDisjointTimer) { - GLint disjoint_value = 0; - glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); - if (disjoint_value) - traces_.clear(); + // Check if timers are still valid (e.g: a disjoint operation + // might have occurred.) + if (gpu_timing_client_->CheckAndResetTimerErrors()) { + ClearFinishedTraces(true); } - while (!traces_.empty() && traces_.front()->IsAvailable()) { - traces_.front()->Process(); - traces_.pop_front(); + while (!finished_traces_.empty()) { + scoped_refptr<GPUTrace>& trace = finished_traces_.front(); + if (trace->IsDeviceTraceEnabled()) { + if (!finished_traces_.front()->IsAvailable()) + break; + finished_traces_.front()->Process(); + } + finished_traces_.front()->Destroy(true); + finished_traces_.pop_front(); } // Clear pending traces if there were are any errors GLenum err = glGetError(); if (err != GL_NO_ERROR) - traces_.clear(); + ClearFinishedTraces(true); } -void GPUTracer::CalculateTimerOffset() { - if (tracer_type_ != kTracerTypeInvalid) { - if (*gpu_trace_dev_category == '\0') { - // If GPU device category is off, invalidate timing sync. - gpu_timing_synced_ = false; - return; - } else if (tracer_type_ == kTracerTypeDisjointTimer) { - // Disjoint timers offsets should be calculated before every query. - gpu_timing_synced_ = true; - timer_offset_ = 0; - } - - if (gpu_timing_synced_) - return; - - TRACE_EVENT0("gpu", "GPUTracer::CalculateTimerOffset"); - - // NOTE(vmiura): It would be better to use glGetInteger64v, however - // it's not available everywhere. - GLuint64 gl_now = 0; - GLuint query; - - glGenQueriesARB(1, &query); - - glFinish(); - glQueryCounter(query, GL_TIMESTAMP); - glFinish(); - - glGetQueryObjectui64v(query, GL_QUERY_RESULT, &gl_now); - glDeleteQueriesARB(1, &query); - - base::TimeTicks system_now = base::TimeTicks::NowFromSystemTraceTime(); - - gl_now /= base::Time::kNanosecondsPerMicrosecond; - timer_offset_ = system_now.ToInternalValue() - gl_now; - gpu_timing_synced_ = true; +void GPUTracer::ClearFinishedTraces(bool have_context) { + while (!finished_traces_.empty()) { + finished_traces_.front()->Destroy(have_context); + finished_traces_.pop_front(); } } void GPUTracer::IssueProcessTask() { - if (traces_.empty() || process_posted_) + if (finished_traces_.empty() || process_posted_) return; process_posted_ = true; - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - base::Bind(&GPUTracer::Process, base::AsWeakPtr(this)), - base::TimeDelta::FromMilliseconds(kProcessInterval)); + PostTask(); } } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/gpu_tracer.h b/chromium/gpu/command_buffer/service/gpu_tracer.h index 2e81b4eb3bb..2565ab87a0e 100644 --- a/chromium/gpu/command_buffer/service/gpu_tracer.h +++ b/chromium/gpu/command_buffer/service/gpu_tracer.h @@ -6,7 +6,10 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_TRACER_H_ #define GPU_COMMAND_BUFFER_SERVICE_GPU_TRACER_H_ +#include <deque> +#include <stack> #include <string> +#include <vector> #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" @@ -14,7 +17,11 @@ #include "base/threading/thread.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/gpu_export.h" -#include "ui/gl/gl_bindings.h" + +namespace gfx { + class GPUTimingClient; + class GPUTimer; +} namespace gpu { namespace gles2 { @@ -33,27 +40,24 @@ enum GpuTracerSource { NUM_TRACER_SOURCES }; -enum GpuTracerType { - kTracerTypeInvalid = -1, - - kTracerTypeARBTimer, - kTracerTypeDisjointTimer -}; - // Marker structure for a Trace. struct TraceMarker { - TraceMarker(const std::string& name); + TraceMarker(const std::string& category, const std::string& name); ~TraceMarker(); + std::string category_; std::string name_; scoped_refptr<GPUTrace> trace_; }; // Traces GPU Commands. -class GPUTracer : public base::SupportsWeakPtr<GPUTracer> { +class GPU_EXPORT GPUTracer + : public base::SupportsWeakPtr<GPUTracer> { public: explicit GPUTracer(gles2::GLES2Decoder* decoder); - ~GPUTracer(); + virtual ~GPUTracer(); + + void Destroy(bool have_context); // Scheduled processing in decoder begins. bool BeginDecoding(); @@ -62,50 +66,61 @@ class GPUTracer : public base::SupportsWeakPtr<GPUTracer> { bool EndDecoding(); // Begin a trace marker. - bool Begin(const std::string& name, GpuTracerSource source); + bool Begin(const std::string& category, const std::string& name, + GpuTracerSource source); // End the last started trace marker. bool End(GpuTracerSource source); - bool IsTracing(); + virtual bool IsTracing(); // Retrieve the name of the current open trace. // Returns empty string if no current open trace. - const std::string& CurrentName() const; + const std::string& CurrentCategory(GpuTracerSource source) const; + const std::string& CurrentName(GpuTracerSource source) const; - private: + protected: // Trace Processing. - scoped_refptr<GPUTrace> CreateTrace(const std::string& name); + virtual scoped_refptr<Outputter> CreateOutputter(const std::string& name); + virtual void PostTask(); + void Process(); void ProcessTraces(); + void ClearFinishedTraces(bool have_context); - void CalculateTimerOffset(); void IssueProcessTask(); + scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_; scoped_refptr<Outputter> outputter_; std::vector<TraceMarker> markers_[NUM_TRACER_SOURCES]; - std::deque<scoped_refptr<GPUTrace> > traces_; + std::deque<scoped_refptr<GPUTrace> > finished_traces_; const unsigned char* gpu_trace_srv_category; const unsigned char* gpu_trace_dev_category; gles2::GLES2Decoder* decoder_; - int64 timer_offset_; - GpuTracerSource last_tracer_source_; - - GpuTracerType tracer_type_; - bool gpu_timing_synced_; bool gpu_executing_; bool process_posted_; + private: DISALLOW_COPY_AND_ASSIGN(GPUTracer); }; class Outputter : public base::RefCounted<Outputter> { public: - virtual void Trace(const std::string& name, - int64 start_time, - int64 end_time) = 0; + virtual void TraceDevice(GpuTracerSource source, + const std::string& category, + const std::string& name, + int64 start_time, + int64 end_time) = 0; + + virtual void TraceServiceBegin(GpuTracerSource source, + const std::string& category, + const std::string& name) = 0; + + virtual void TraceServiceEnd(GpuTracerSource source, + const std::string& category, + const std::string& name) = 0; protected: virtual ~Outputter() {} @@ -115,9 +130,19 @@ class Outputter : public base::RefCounted<Outputter> { class TraceOutputter : public Outputter { public: static scoped_refptr<TraceOutputter> Create(const std::string& name); - void Trace(const std::string& name, - int64 start_time, - int64 end_time) override; + void TraceDevice(GpuTracerSource source, + const std::string& category, + const std::string& name, + int64 start_time, + int64 end_time) override; + + void TraceServiceBegin(GpuTracerSource source, + const std::string& category, + const std::string& name) override; + + void TraceServiceEnd(GpuTracerSource source, + const std::string& category, + const std::string& name) override; protected: friend class base::RefCounted<Outputter>; @@ -125,8 +150,12 @@ class TraceOutputter : public Outputter { ~TraceOutputter() override; base::Thread named_thread_; - uint64 local_trace_id_; + uint64 local_trace_device_id_ = 0; + uint64 local_trace_service_id_ = 0; + + std::stack<uint64> trace_service_id_stack_[NUM_TRACER_SOURCES]; + private: DISALLOW_COPY_AND_ASSIGN(TraceOutputter); }; @@ -134,16 +163,20 @@ class GPU_EXPORT GPUTrace : public base::RefCounted<GPUTrace> { public: GPUTrace(scoped_refptr<Outputter> outputter, + gfx::GPUTimingClient* gpu_timing_client, + const GpuTracerSource source, + const std::string& category, const std::string& name, - int64 offset, - GpuTracerType tracer_type); + const bool tracing_service, + const bool tracing_device); - bool IsEnabled() { return tracer_type_ != kTracerTypeInvalid; } - const std::string& name() { return name_; } + void Destroy(bool have_context); void Start(); void End(); bool IsAvailable(); + bool IsServiceTraceEnabled() const { return service_enabled_; } + bool IsDeviceTraceEnabled() const { return device_enabled_; } void Process(); private: @@ -153,18 +186,32 @@ class GPU_EXPORT GPUTrace friend class base::RefCounted<GPUTrace>; - std::string name_; + const GpuTracerSource source_ = kTraceGroupInvalid; + const std::string category_; + const std::string name_; scoped_refptr<Outputter> outputter_; + scoped_ptr<gfx::GPUTimer> gpu_timer_; + const bool service_enabled_ = false; + const bool device_enabled_ = false; - int64 offset_; - int64 start_time_; - int64 end_time_; - GpuTracerType tracer_type_; - bool end_requested_; + DISALLOW_COPY_AND_ASSIGN(GPUTrace); +}; - GLuint queries_[2]; +class ScopedGPUTrace { + public: + ScopedGPUTrace(GPUTracer* gpu_tracer, + GpuTracerSource source, + const std::string& category, + const std::string& name) + : gpu_tracer_(gpu_tracer), source_(source) { + gpu_tracer_->Begin(category, name, source_); + } - DISALLOW_COPY_AND_ASSIGN(GPUTrace); + ~ScopedGPUTrace() { gpu_tracer_->End(source_); } + + private: + GPUTracer* gpu_tracer_; + GpuTracerSource source_; }; } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc b/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc index 59ea63e0b3f..8de31fade1a 100644 --- a/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc +++ b/chromium/gpu/command_buffer/service/gpu_tracer_unittest.cc @@ -5,34 +5,46 @@ #include <map> #include <set> +#include "base/bind.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/gpu_service_test.h" #include "gpu/command_buffer/service/gpu_tracer.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_mock.h" +#include "ui/gl/gpu_timing.h" namespace gpu { namespace gles2 { +namespace { -using ::testing::InvokeWithoutArgs; -using ::testing::Return; -using ::testing::ReturnRef; -using ::testing::ReturnPointee; -using ::testing::NotNull; -using ::testing::ElementsAreArray; -using ::testing::ElementsAre; -using ::testing::SetArrayArgument; +using ::testing::_; using ::testing::AtLeast; -using ::testing::SetArgPointee; -using ::testing::Pointee; -using ::testing::Unused; +using ::testing::AtMost; +using ::testing::Exactly; using ::testing::Invoke; -using ::testing::_; +using ::testing::NotNull; +using ::testing::Return; + +int64 g_fakeCPUTime = 0; +int64 FakeCpuTime() { + return g_fakeCPUTime; +} class MockOutputter : public Outputter { public: MockOutputter() {} - MOCK_METHOD3(Trace, - void(const std::string& name, int64 start_time, int64 end_time)); + MOCK_METHOD5(TraceDevice, + void(GpuTracerSource source, + const std::string& category, const std::string& name, + int64 start_time, int64 end_time)); + + MOCK_METHOD3(TraceServiceBegin, + void(GpuTracerSource source, + const std::string& category, const std::string& name)); + + MOCK_METHOD3(TraceServiceEnd, + void(GpuTracerSource source, + const std::string& category, const std::string& name)); protected: ~MockOutputter() {} @@ -50,15 +62,16 @@ class GlFakeQueries { } void SetCurrentGLTime(GLint64 current_time) { current_time_ = current_time; } + void SetDisjoint() { disjointed_ = true; } - void GenQueriesARB(GLsizei n, GLuint* ids) { + void GenQueries(GLsizei n, GLuint* ids) { for (GLsizei i = 0; i < n; i++) { ids[i] = next_query_id_++; alloced_queries_.insert(ids[i]); } } - void DeleteQueriesARB(GLsizei n, const GLuint* ids) { + void DeleteQueries(GLsizei n, const GLuint* ids) { for (GLsizei i = 0; i < n; i++) { alloced_queries_.erase(ids[i]); query_timestamp_.erase(ids[i]); @@ -76,7 +89,7 @@ class GlFakeQueries { break; } default: - ASSERT_TRUE(false); + FAIL() << "Invalid variable passed to GetQueryObjectiv: " << pname; } } @@ -87,7 +100,17 @@ class GlFakeQueries { query_timestamp_[id] = current_time_; break; default: - ASSERT_TRUE(false); + FAIL() << "Invalid variable passed to QueryCounter: " << target; + } + } + + void GetInteger64v(GLenum pname, GLint64 * data) { + switch (pname) { + case GL_TIMESTAMP: + *data = current_time_; + break; + default: + FAIL() << "Invalid variable passed to GetInteger64v: " << pname; } } @@ -98,30 +121,228 @@ class GlFakeQueries { *params = query_timestamp_.find(id)->second; break; default: - ASSERT_TRUE(false); + FAIL() << "Invalid variable passed to GetQueryObjectui64v: " << pname; } } + void GetIntegerv(GLenum pname, GLint* params) { + switch (pname) { + case GL_GPU_DISJOINT_EXT: + *params = static_cast<GLint>(disjointed_); + disjointed_ = false; + break; + default: + FAIL() << "Invalid variable passed to GetIntegerv: " << pname; + } + } + + void Finish() { + } + + GLenum GetError() { + return GL_NO_ERROR; + } + protected: - GLint64 current_time_; - GLuint next_query_id_; + bool disjointed_ = false; + GLint64 current_time_ = 0; + GLuint next_query_id_ = 0; std::set<GLuint> alloced_queries_; std::map<GLuint, GLint64> query_timestamp_; }; -class BaseGpuTracerTest : public GpuServiceTest { +class GPUTracerTester : public GPUTracer { public: - BaseGpuTracerTest() {} + explicit GPUTracerTester(gles2::GLES2Decoder* decoder) + : GPUTracer(decoder), tracing_enabled_(0) { + gpu_timing_client_->SetCpuTimeForTesting(base::Bind(&FakeCpuTime)); + + // Force tracing to be dependent on our mock variable here. + gpu_trace_srv_category = &tracing_enabled_; + gpu_trace_dev_category = &tracing_enabled_; + } + + ~GPUTracerTester() override {} + + void SetTracingEnabled(bool enabled) { + tracing_enabled_ = enabled ? 1 : 0; + } + + void SetOutputter(scoped_refptr<Outputter> outputter) { + set_outputter_ = outputter; + } + + protected: + scoped_refptr<Outputter> CreateOutputter(const std::string& name) override { + if (set_outputter_.get()) { + return set_outputter_; + } + return new MockOutputter(); + } + + void PostTask() override { + // Process synchronously. + Process(); + } + + unsigned char tracing_enabled_; + + scoped_refptr<Outputter> set_outputter_; +}; + +class BaseGpuTest : public GpuServiceTest { + public: + explicit BaseGpuTest(gfx::GPUTiming::TimerType test_timer_type) + : test_timer_type_(test_timer_type) { + } + + protected: + void SetUp() override { + g_fakeCPUTime = 0; + const char* gl_version = "3.2"; + const char* extensions = ""; + if (GetTimerType() == gfx::GPUTiming::kTimerTypeEXT) { + gl_version = "opengl 2.1"; + extensions = "GL_EXT_timer_query"; + } else if (GetTimerType() == gfx::GPUTiming::kTimerTypeDisjoint) { + gl_version = "opengl es 3.0"; + extensions = "GL_EXT_disjoint_timer_query"; + } else if (GetTimerType() == gfx::GPUTiming::kTimerTypeARB) { + // TODO(sievers): The tracer should not depend on ARB_occlusion_query. + // Try merge Query APIs (core, ARB, EXT) into a single binding each. + extensions = "GL_ARB_timer_query GL_ARB_occlusion_query"; + } + GpuServiceTest::SetUpWithGLVersion(gl_version, extensions); + + // Disjoint check should only be called by kTracerTypeDisjointTimer type. + if (GetTimerType() == gfx::GPUTiming::kTimerTypeDisjoint) { + EXPECT_CALL(*gl_, GetIntegerv(GL_GPU_DISJOINT_EXT, _)).Times(AtLeast(1)) + .WillRepeatedly( + Invoke(&gl_fake_queries_, &GlFakeQueries::GetIntegerv)); + } else { + EXPECT_CALL(*gl_, GetIntegerv(GL_GPU_DISJOINT_EXT, _)).Times(Exactly(0)); + } + gpu_timing_client_ = GetGLContext()->CreateGPUTimingClient(); + gpu_timing_client_->SetCpuTimeForTesting(base::Bind(&FakeCpuTime)); + gl_fake_queries_.Reset(); + + outputter_ref_ = new MockOutputter(); + } - /////////////////////////////////////////////////////////////////////////// + void TearDown() override { + outputter_ref_ = NULL; + gpu_timing_client_ = NULL; + + gl_fake_queries_.Reset(); + GpuServiceTest::TearDown(); + } + + void ExpectTraceQueryMocks() { + if (gpu_timing_client_->IsAvailable() && + gpu_timing_client_->IsTimerOffsetAvailable()) { + // Delegate query APIs used by GPUTrace to a GlFakeQueries + EXPECT_CALL(*gl_, GenQueries(2, NotNull())).Times(AtLeast(1)) + .WillRepeatedly( + Invoke(&gl_fake_queries_, &GlFakeQueries::GenQueries)); + + EXPECT_CALL(*gl_, GetQueryObjectiv(_, GL_QUERY_RESULT_AVAILABLE, + NotNull())) + .WillRepeatedly( + Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectiv)); + + EXPECT_CALL(*gl_, GetInteger64v(GL_TIMESTAMP, _)) + .WillRepeatedly( + Invoke(&gl_fake_queries_, &GlFakeQueries::GetInteger64v)); + + EXPECT_CALL(*gl_, QueryCounter(_, GL_TIMESTAMP)).Times(AtLeast(2)) + .WillRepeatedly( + Invoke(&gl_fake_queries_, &GlFakeQueries::QueryCounter)); + + EXPECT_CALL(*gl_, GetQueryObjectui64v(_, GL_QUERY_RESULT, NotNull())) + .WillRepeatedly( + Invoke(&gl_fake_queries_, + &GlFakeQueries::GetQueryObjectui64v)); + + EXPECT_CALL(*gl_, DeleteQueries(2, NotNull())).Times(AtLeast(1)) + .WillRepeatedly( + Invoke(&gl_fake_queries_, &GlFakeQueries::DeleteQueries)); + } + } - void DoTraceTest() { - MockOutputter* outputter = new MockOutputter(); - scoped_refptr<Outputter> outputter_ref = outputter; + void ExpectOutputterBeginMocks(MockOutputter* outputter, + GpuTracerSource source, + const std::string& category, + const std::string& name) { + EXPECT_CALL(*outputter, + TraceServiceBegin(source, category, name)); + } - SetupTimerQueryMocks(); + void ExpectOutputterEndMocks(MockOutputter* outputter, + GpuTracerSource source, + const std::string& category, + const std::string& name, int64 expect_start_time, + int64 expect_end_time, + bool trace_device) { + EXPECT_CALL(*outputter, + TraceServiceEnd(source, category, name)); + + if (trace_device) { + EXPECT_CALL(*outputter, + TraceDevice(source, category, name, + expect_start_time, expect_end_time)) + .Times(Exactly(1)); + } else { + EXPECT_CALL(*outputter, TraceDevice(source, category, name, + expect_start_time, expect_end_time)) + .Times(Exactly(0)); + } + } + void ExpectOutputterMocks(MockOutputter* outputter, + bool tracing_device, + GpuTracerSource source, + const std::string& category, + const std::string& name, int64 expect_start_time, + int64 expect_end_time) { + ExpectOutputterBeginMocks(outputter, source, category, name); + bool valid_timer = tracing_device && + gpu_timing_client_->IsAvailable() && + gpu_timing_client_->IsTimerOffsetAvailable(); + ExpectOutputterEndMocks(outputter, source, category, name, + expect_start_time, expect_end_time, valid_timer); + } + + void ExpectTracerOffsetQueryMocks() { + if (GetTimerType() != gfx::GPUTiming::kTimerTypeARB) { + EXPECT_CALL(*gl_, GetInteger64v(GL_TIMESTAMP, NotNull())) + .Times(Exactly(0)); + } else { + EXPECT_CALL(*gl_, GetInteger64v(GL_TIMESTAMP, NotNull())) + .Times(AtMost(1)) + .WillRepeatedly( + Invoke(&gl_fake_queries_, &GlFakeQueries::GetInteger64v)); + } + } + + gfx::GPUTiming::TimerType GetTimerType() { return test_timer_type_; } + + gfx::GPUTiming::TimerType test_timer_type_; + GlFakeQueries gl_fake_queries_; + + scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_; + scoped_refptr<MockOutputter> outputter_ref_; +}; + +// Test GPUTrace calls all the correct gl calls. +class BaseGpuTraceTest : public BaseGpuTest { + public: + explicit BaseGpuTraceTest(gfx::GPUTiming::TimerType test_timer_type) + : BaseGpuTest(test_timer_type) {} + + void DoTraceTest(bool tracing_service, bool tracing_device) { // Expected results + const GpuTracerSource tracer_source = kTraceGroupMarker; + const std::string category_name("trace_category"); const std::string trace_name("trace_test"); const int64 offset_time = 3231; const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond; @@ -132,27 +353,35 @@ class BaseGpuTracerTest : public GpuServiceTest { const int64 expect_end_time = (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time; - // Expected Outputter::Trace call - EXPECT_CALL(*outputter, - Trace(trace_name, expect_start_time, expect_end_time)); + if (tracing_service) + ExpectOutputterMocks(outputter_ref_.get(), tracing_device, tracer_source, + category_name, trace_name, + expect_start_time, expect_end_time); + + if (tracing_device) + ExpectTraceQueryMocks(); - scoped_refptr<GPUTrace> trace = - new GPUTrace(outputter_ref, trace_name, offset_time, - GetTracerType()); + scoped_refptr<GPUTrace> trace = new GPUTrace( + outputter_ref_, gpu_timing_client_.get(), tracer_source, + category_name, trace_name, tracing_service, tracing_device); gl_fake_queries_.SetCurrentGLTime(start_timestamp); + g_fakeCPUTime = expect_start_time; trace->Start(); // Shouldn't be available before End() call gl_fake_queries_.SetCurrentGLTime(end_timestamp); - EXPECT_FALSE(trace->IsAvailable()); + g_fakeCPUTime = expect_end_time; + if (tracing_device) + EXPECT_FALSE(trace->IsAvailable()); trace->End(); // Shouldn't be available until the queries complete gl_fake_queries_.SetCurrentGLTime(end_timestamp - base::Time::kNanosecondsPerMicrosecond); - EXPECT_FALSE(trace->IsAvailable()); + if (tracing_device) + EXPECT_FALSE(trace->IsAvailable()); // Now it should be available gl_fake_queries_.SetCurrentGLTime(end_timestamp); @@ -160,74 +389,363 @@ class BaseGpuTracerTest : public GpuServiceTest { // Proces should output expected Trace results to MockOutputter trace->Process(); + + // Destroy trace after we are done. + trace->Destroy(true); + + outputter_ref_ = NULL; } +}; - protected: - void SetUp() override { - GpuServiceTest::SetUp(); - gl_fake_queries_.Reset(); +class GpuARBTimerTraceTest : public BaseGpuTraceTest { + public: + GpuARBTimerTraceTest() : BaseGpuTraceTest(gfx::GPUTiming::kTimerTypeARB) {} +}; + +class GpuDisjointTimerTraceTest : public BaseGpuTraceTest { + public: + GpuDisjointTimerTraceTest() + : BaseGpuTraceTest(gfx::GPUTiming::kTimerTypeDisjoint) {} +}; + +TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestOff) { + DoTraceTest(false, false); +} + +TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestServiceOnly) { + DoTraceTest(true, false); +} + +TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestDeviceOnly) { + DoTraceTest(false, true); +} + +TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestBothOn) { + DoTraceTest(true, true); +} + +TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestOff) { + DoTraceTest(false, false); +} + +TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestServiceOnly) { + DoTraceTest(true, false); +} + +TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestDeviceOnly) { + DoTraceTest(false, true); +} + +TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestBothOn) { + DoTraceTest(true, true); +} + +// Test GPUTracer calls all the correct gl calls. +class BaseGpuTracerTest : public BaseGpuTest { + public: + explicit BaseGpuTracerTest(gfx::GPUTiming::TimerType test_timer_type) + : BaseGpuTest(test_timer_type) {} + + void DoBasicTracerTest() { + ExpectTracerOffsetQueryMocks(); + + MockGLES2Decoder decoder; + EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext())); + GPUTracerTester tracer(&decoder); + tracer.SetTracingEnabled(true); + + tracer.SetOutputter(outputter_ref_); + + ASSERT_TRUE(tracer.BeginDecoding()); + ASSERT_TRUE(tracer.EndDecoding()); + + outputter_ref_ = NULL; } - void TearDown() override { - gl_.reset(); - gl_fake_queries_.Reset(); - GpuServiceTest::TearDown(); + void DoTracerMarkersTest() { + ExpectTracerOffsetQueryMocks(); + + EXPECT_CALL(*gl_, GetError()).Times(AtLeast(0)) + .WillRepeatedly( + Invoke(&gl_fake_queries_, &GlFakeQueries::GetError)); + + const std::string category_name("trace_category"); + const std::string trace_name("trace_test"); + const int64 offset_time = 3231; + const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond; + const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond; + const int64 expect_start_time = + (start_timestamp / base::Time::kNanosecondsPerMicrosecond) + + offset_time; + const int64 expect_end_time = + (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time; + + MockGLES2Decoder decoder; + EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext())); + GPUTracerTester tracer(&decoder); + tracer.SetTracingEnabled(true); + + tracer.SetOutputter(outputter_ref_); + + gl_fake_queries_.SetCurrentGLTime(start_timestamp); + g_fakeCPUTime = expect_start_time; + + ASSERT_TRUE(tracer.BeginDecoding()); + + ExpectTraceQueryMocks(); + + // This will test multiple marker sources which overlap one another. + for (int i = 0; i < NUM_TRACER_SOURCES; ++i) { + // Set times so each source has a different time. + gl_fake_queries_.SetCurrentGLTime( + start_timestamp + + (i * base::Time::kNanosecondsPerMicrosecond)); + g_fakeCPUTime = expect_start_time + i; + + // Each trace name should be different to differentiate. + const char num_char = static_cast<char>('0' + i); + std::string source_category = category_name + num_char; + std::string source_trace_name = trace_name + num_char; + + const GpuTracerSource source = static_cast<GpuTracerSource>(i); + ExpectOutputterBeginMocks(outputter_ref_.get(), source, + source_category, source_trace_name); + ASSERT_TRUE(tracer.Begin(source_category, source_trace_name, source)); + } + + for (int i = 0; i < NUM_TRACER_SOURCES; ++i) { + // Set times so each source has a different time. + gl_fake_queries_.SetCurrentGLTime( + end_timestamp + + (i * base::Time::kNanosecondsPerMicrosecond)); + g_fakeCPUTime = expect_end_time + i; + + // Each trace name should be different to differentiate. + const char num_char = static_cast<char>('0' + i); + std::string source_category = category_name + num_char; + std::string source_trace_name = trace_name + num_char; + + bool valid_timer = gpu_timing_client_->IsAvailable() && + gpu_timing_client_->IsTimerOffsetAvailable(); + + const GpuTracerSource source = static_cast<GpuTracerSource>(i); + ExpectOutputterEndMocks(outputter_ref_.get(), source, source_category, + source_trace_name, expect_start_time + i, + expect_end_time + i, valid_timer); + + // Check if the current category/name are correct for this source. + ASSERT_EQ(source_category, tracer.CurrentCategory(source)); + ASSERT_EQ(source_trace_name, tracer.CurrentName(source)); + + ASSERT_TRUE(tracer.End(source)); + } + + ASSERT_TRUE(tracer.EndDecoding()); + + outputter_ref_ = NULL; } - virtual void SetupTimerQueryMocks() { - // Delegate query APIs used by GPUTrace to a GlFakeQueries - EXPECT_CALL(*gl_, GenQueriesARB(_, NotNull())).Times(AtLeast(1)).WillOnce( - Invoke(&gl_fake_queries_, &GlFakeQueries::GenQueriesARB)); + void DoDisjointTest() { + // Cause a disjoint in a middle of a trace and expect no output calls. + ExpectTracerOffsetQueryMocks(); + + EXPECT_CALL(*gl_, GetError()).Times(AtLeast(0)) + .WillRepeatedly( + Invoke(&gl_fake_queries_, &GlFakeQueries::GetError)); + + const GpuTracerSource tracer_source = kTraceGroupMarker; + const std::string category_name("trace_category"); + const std::string trace_name("trace_test"); + const GpuTracerSource source = static_cast<GpuTracerSource>(0); + const int64 offset_time = 3231; + const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond; + const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond; + const int64 expect_start_time = + (start_timestamp / base::Time::kNanosecondsPerMicrosecond) + + offset_time; + const int64 expect_end_time = + (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time; + + MockGLES2Decoder decoder; + EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext())); + GPUTracerTester tracer(&decoder); + tracer.SetTracingEnabled(true); + + tracer.SetOutputter(outputter_ref_); + + gl_fake_queries_.SetCurrentGLTime(start_timestamp); + g_fakeCPUTime = expect_start_time; + + ASSERT_TRUE(tracer.BeginDecoding()); + + ExpectTraceQueryMocks(); + + ExpectOutputterBeginMocks(outputter_ref_.get(), tracer_source, + category_name, trace_name); + ASSERT_TRUE(tracer.Begin(category_name, trace_name, source)); + + gl_fake_queries_.SetCurrentGLTime(end_timestamp); + g_fakeCPUTime = expect_end_time; + + // Create GPUTimingClient to make sure disjoint value is correct. This + // should not interfere with the tracer's disjoint value. + scoped_refptr<gfx::GPUTimingClient> disjoint_client = + GetGLContext()->CreateGPUTimingClient(); - EXPECT_CALL(*gl_, GetQueryObjectiv(_, GL_QUERY_RESULT_AVAILABLE, NotNull())) - .Times(AtLeast(2)) - .WillRepeatedly( - Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectiv)); + // We assert here based on the disjoint_client because if disjoints are not + // working properly there is no point testing the tracer output. + ASSERT_FALSE(disjoint_client->CheckAndResetTimerErrors()); + gl_fake_queries_.SetDisjoint(); + ASSERT_TRUE(disjoint_client->CheckAndResetTimerErrors()); - EXPECT_CALL(*gl_, QueryCounter(_, GL_TIMESTAMP)) - .Times(AtLeast(2)) - .WillRepeatedly( - Invoke(&gl_fake_queries_, &GlFakeQueries::QueryCounter)); + ExpectOutputterEndMocks(outputter_ref_.get(), tracer_source, + category_name, trace_name, + expect_start_time, expect_end_time, false); - EXPECT_CALL(*gl_, GetQueryObjectui64v(_, GL_QUERY_RESULT, NotNull())) - .Times(AtLeast(2)) - .WillRepeatedly( - Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectui64v)); + ASSERT_TRUE(tracer.End(source)); + ASSERT_TRUE(tracer.EndDecoding()); - EXPECT_CALL(*gl_, DeleteQueriesARB(2, NotNull())) - .Times(AtLeast(1)) - .WillRepeatedly( - Invoke(&gl_fake_queries_, &GlFakeQueries::DeleteQueriesARB)); + outputter_ref_ = NULL; } +}; - virtual GpuTracerType GetTracerType() = 0; +class InvalidTimerTracerTest : public BaseGpuTracerTest { + public: + InvalidTimerTracerTest() + : BaseGpuTracerTest(gfx::GPUTiming::kTimerTypeInvalid) {} +}; - GlFakeQueries gl_fake_queries_; +class GpuEXTTimerTracerTest : public BaseGpuTracerTest { + public: + GpuEXTTimerTracerTest() : BaseGpuTracerTest(gfx::GPUTiming::kTimerTypeEXT) {} }; class GpuARBTimerTracerTest : public BaseGpuTracerTest { - protected: - GpuTracerType GetTracerType() override { return kTracerTypeARBTimer; } + public: + GpuARBTimerTracerTest() + : BaseGpuTracerTest(gfx::GPUTiming::kTimerTypeARB) {} }; class GpuDisjointTimerTracerTest : public BaseGpuTracerTest { - protected: - GpuTracerType GetTracerType() override { return kTracerTypeDisjointTimer; } + public: + GpuDisjointTimerTracerTest() + : BaseGpuTracerTest(gfx::GPUTiming::kTimerTypeDisjoint) {} }; -TEST_F(GpuARBTimerTracerTest, GPUTrace) { - // Test basic timer query functionality - { - DoTraceTest(); - } +TEST_F(InvalidTimerTracerTest, InvalidTimerBasicTracerTest) { + DoBasicTracerTest(); +} + +TEST_F(GpuEXTTimerTracerTest, EXTTimerBasicTracerTest) { + DoBasicTracerTest(); +} + +TEST_F(GpuARBTimerTracerTest, ARBTimerBasicTracerTest) { + DoBasicTracerTest(); +} + +TEST_F(GpuDisjointTimerTracerTest, DisjointTimerBasicTracerTest) { + DoBasicTracerTest(); +} + +TEST_F(InvalidTimerTracerTest, InvalidTimerTracerMarkersTest) { + DoTracerMarkersTest(); +} + +TEST_F(GpuEXTTimerTracerTest, EXTTimerTracerMarkersTest) { + DoTracerMarkersTest(); } -TEST_F(GpuDisjointTimerTracerTest, GPUTrace) { - // Test basic timer query functionality - { - DoTraceTest(); +TEST_F(GpuARBTimerTracerTest, ARBTimerBasicTracerMarkersTest) { + DoTracerMarkersTest(); +} + +TEST_F(GpuDisjointTimerTracerTest, DisjointTimerBasicTracerMarkersTest) { + DoTracerMarkersTest(); +} + +TEST_F(GpuDisjointTimerTracerTest, DisjointTimerDisjointTraceTest) { + DoDisjointTest(); +} + +class GPUTracerTest : public GpuServiceTest { + protected: + void SetUp() override { + g_fakeCPUTime = 0; + GpuServiceTest::SetUpWithGLVersion("3.2", ""); + decoder_.reset(new MockGLES2Decoder()); + EXPECT_CALL(*decoder_, GetGLContext()) + .Times(AtMost(1)) + .WillRepeatedly(Return(GetGLContext())); + tracer_tester_.reset(new GPUTracerTester(decoder_.get())); } + + void TearDown() override { + tracer_tester_ = nullptr; + decoder_ = nullptr; + GpuServiceTest::TearDown(); + } + scoped_ptr<MockGLES2Decoder> decoder_; + scoped_ptr<GPUTracerTester> tracer_tester_; +}; + +TEST_F(GPUTracerTest, IsTracingTest) { + EXPECT_FALSE(tracer_tester_->IsTracing()); + tracer_tester_->SetTracingEnabled(true); + EXPECT_TRUE(tracer_tester_->IsTracing()); +} +// Test basic functionality of the GPUTracerTester. +TEST_F(GPUTracerTest, DecodeTest) { + ASSERT_TRUE(tracer_tester_->BeginDecoding()); + EXPECT_FALSE(tracer_tester_->BeginDecoding()); + ASSERT_TRUE(tracer_tester_->EndDecoding()); + EXPECT_FALSE(tracer_tester_->EndDecoding()); +} + +TEST_F(GPUTracerTest, TraceDuringDecodeTest) { + const std::string category_name("trace_category"); + const std::string trace_name("trace_test"); + + EXPECT_FALSE( + tracer_tester_->Begin(category_name, trace_name, kTraceGroupMarker)); + + ASSERT_TRUE(tracer_tester_->BeginDecoding()); + EXPECT_TRUE( + tracer_tester_->Begin(category_name, trace_name, kTraceGroupMarker)); + ASSERT_TRUE(tracer_tester_->EndDecoding()); +} + +TEST_F(GpuDisjointTimerTracerTest, MultipleClientsDisjointTest) { + scoped_refptr<gfx::GPUTimingClient> client1 = + GetGLContext()->CreateGPUTimingClient(); + scoped_refptr<gfx::GPUTimingClient> client2 = + GetGLContext()->CreateGPUTimingClient(); + + // Test both clients are initialized as no errors. + ASSERT_FALSE(client1->CheckAndResetTimerErrors()); + ASSERT_FALSE(client2->CheckAndResetTimerErrors()); + + // Issue a disjoint. + gl_fake_queries_.SetDisjoint(); + + ASSERT_TRUE(client1->CheckAndResetTimerErrors()); + ASSERT_TRUE(client2->CheckAndResetTimerErrors()); + + // Test both are now reset. + ASSERT_FALSE(client1->CheckAndResetTimerErrors()); + ASSERT_FALSE(client2->CheckAndResetTimerErrors()); + + // Issue a disjoint. + gl_fake_queries_.SetDisjoint(); + + // Test new client disjoint value is cleared. + scoped_refptr<gfx::GPUTimingClient> client3 = + GetGLContext()->CreateGPUTimingClient(); + ASSERT_TRUE(client1->CheckAndResetTimerErrors()); + ASSERT_TRUE(client2->CheckAndResetTimerErrors()); + ASSERT_FALSE(client3->CheckAndResetTimerErrors()); } +} // namespace } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/image_factory.cc b/chromium/gpu/command_buffer/service/image_factory.cc index 0b740d8f32b..ce88f29ed61 100644 --- a/chromium/gpu/command_buffer/service/image_factory.cc +++ b/chromium/gpu/command_buffer/service/image_factory.cc @@ -4,6 +4,7 @@ #include "gpu/command_buffer/service/image_factory.h" +#include "gpu/command_buffer/common/capabilities.h" #include "ui/gl/gl_bindings.h" namespace gpu { @@ -18,10 +19,26 @@ ImageFactory::~ImageFactory() { gfx::GpuMemoryBuffer::Format ImageFactory::ImageFormatToGpuMemoryBufferFormat( unsigned internalformat) { switch (internalformat) { + case GL_R8: + return gfx::GpuMemoryBuffer::R_8; case GL_RGB: return gfx::GpuMemoryBuffer::RGBX_8888; case GL_RGBA: return gfx::GpuMemoryBuffer::RGBA_8888; + case GL_BGRA_EXT: + return gfx::GpuMemoryBuffer::BGRA_8888; + case GL_ATC_RGB_AMD: + return gfx::GpuMemoryBuffer::ATC; + case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: + return gfx::GpuMemoryBuffer::ATCIA; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return gfx::GpuMemoryBuffer::DXT1; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return gfx::GpuMemoryBuffer::DXT5; + case GL_ETC1_RGB8_OES: + return gfx::GpuMemoryBuffer::ETC1; + case GL_RGB_YUV_420_CHROMIUM: + return gfx::GpuMemoryBuffer::YUV_420; default: NOTREACHED(); return gfx::GpuMemoryBuffer::RGBA_8888; @@ -46,31 +63,62 @@ gfx::GpuMemoryBuffer::Usage ImageFactory::ImageUsageToGpuMemoryBufferUsage( bool ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat( unsigned internalformat, gfx::GpuMemoryBuffer::Format format) { - switch (internalformat) { - case GL_RGB: - switch (format) { - case gfx::GpuMemoryBuffer::RGBX_8888: - return true; - case gfx::GpuMemoryBuffer::RGBA_8888: - case gfx::GpuMemoryBuffer::BGRA_8888: - return false; - } - NOTREACHED(); - return false; - case GL_RGBA: - switch (format) { - case gfx::GpuMemoryBuffer::RGBX_8888: - return false; - case gfx::GpuMemoryBuffer::RGBA_8888: - case gfx::GpuMemoryBuffer::BGRA_8888: - return true; - } - NOTREACHED(); - return false; - default: - NOTREACHED(); - return false; + return ImageFormatToGpuMemoryBufferFormat(internalformat) == format; +} + +// static +bool ImageFactory::IsGpuMemoryBufferFormatSupported( + gfx::GpuMemoryBuffer::Format format, + const gpu::Capabilities& capabilities) { + switch (format) { + case gfx::GpuMemoryBuffer::ATC: + case gfx::GpuMemoryBuffer::ATCIA: + return capabilities.texture_format_atc; + case gfx::GpuMemoryBuffer::BGRA_8888: + return capabilities.texture_format_bgra8888; + case gfx::GpuMemoryBuffer::DXT1: + return capabilities.texture_format_dxt1; + case gfx::GpuMemoryBuffer::DXT5: + return capabilities.texture_format_dxt5; + case gfx::GpuMemoryBuffer::ETC1: + return capabilities.texture_format_etc1; + case gfx::GpuMemoryBuffer::R_8: + return capabilities.texture_rg; + case gfx::GpuMemoryBuffer::RGBA_8888: + case gfx::GpuMemoryBuffer::RGBX_8888: + case gfx::GpuMemoryBuffer::YUV_420: + return true; + } + + NOTREACHED(); + return false; +} + +// static +bool ImageFactory::IsImageSizeValidForGpuMemoryBufferFormat( + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format) { + switch (format) { + case gfx::GpuMemoryBuffer::ATC: + case gfx::GpuMemoryBuffer::ATCIA: + case gfx::GpuMemoryBuffer::DXT1: + case gfx::GpuMemoryBuffer::DXT5: + case gfx::GpuMemoryBuffer::ETC1: + // Compressed images must have a width and height that's evenly divisible + // by the block size. + return size.width() % 4 == 0 && size.height() % 4 == 0; + case gfx::GpuMemoryBuffer::R_8: + case gfx::GpuMemoryBuffer::RGBA_8888: + case gfx::GpuMemoryBuffer::BGRA_8888: + case gfx::GpuMemoryBuffer::RGBX_8888: + return true; + case gfx::GpuMemoryBuffer::YUV_420: + // U and V planes are subsampled by a factor of 2. + return size.width() % 2 == 0 && size.height() % 2 == 0; } + + NOTREACHED(); + return false; } } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/image_factory.h b/chromium/gpu/command_buffer/service/image_factory.h index 40dd15a0e61..b5813421945 100644 --- a/chromium/gpu/command_buffer/service/image_factory.h +++ b/chromium/gpu/command_buffer/service/image_factory.h @@ -15,6 +15,7 @@ class GLImage; } namespace gpu { +struct Capabilities; class GPU_EXPORT ImageFactory { public: @@ -35,6 +36,16 @@ class GPU_EXPORT ImageFactory { unsigned internalformat, gfx::GpuMemoryBuffer::Format format); + // Returns true if |format| is supported by |capabilities|. + static bool IsGpuMemoryBufferFormatSupported( + gfx::GpuMemoryBuffer::Format format, + const Capabilities& capabilities); + + // Returns true if |size| is valid for |format|. + static bool IsImageSizeValidForGpuMemoryBufferFormat( + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format); + // Creates a GLImage instance for GPU memory buffer identified by |handle|. // |client_id| should be set to the client requesting the creation of instance // and can be used by factory implementation to verify access rights. diff --git a/chromium/gpu/command_buffer/service/in_process_command_buffer.cc b/chromium/gpu/command_buffer/service/in_process_command_buffer.cc index 815b197e3b1..0b1ebb3c59f 100644 --- a/chromium/gpu/command_buffer/service/in_process_command_buffer.cc +++ b/chromium/gpu/command_buffer/service/in_process_command_buffer.cc @@ -12,13 +12,16 @@ #include "base/bind_helpers.h" #include "base/command_line.h" #include "base/lazy_instance.h" +#include "base/location.h" #include "base/logging.h" #include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop_proxy.h" #include "base/sequence_checker.h" +#include "base/single_thread_task_runner.h" #include "base/synchronization/condition_variable.h" +#include "base/thread_task_runner_handle.h" #include "base/threading/thread.h" #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" +#include "gpu/command_buffer/common/value_state.h" #include "gpu/command_buffer/service/command_buffer_service.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/gl_context_virtual.h" @@ -30,8 +33,10 @@ #include "gpu/command_buffer/service/mailbox_manager_sync.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "gpu/command_buffer/service/query_manager.h" +#include "gpu/command_buffer/service/sync_point_manager.h" #include "gpu/command_buffer/service/transfer_buffer_manager.h" -#include "ui/gfx/size.h" +#include "gpu/command_buffer/service/valuebuffer_manager.h" +#include "ui/gfx/geometry/size.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_image.h" #include "ui/gl/gl_share_group.h" @@ -41,6 +46,11 @@ #include "ui/gl/android/surface_texture.h" #endif +#if defined(OS_WIN) +#include <windows.h> +#include "base/process/process_handle.h" +#endif + namespace gpu { namespace { @@ -90,12 +100,13 @@ GpuInProcessThread::~GpuInProcessThread() { } void GpuInProcessThread::ScheduleTask(const base::Closure& task) { - message_loop()->PostTask(FROM_HERE, task); + task_runner()->PostTask(FROM_HERE, task); } void GpuInProcessThread::ScheduleIdleWork(const base::Closure& callback) { - message_loop()->PostDelayedTask( - FROM_HERE, callback, base::TimeDelta::FromMilliseconds(5)); + // Match delay with GpuCommandBufferStub. + task_runner()->PostDelayedTask(FROM_HERE, callback, + base::TimeDelta::FromMilliseconds(2)); } scoped_refptr<gles2::ShaderTranslatorCache> @@ -105,82 +116,143 @@ GpuInProcessThread::shader_translator_cache() { return shader_translator_cache_; } -base::LazyInstance<std::set<InProcessCommandBuffer*> > default_thread_clients_ = - LAZY_INSTANCE_INITIALIZER; -base::LazyInstance<base::Lock> default_thread_clients_lock_ = +struct GpuInProcessThreadHolder { + GpuInProcessThreadHolder() : gpu_thread(new GpuInProcessThread) {} + scoped_refptr<InProcessCommandBuffer::Service> gpu_thread; +}; + +base::LazyInstance<GpuInProcessThreadHolder> g_default_service = LAZY_INSTANCE_INITIALIZER; class ScopedEvent { public: - ScopedEvent(base::WaitableEvent* event) : event_(event) {} + explicit ScopedEvent(base::WaitableEvent* event) : event_(event) {} ~ScopedEvent() { event_->Signal(); } private: base::WaitableEvent* event_; }; -class SyncPointManager { +// This wrapper adds the WaitSyncPoint which allows waiting on a sync point +// on the service thread, implemented using a condition variable. +class SyncPointManagerWrapper { public: - SyncPointManager(); - ~SyncPointManager(); + SyncPointManagerWrapper(); uint32 GenerateSyncPoint(); void RetireSyncPoint(uint32 sync_point); + void AddSyncPointCallback(uint32 sync_point, const base::Closure& callback); - bool IsSyncPointPassed(uint32 sync_point); void WaitSyncPoint(uint32 sync_point); -private: - // This lock protects access to pending_sync_points_ and next_sync_point_ and - // is used with the ConditionVariable to signal when a sync point is retired. - base::Lock lock_; - std::set<uint32> pending_sync_points_; - uint32 next_sync_point_; - base::ConditionVariable cond_var_; -}; + private: + void OnSyncPointRetired(); + + const scoped_refptr<SyncPointManager> manager_; + base::Lock retire_lock_; + base::ConditionVariable retire_cond_var_; -SyncPointManager::SyncPointManager() : next_sync_point_(1), cond_var_(&lock_) {} + DISALLOW_COPY_AND_ASSIGN(SyncPointManagerWrapper); +}; -SyncPointManager::~SyncPointManager() { - DCHECK_EQ(pending_sync_points_.size(), 0U); +SyncPointManagerWrapper::SyncPointManagerWrapper() + : manager_(SyncPointManager::Create(true)), + retire_cond_var_(&retire_lock_) { } -uint32 SyncPointManager::GenerateSyncPoint() { - base::AutoLock lock(lock_); - uint32 sync_point = next_sync_point_++; - DCHECK_EQ(pending_sync_points_.count(sync_point), 0U); - pending_sync_points_.insert(sync_point); +uint32 SyncPointManagerWrapper::GenerateSyncPoint() { + uint32 sync_point = manager_->GenerateSyncPoint(); + manager_->AddSyncPointCallback( + sync_point, base::Bind(&SyncPointManagerWrapper::OnSyncPointRetired, + base::Unretained(this))); return sync_point; } -void SyncPointManager::RetireSyncPoint(uint32 sync_point) { - base::AutoLock lock(lock_); - DCHECK(pending_sync_points_.count(sync_point)); - pending_sync_points_.erase(sync_point); - cond_var_.Broadcast(); +void SyncPointManagerWrapper::RetireSyncPoint(uint32 sync_point) { + manager_->RetireSyncPoint(sync_point); } -bool SyncPointManager::IsSyncPointPassed(uint32 sync_point) { - base::AutoLock lock(lock_); - return pending_sync_points_.count(sync_point) == 0; +void SyncPointManagerWrapper::AddSyncPointCallback( + uint32 sync_point, + const base::Closure& callback) { + manager_->AddSyncPointCallback(sync_point, callback); } -void SyncPointManager::WaitSyncPoint(uint32 sync_point) { - base::AutoLock lock(lock_); - while (pending_sync_points_.count(sync_point)) { - cond_var_.Wait(); +void SyncPointManagerWrapper::WaitSyncPoint(uint32 sync_point) { + base::AutoLock lock(retire_lock_); + while (!manager_->IsSyncPointRetired(sync_point)) { + retire_cond_var_.Wait(); } } -base::LazyInstance<SyncPointManager> g_sync_point_manager = +void SyncPointManagerWrapper::OnSyncPointRetired() { + base::AutoLock lock(retire_lock_); + retire_cond_var_.Broadcast(); +} + +base::LazyInstance<SyncPointManagerWrapper> g_sync_point_manager = LAZY_INSTANCE_INITIALIZER; +base::SharedMemoryHandle ShareToGpuThread( + base::SharedMemoryHandle source_handle) { +#if defined(OS_WIN) + // Windows needs to explicitly duplicate the handle to current process. + base::SharedMemoryHandle target_handle; + if (!DuplicateHandle(GetCurrentProcess(), + source_handle, + GetCurrentProcess(), + &target_handle, + FILE_GENERIC_READ | FILE_GENERIC_WRITE, + FALSE, + 0)) { + return base::SharedMemory::NULLHandle(); + } + + return target_handle; +#else + int duped_handle = HANDLE_EINTR(dup(source_handle.fd)); + if (duped_handle < 0) + return base::SharedMemory::NULLHandle(); + + return base::FileDescriptor(duped_handle, true); +#endif +} + +gfx::GpuMemoryBufferHandle ShareGpuMemoryBufferToGpuThread( + const gfx::GpuMemoryBufferHandle& source_handle, + bool* requires_sync_point) { + switch (source_handle.type) { + case gfx::SHARED_MEMORY_BUFFER: { + gfx::GpuMemoryBufferHandle handle; + handle.type = gfx::SHARED_MEMORY_BUFFER; + handle.handle = ShareToGpuThread(source_handle.handle); + *requires_sync_point = false; + return handle; + } + case gfx::IO_SURFACE_BUFFER: + case gfx::SURFACE_TEXTURE_BUFFER: + case gfx::OZONE_NATIVE_BUFFER: + *requires_sync_point = true; + return source_handle; + default: + NOTREACHED(); + return gfx::GpuMemoryBufferHandle(); + } +} + } // anonyous namespace InProcessCommandBuffer::Service::Service() {} InProcessCommandBuffer::Service::~Service() {} +scoped_refptr<gfx::GLShareGroup> +InProcessCommandBuffer::Service::share_group() { + if (!share_group_.get()) + share_group_ = new gfx::GLShareGroup; + return share_group_; +} + scoped_refptr<gles2::MailboxManager> InProcessCommandBuffer::Service::mailbox_manager() { if (!mailbox_manager_.get()) { @@ -194,18 +266,20 @@ InProcessCommandBuffer::Service::mailbox_manager() { return mailbox_manager_; } -scoped_refptr<InProcessCommandBuffer::Service> -InProcessCommandBuffer::GetDefaultService() { - base::AutoLock lock(default_thread_clients_lock_.Get()); - scoped_refptr<Service> service; - if (!default_thread_clients_.Get().empty()) { - InProcessCommandBuffer* other = *default_thread_clients_.Get().begin(); - service = other->service_; - DCHECK(service.get()); - } else { - service = new GpuInProcessThread; +scoped_refptr<gles2::SubscriptionRefSet> +InProcessCommandBuffer::Service::subscription_ref_set() { + if (!subscription_ref_set_.get()) { + subscription_ref_set_ = new gles2::SubscriptionRefSet(); } - return service; + return subscription_ref_set_; +} + +scoped_refptr<ValueStateMap> +InProcessCommandBuffer::Service::pending_valuebuffer_state() { + if (!pending_valuebuffer_state_.get()) { + pending_valuebuffer_state_ = new ValueStateMap(); + } + return pending_valuebuffer_state_; } InProcessCommandBuffer::InProcessCommandBuffer( @@ -216,19 +290,14 @@ InProcessCommandBuffer::InProcessCommandBuffer( last_put_offset_(-1), gpu_memory_buffer_manager_(nullptr), flush_event_(false, false), - service_(service.get() ? service : GetDefaultService()), + service_(service.get() ? service : g_default_service.Get().gpu_thread), gpu_thread_weak_ptr_factory_(this) { - if (!service.get()) { - base::AutoLock lock(default_thread_clients_lock_.Get()); - default_thread_clients_.Get().insert(this); - } + DCHECK(service_.get()); next_image_id_.GetNext(); } InProcessCommandBuffer::~InProcessCommandBuffer() { Destroy(); - base::AutoLock lock(default_thread_clients_lock_.Get()); - default_thread_clients_.Get().erase(this); } void InProcessCommandBuffer::OnResizeView(gfx::Size size, float scale_factor) { @@ -343,8 +412,8 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( } gl_share_group_ = params.context_group - ? params.context_group->gl_share_group_.get() - : new gfx::GLShareGroup; + ? params.context_group->gl_share_group_ + : service_->share_group(); #if defined(OS_ANDROID) stream_texture_manager_.reset(new StreamTextureManagerInProcess); @@ -358,6 +427,8 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( NULL, service_->shader_translator_cache(), NULL, + service_->subscription_ref_set(), + service_->pending_valuebuffer_state(), bind_generates_resource))); gpu_scheduler_.reset( @@ -381,7 +452,11 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( return false; } - if (service_->UseVirtualizedGLContexts()) { + if (service_->UseVirtualizedGLContexts() || + decoder_->GetContextGroup() + ->feature_info() + ->workarounds() + .use_virtualized_gl_contexts) { context_ = gl_share_group_->GetSharedContext(); if (!context_.get()) { context_ = gfx::GLContext::CreateGLContext( @@ -563,6 +638,10 @@ void InProcessCommandBuffer::Flush(int32 put_offset) { QueueTask(task); } +void InProcessCommandBuffer::OrderingBarrier(int32 put_offset) { + Flush(put_offset); +} + void InProcessCommandBuffer::WaitForTokenInRange(int32 start, int32 end) { CheckSequencedThread(); while (!InRange(start, end, GetLastToken()) && @@ -636,15 +715,32 @@ int32 InProcessCommandBuffer::CreateImage(ClientBuffer buffer, int32 new_id = next_image_id_.GetNext(); + DCHECK(gpu::ImageFactory::IsGpuMemoryBufferFormatSupported( + gpu_memory_buffer->GetFormat(), capabilities_)); DCHECK(gpu::ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat( internalformat, gpu_memory_buffer->GetFormat())); + + // This handle is owned by the GPU thread and must be passed to it or it + // will leak. In otherwords, do not early out on error between here and the + // queuing of the CreateImage task below. + bool requires_sync_point = false; + gfx::GpuMemoryBufferHandle handle = + ShareGpuMemoryBufferToGpuThread(gpu_memory_buffer->GetHandle(), + &requires_sync_point); + QueueTask(base::Bind(&InProcessCommandBuffer::CreateImageOnGpuThread, base::Unretained(this), new_id, - gpu_memory_buffer->GetHandle(), + handle, gfx::Size(width, height), gpu_memory_buffer->GetFormat(), internalformat)); + + if (requires_sync_point) { + gpu_memory_buffer_manager_->SetDestructionSyncPoint(gpu_memory_buffer, + InsertSyncPoint()); + } + return new_id; } @@ -771,15 +867,7 @@ bool InProcessCommandBuffer::WaitSyncPointOnGpuThread(unsigned sync_point) { void InProcessCommandBuffer::SignalSyncPointOnGpuThread( unsigned sync_point, const base::Closure& callback) { - if (g_sync_point_manager.Get().IsSyncPointPassed(sync_point)) { - callback.Run(); - } else { - service_->ScheduleIdleWork( - base::Bind(&InProcessCommandBuffer::SignalSyncPointOnGpuThread, - gpu_thread_weak_ptr_, - sync_point, - callback)); - } + g_sync_point_manager.Get().AddSyncPointCallback(sync_point, callback); } void InProcessCommandBuffer::SignalQuery(unsigned query_id, @@ -819,6 +907,9 @@ uint32 InProcessCommandBuffer::CreateStreamTexture(uint32 texture_id) { return stream_id; } +void InProcessCommandBuffer::SetLock(base::Lock*) { +} + uint32 InProcessCommandBuffer::CreateStreamTextureOnGpuThread( uint32 client_texture_id) { #if defined(OS_ANDROID) @@ -841,12 +932,13 @@ bool InProcessCommandBuffer::Initialize() { namespace { -void PostCallback(const scoped_refptr<base::MessageLoopProxy>& loop, - const base::Closure& callback) { - // The loop.get() check is to support using InProcessCommandBuffer on a thread - // without a message loop. - if (loop.get() && !loop->BelongsToCurrentThread()) { - loop->PostTask(FROM_HERE, callback); +void PostCallback( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + const base::Closure& callback) { + // The task_runner.get() check is to support using InProcessCommandBuffer on + // a thread without a message loop. + if (task_runner.get() && !task_runner->BelongsToCurrentThread()) { + task_runner->PostTask(FROM_HERE, callback); } else { callback.Run(); } @@ -867,7 +959,9 @@ base::Closure InProcessCommandBuffer::WrapCallback( base::Closure callback_on_client_thread = base::Bind(&RunOnTargetThread, base::Passed(&scoped_callback)); base::Closure wrapped_callback = - base::Bind(&PostCallback, base::MessageLoopProxy::current(), + base::Bind(&PostCallback, base::ThreadTaskRunnerHandle::IsSet() + ? base::ThreadTaskRunnerHandle::Get() + : nullptr, callback_on_client_thread); return wrapped_callback; } diff --git a/chromium/gpu/command_buffer/service/in_process_command_buffer.h b/chromium/gpu/command_buffer/service/in_process_command_buffer.h index cb1ab289999..b3f6eb806d7 100644 --- a/chromium/gpu/command_buffer/service/in_process_command_buffer.h +++ b/chromium/gpu/command_buffer/service/in_process_command_buffer.h @@ -46,11 +46,13 @@ class StreamTextureManagerInProcess; #endif namespace gpu { +class ValueStateMap; namespace gles2 { class GLES2Decoder; class MailboxManager; class ShaderTranslatorCache; +class SubscriptionRefSet; } class CommandBufferServiceBase; @@ -90,6 +92,7 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, State GetLastState() override; int32 GetLastToken() override; void Flush(int32 put_offset) override; + void OrderingBarrier(int32 put_offset) override; void WaitForTokenInRange(int32 start, int32 end) override; void WaitForGetOffsetInRange(int32 start, int32 end) override; void SetGetBuffer(int32 shm_id) override; @@ -117,6 +120,7 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, void SignalQuery(uint32 query_id, const base::Closure& callback) override; void SetSurfaceVisible(bool visible) override; uint32 CreateStreamTexture(uint32 texture_id) override; + void SetLock(base::Lock*) override; // The serializer interface to the GPU service (i.e. thread). class Service { @@ -137,10 +141,16 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, virtual bool UseVirtualizedGLContexts() = 0; virtual scoped_refptr<gles2::ShaderTranslatorCache> shader_translator_cache() = 0; + scoped_refptr<gfx::GLShareGroup> share_group(); scoped_refptr<gles2::MailboxManager> mailbox_manager(); + scoped_refptr<gles2::SubscriptionRefSet> subscription_ref_set(); + scoped_refptr<gpu::ValueStateMap> pending_valuebuffer_state(); private: + scoped_refptr<gfx::GLShareGroup> share_group_; scoped_refptr<gles2::MailboxManager> mailbox_manager_; + scoped_refptr<gles2::SubscriptionRefSet> subscription_ref_set_; + scoped_refptr<gpu::ValueStateMap> pending_valuebuffer_state_; }; #if defined(OS_ANDROID) @@ -207,8 +217,6 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, void PumpCommands(); void PerformIdleWork(); - static scoped_refptr<Service> GetDefaultService(); - // Members accessed on the gpu thread (possibly with the exception of // creation): bool context_lost_; diff --git a/chromium/gpu/command_buffer/service/logger.cc b/chromium/gpu/command_buffer/service/logger.cc index 1fd29336d7b..d8311f10dc3 100644 --- a/chromium/gpu/command_buffer/service/logger.cc +++ b/chromium/gpu/command_buffer/service/logger.cc @@ -27,7 +27,7 @@ Logger::~Logger() {} void Logger::LogMessage( const char* filename, int line, const std::string& msg) { if (log_message_count_ < kMaxLogMessages || - CommandLine::ForCurrentProcess()->HasSwitch( + base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableGLErrorLimit)) { std::string prefixed_msg(std::string("[") + GetLogPrefix() + "]" + msg); ++log_message_count_; diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_sync.cc b/chromium/gpu/command_buffer/service/mailbox_manager_sync.cc index 65376afdf87..be12b3a8fe8 100644 --- a/chromium/gpu/command_buffer/service/mailbox_manager_sync.cc +++ b/chromium/gpu/command_buffer/service/mailbox_manager_sync.cc @@ -22,23 +22,6 @@ namespace gles2 { namespace { -bool SkipTextureWorkarounds(const Texture* texture) { - // TODO(sievers): crbug.com/352274 - // Should probably only fail if it already *has* mipmaps, while allowing - // incomplete textures here. - bool needs_mips = - texture->min_filter() != GL_NEAREST && texture->min_filter() != GL_LINEAR; - if (texture->target() != GL_TEXTURE_2D || needs_mips || !texture->IsDefined()) - return true; - - // Skip compositor resources/tile textures. - // TODO: Remove this, see crbug.com/399226. - if (texture->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM) - return true; - - return false; -} - base::LazyInstance<base::Lock> g_lock = LAZY_INSTANCE_INITIALIZER; typedef std::map<uint32, linked_ptr<gfx::GLFence>> SyncPointToFenceMap; @@ -64,7 +47,7 @@ void CreateFenceLocked(uint32 sync_point) { sync_points.pop(); } // Need to use EGL fences since we are likely not in a single share group. - linked_ptr<gfx::GLFence> fence(make_linked_ptr(new gfx::GLFenceEGL(true))); + linked_ptr<gfx::GLFence> fence(make_linked_ptr(new gfx::GLFenceEGL)); if (fence.get()) { std::pair<SyncPointToFenceMap::iterator, bool> result = sync_point_to_fence.insert(std::make_pair(sync_point, fence)); @@ -94,21 +77,6 @@ base::LazyInstance<MailboxManagerSync::TextureGroup::MailboxToGroupMap> LAZY_INSTANCE_INITIALIZER; // static -MailboxManagerSync::TextureGroup* -MailboxManagerSync::TextureGroup::CreateFromTexture(const Mailbox& name, - MailboxManagerSync* manager, - Texture* texture) { - TextureGroup* group = new TextureGroup(); - group->AddTexture(manager, texture); - group->AddName(name); - if (!SkipTextureWorkarounds(texture)) { - group->definition_ = - TextureDefinition(texture, kNewTextureVersion, NULL); - } - return group; -} - -// static MailboxManagerSync::TextureGroup* MailboxManagerSync::TextureGroup::FromName( const Mailbox& name) { MailboxToGroupMap::iterator it = mailbox_to_group_.Get().find(name); @@ -118,7 +86,9 @@ MailboxManagerSync::TextureGroup* MailboxManagerSync::TextureGroup::FromName( return it->second.get(); } -MailboxManagerSync::TextureGroup::TextureGroup() { +MailboxManagerSync::TextureGroup::TextureGroup( + const TextureDefinition& definition) + : definition_(definition) { } MailboxManagerSync::TextureGroup::~TextureGroup() { @@ -201,6 +171,15 @@ MailboxManagerSync::~MailboxManagerSync() { DCHECK_EQ(0U, texture_to_group_.size()); } +// static +bool MailboxManagerSync::SkipTextureWorkarounds(const Texture* texture) { + // Cannot support mips due to support mismatch between + // EGL_KHR_gl_texture_2D_image and glEGLImageTargetTexture2DOES for + // texture levels. + bool has_mips = texture->NeedsMips() && texture->texture_complete(); + return texture->target() != GL_TEXTURE_2D || has_mips; +} + bool MailboxManagerSync::UsesSync() { return true; } @@ -258,8 +237,14 @@ void MailboxManagerSync::ProduceTexture(const Mailbox& mailbox, } else { // This is a new texture, so create a new group. texture->SetMailboxManager(this); - group_for_texture = - TextureGroup::CreateFromTexture(mailbox, this, texture); + TextureDefinition definition; + if (!SkipTextureWorkarounds(texture)) { + base::AutoUnlock unlock(g_lock.Get()); + definition = TextureDefinition(texture, kNewTextureVersion, NULL); + } + group_for_texture = new TextureGroup(definition); + group_for_texture->AddTexture(this, texture); + group_for_texture->AddName(mailbox); texture_to_group_.insert(std::make_pair( texture, TextureGroupRef(kNewTextureVersion, group_for_texture))); } @@ -299,6 +284,7 @@ void MailboxManagerSync::UpdateDefinitionLocked( if (definition.Matches(texture)) return; + DCHECK_IMPLIES(gl_image, image_buffer.get()); if (gl_image && !image_buffer->IsClient(gl_image)) { LOG(ERROR) << "MailboxSync: Incompatible attachment"; return; @@ -319,19 +305,30 @@ void MailboxManagerSync::PushTextureUpdates(uint32 sync_point) { } void MailboxManagerSync::PullTextureUpdates(uint32 sync_point) { - base::AutoLock lock(g_lock.Get()); - AcquireFenceLocked(sync_point); + using TextureUpdatePair = std::pair<Texture*, TextureDefinition>; + std::vector<TextureUpdatePair> needs_update; + { + base::AutoLock lock(g_lock.Get()); + AcquireFenceLocked(sync_point); + + for (TextureToGroupMap::iterator it = texture_to_group_.begin(); + it != texture_to_group_.end(); it++) { + const TextureDefinition& definition = it->second.group->GetDefinition(); + Texture* texture = it->first; + unsigned& texture_version = it->second.version; + if (texture_version == definition.version() || + definition.IsOlderThan(texture_version)) + continue; + texture_version = definition.version(); + needs_update.push_back(TextureUpdatePair(texture, definition)); + } + } - for (TextureToGroupMap::iterator it = texture_to_group_.begin(); - it != texture_to_group_.end(); it++) { - const TextureDefinition& definition = it->second.group->GetDefinition(); - Texture* texture = it->first; - unsigned& texture_version = it->second.version; - if (texture_version == definition.version() || - definition.IsOlderThan(texture_version)) - continue; - texture_version = definition.version(); - definition.UpdateTexture(texture); + if (!needs_update.empty()) { + ScopedUpdateTexture scoped_update_texture; + for (const TextureUpdatePair& pair : needs_update) { + pair.second.UpdateTexture(pair.first); + } } } diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_sync.h b/chromium/gpu/command_buffer/service/mailbox_manager_sync.h index 4727f3babb7..481948ee8d5 100644 --- a/chromium/gpu/command_buffer/service/mailbox_manager_sync.h +++ b/chromium/gpu/command_buffer/service/mailbox_manager_sync.h @@ -40,13 +40,13 @@ class GPU_EXPORT MailboxManagerSync : public MailboxManager { private: friend class base::RefCounted<MailboxManager>; + static bool SkipTextureWorkarounds(const Texture* texture); + ~MailboxManagerSync() override; class TextureGroup : public base::RefCounted<TextureGroup> { public: - static TextureGroup* CreateFromTexture(const Mailbox& name, - MailboxManagerSync* manager, - Texture* texture); + explicit TextureGroup(const TextureDefinition& definition); static TextureGroup* FromName(const Mailbox& name); void AddName(const Mailbox& name); @@ -64,7 +64,6 @@ class GPU_EXPORT MailboxManagerSync : public MailboxManager { private: friend class base::RefCounted<TextureGroup>; - TextureGroup(); ~TextureGroup(); typedef std::vector<std::pair<MailboxManagerSync*, Texture*>> TextureList; diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_unittest.cc b/chromium/gpu/command_buffer/service/mailbox_manager_unittest.cc index 231193f1926..0e064d4b488 100644 --- a/chromium/gpu/command_buffer/service/mailbox_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/mailbox_manager_unittest.cc @@ -72,6 +72,13 @@ class MailboxManagerTest : public GpuServiceTest { cleared); } + void SetLevelCleared(Texture* texture, + GLenum target, + GLint level, + bool cleared) { + texture->SetLevelCleared(target, level, cleared); + } + GLenum SetParameter(Texture* texture, GLenum pname, GLint param) { return texture->SetParameteri(feature_info_.get(), pname, param); } @@ -247,10 +254,10 @@ class MailboxManagerSyncTest : public MailboxManagerTest { EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, Flush()) + EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kCurrentTexture)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kCurrentTexture)) + EXPECT_CALL(*gl_, Flush()) .Times(1) .RetiresOnSaturation(); } @@ -365,7 +372,7 @@ TEST_F(MailboxManagerSyncTest, ProduceConsumeResize) { kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); manager2_->PullTextureUpdates(0); GLsizei width, height; - new_texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height); + new_texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr); EXPECT_EQ(16, width); EXPECT_EQ(32, height); @@ -394,7 +401,7 @@ TEST_F(MailboxManagerSyncTest, ProduceConsumeResize) { // The last change to the texture should be visible without a sync point (i.e. // push). manager2_->PullTextureUpdates(0); - new_texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height); + new_texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr); EXPECT_EQ(64, width); EXPECT_EQ(64, height); @@ -543,6 +550,111 @@ TEST_F(MailboxManagerSyncTest, ProduceAndClobber) { EXPECT_EQ(NULL, manager2_->ConsumeTexture(name)); } +TEST_F(MailboxManagerSyncTest, ClearedStateSynced) { + const GLuint kNewTextureId = 1234; + + Texture* texture = DefineTexture(); + EXPECT_TRUE(texture->SafeToRenderFrom()); + + Mailbox name = Mailbox::Generate(); + + manager_->ProduceTexture(name, texture); + EXPECT_EQ(texture, manager_->ConsumeTexture(name)); + + // Synchronize + manager_->PushTextureUpdates(0); + manager2_->PullTextureUpdates(0); + + EXPECT_CALL(*gl_, GenTextures(1, _)) + .WillOnce(SetArgPointee<1>(kNewTextureId)); + SetupUpdateTexParamExpectations( + kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); + Texture* new_texture = manager2_->ConsumeTexture(name); + EXPECT_FALSE(new_texture == NULL); + EXPECT_NE(texture, new_texture); + EXPECT_EQ(kNewTextureId, new_texture->service_id()); + EXPECT_TRUE(texture->SafeToRenderFrom()); + + // Change cleared to false. + SetLevelCleared(texture, texture->target(), 0, false); + EXPECT_FALSE(texture->SafeToRenderFrom()); + + // Synchronize + manager_->PushTextureUpdates(0); + SetupUpdateTexParamExpectations( + kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); + manager2_->PullTextureUpdates(0); + + // Cleared state should be synced. + EXPECT_FALSE(new_texture->SafeToRenderFrom()); + + DestroyTexture(texture); + DestroyTexture(new_texture); + + EXPECT_EQ(NULL, manager_->ConsumeTexture(name)); + EXPECT_EQ(NULL, manager2_->ConsumeTexture(name)); +} + +TEST_F(MailboxManagerSyncTest, SyncIncompleteTexture) { + const GLuint kNewTextureId = 1234; + + // Create but not define texture. + Texture* texture = CreateTexture(); + SetTarget(texture, GL_TEXTURE_2D, 1); + EXPECT_FALSE(texture->IsDefined()); + + Mailbox name = Mailbox::Generate(); + manager_->ProduceTexture(name, texture); + EXPECT_EQ(texture, manager_->ConsumeTexture(name)); + + // Synchronize + manager_->PushTextureUpdates(0); + manager2_->PullTextureUpdates(0); + + // Should sync to new texture which is not defined. + EXPECT_CALL(*gl_, GenTextures(1, _)) + .WillOnce(SetArgPointee<1>(kNewTextureId)); + SetupUpdateTexParamExpectations(kNewTextureId, texture->min_filter(), + texture->mag_filter(), texture->wrap_s(), + texture->wrap_t()); + Texture* new_texture = manager2_->ConsumeTexture(name); + ASSERT_TRUE(new_texture); + EXPECT_NE(texture, new_texture); + EXPECT_EQ(kNewTextureId, new_texture->service_id()); + EXPECT_FALSE(new_texture->IsDefined()); + + // Change cleared to false. + SetLevelInfo(texture, + GL_TEXTURE_2D, + 0, + GL_RGBA, + 1, + 1, + 1, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + true); + SetParameter(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + SetParameter(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + EXPECT_TRUE(texture->IsDefined()); + + // Synchronize + manager_->PushTextureUpdates(0); + SetupUpdateTexParamExpectations( + kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); + manager2_->PullTextureUpdates(0); + + // Cleared state should be synced. + EXPECT_TRUE(new_texture->IsDefined()); + + DestroyTexture(texture); + DestroyTexture(new_texture); + + EXPECT_EQ(NULL, manager_->ConsumeTexture(name)); + EXPECT_EQ(NULL, manager2_->ConsumeTexture(name)); +} + // Putting the same texture into multiple mailboxes should result in sharing // only a single texture also within a synchronized manager instance. TEST_F(MailboxManagerSyncTest, SharedThroughMultipleMailboxes) { @@ -619,8 +731,6 @@ TEST_F(MailboxManagerSyncTest, ProduceBothWays) { DestroyTexture(new_texture); } -// TODO: Produce incomplete texture - // TODO: Texture::level_infos_[][].size() // TODO: unsupported targets and formats diff --git a/chromium/gpu/command_buffer/service/memory_program_cache.cc b/chromium/gpu/command_buffer/service/memory_program_cache.cc index 86fffd38164..cf3b0ca7d8d 100644 --- a/chromium/gpu/command_buffer/service/memory_program_cache.cc +++ b/chromium/gpu/command_buffer/service/memory_program_cache.cc @@ -15,13 +15,13 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/shader_manager.h" -#include "gpu/command_buffer/service/shader_translator.h" #include "ui/gl/gl_bindings.h" namespace { size_t GetCacheSizeBytes() { - const CommandLine* command_line = CommandLine::ForCurrentProcess(); + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kGpuProgramCacheSizeKb)) { size_t size; if (base::StringToSizeT( @@ -172,24 +172,26 @@ void MemoryProgramCache::ClearBackend() { ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( GLuint program, Shader* shader_a, - const ShaderTranslatorInterface* translator_a, Shader* shader_b, - const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode, const ShaderCacheCallback& shader_callback) { char a_sha[kHashLength]; char b_sha[kHashLength]; - DCHECK(shader_a && !shader_a->signature_source().empty() && - shader_b && !shader_b->signature_source().empty()); + DCHECK(shader_a && !shader_a->last_compiled_source().empty() && + shader_b && !shader_b->last_compiled_source().empty()); ComputeShaderHash( - shader_a->signature_source(), translator_a, a_sha); + shader_a->last_compiled_signature(), a_sha); ComputeShaderHash( - shader_b->signature_source(), translator_b, b_sha); + shader_b->last_compiled_signature(), b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, b_sha, bind_attrib_location_map, + transform_feedback_varyings, + transform_feedback_buffer_mode, sha); const std::string sha_string(sha, kHashLength); @@ -215,7 +217,7 @@ ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( shader_b->set_varying_map(value->varying_map_1()); if (!shader_callback.is_null() && - !CommandLine::ForCurrentProcess()->HasSwitch( + !base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableGpuShaderDiskCache)) { scoped_ptr<GpuProgramProto> proto( GpuProgramProto::default_instance().New()); @@ -234,10 +236,10 @@ ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( void MemoryProgramCache::SaveLinkedProgram( GLuint program, const Shader* shader_a, - const ShaderTranslatorInterface* translator_a, const Shader* shader_b, - const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode, const ShaderCacheCallback& shader_callback) { GLenum format; GLsizei length = 0; @@ -255,17 +257,19 @@ void MemoryProgramCache::SaveLinkedProgram( char a_sha[kHashLength]; char b_sha[kHashLength]; - DCHECK(shader_a && !shader_a->signature_source().empty() && - shader_b && !shader_b->signature_source().empty()); + DCHECK(shader_a && !shader_a->last_compiled_source().empty() && + shader_b && !shader_b->last_compiled_source().empty()); ComputeShaderHash( - shader_a->signature_source(), translator_a, a_sha); + shader_a->last_compiled_signature(), a_sha); ComputeShaderHash( - shader_b->signature_source(), translator_b, b_sha); + shader_b->last_compiled_signature(), b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, b_sha, bind_attrib_location_map, + transform_feedback_varyings, + transform_feedback_buffer_mode, sha); const std::string sha_string(sha, sizeof(sha)); @@ -284,7 +288,7 @@ void MemoryProgramCache::SaveLinkedProgram( } if (!shader_callback.is_null() && - !CommandLine::ForCurrentProcess()->HasSwitch( + !base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableGpuShaderDiskCache)) { scoped_ptr<GpuProgramProto> proto( GpuProgramProto::default_instance().New()); diff --git a/chromium/gpu/command_buffer/service/memory_program_cache.h b/chromium/gpu/command_buffer/service/memory_program_cache.h index 7560d01bc12..593625daa9c 100644 --- a/chromium/gpu/command_buffer/service/memory_program_cache.h +++ b/chromium/gpu/command_buffer/service/memory_program_cache.h @@ -14,7 +14,6 @@ #include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/program_cache.h" -#include "gpu/command_buffer/service/shader_translator.h" namespace gpu { namespace gles2 { @@ -29,18 +28,19 @@ class GPU_EXPORT MemoryProgramCache : public ProgramCache { ProgramLoadResult LoadLinkedProgram( GLuint program, Shader* shader_a, - const ShaderTranslatorInterface* translator_a, Shader* shader_b, - const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode, + const ShaderCacheCallback& shader_callback) override; + void SaveLinkedProgram( + GLuint program, + const Shader* shader_a, + const Shader* shader_b, + const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode, const ShaderCacheCallback& shader_callback) override; - void SaveLinkedProgram(GLuint program, - const Shader* shader_a, - const ShaderTranslatorInterface* translator_a, - const Shader* shader_b, - const ShaderTranslatorInterface* translator_b, - const LocationMap* bind_attrib_location_map, - const ShaderCacheCallback& shader_callback) override; void LoadProgram(const std::string& program) override; diff --git a/chromium/gpu/command_buffer/service/memory_program_cache_unittest.cc b/chromium/gpu/command_buffer/service/memory_program_cache_unittest.cc index d3e954e2adf..7a22eac3fd8 100644 --- a/chromium/gpu/command_buffer/service/memory_program_cache_unittest.cc +++ b/chromium/gpu/command_buffer/service/memory_program_cache_unittest.cc @@ -16,10 +16,8 @@ #include "ui/gl/gl_mock.h" using ::testing::_; -using ::testing::ElementsAreArray; using ::testing::Invoke; using ::testing::SetArgPointee; -using ::testing::SetArrayArgument; namespace gpu { namespace gles2 { @@ -88,7 +86,7 @@ class MemoryProgramCacheTest : public GpuServiceTest { protected: void SetUp() override { - GpuServiceTest::SetUp(); + GpuServiceTest::SetUpWithGLVersion("3.0", "GL_ARB_get_program_binary"); vertex_shader_ = shader_manager_.CreateShader(kVertexShaderClientId, kVertexShaderServiceId, @@ -125,11 +123,11 @@ class MemoryProgramCacheTest : public GpuServiceTest { fragment_shader_->set_source("bbbal sldkdkdkas 134 ad"); TestHelper::SetShaderStates( - gl_.get(), vertex_shader_, true, NULL, NULL, + gl_.get(), vertex_shader_, true, NULL, NULL, NULL, &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map, NULL); TestHelper::SetShaderStates( - gl_.get(), fragment_shader_, true, NULL, NULL, + gl_.get(), fragment_shader_, true, NULL, NULL, NULL, &fragment_attrib_map, &fragment_uniform_map, &fragment_varying_map, NULL); } @@ -179,6 +177,7 @@ class MemoryProgramCacheTest : public GpuServiceTest { Shader* fragment_shader_; int32 shader_cache_count_; std::string shader_cache_shader_; + std::vector<std::string> varyings_; }; TEST_F(MemoryProgramCacheTest, CacheSave) { @@ -192,17 +191,15 @@ TEST_F(MemoryProgramCacheTest, CacheSave) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, - fragment_shader_, NULL, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + fragment_shader_, NULL, varyings_, GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), - NULL, - fragment_shader_->signature_source(), - NULL, - NULL)); + vertex_shader_->last_compiled_signature(), + fragment_shader_->last_compiled_signature(), + NULL, varyings_, GL_NONE)); EXPECT_EQ(1, shader_cache_count()); } @@ -217,28 +214,24 @@ TEST_F(MemoryProgramCacheTest, LoadProgram) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, - fragment_shader_, NULL, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + fragment_shader_, NULL, varyings_, GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), - NULL, - fragment_shader_->signature_source(), - NULL, - NULL)); + vertex_shader_->last_compiled_signature(), + fragment_shader_->last_compiled_signature(), + NULL, varyings_, GL_NONE)); EXPECT_EQ(1, shader_cache_count()); cache_->Clear(); cache_->LoadProgram(shader_cache_shader()); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), - NULL, - fragment_shader_->signature_source(), - NULL, - NULL)); + vertex_shader_->last_compiled_signature(), + fragment_shader_->last_compiled_signature(), + NULL, varyings_, GL_NONE)); } TEST_F(MemoryProgramCacheTest, CacheLoadMatchesSave) { @@ -252,8 +245,8 @@ TEST_F(MemoryProgramCacheTest, CacheLoadMatchesSave) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, - fragment_shader_, NULL, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + fragment_shader_, NULL, varyings_, GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(1, shader_cache_count()); @@ -277,10 +270,10 @@ TEST_F(MemoryProgramCacheTest, CacheLoadMatchesSave) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, - NULL, fragment_shader_, NULL, - NULL, + varyings_, + GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); @@ -307,8 +300,8 @@ TEST_F(MemoryProgramCacheTest, LoadProgramMatchesSave) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, - fragment_shader_, NULL, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + fragment_shader_, NULL, varyings_, GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(1, shader_cache_count()); @@ -335,10 +328,10 @@ TEST_F(MemoryProgramCacheTest, LoadProgramMatchesSave) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, - NULL, fragment_shader_, NULL, - NULL, + varyings_, + GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); @@ -365,8 +358,8 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnLinkFalse) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, - fragment_shader_, NULL, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + fragment_shader_, NULL, varyings_, GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); @@ -374,10 +367,10 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnLinkFalse) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, - NULL, fragment_shader_, NULL, - NULL, + varyings_, + GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); } @@ -393,21 +386,21 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, - fragment_shader_, NULL, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + fragment_shader_, NULL, varyings_, GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); - const std::string vertex_orig_source = vertex_shader_->signature_source(); + const std::string vertex_orig_source = vertex_shader_->last_compiled_source(); vertex_shader_->set_source("different!"); TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true); EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, - NULL, fragment_shader_, NULL, - NULL, + varyings_, + GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); @@ -418,10 +411,10 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, - NULL, fragment_shader_, NULL, - NULL, + varyings_, + GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); } @@ -441,10 +434,10 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentMap) { binding_map["test"] = 512; cache_->SaveLinkedProgram(kProgramId, vertex_shader_, - NULL, fragment_shader_, - NULL, &binding_map, + varyings_, + GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); @@ -452,19 +445,62 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentMap) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, - NULL, fragment_shader_, - NULL, &binding_map, + varyings_, + GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, + fragment_shader_, NULL, + varyings_, + GL_NONE, + base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, + base::Unretained(this)))); +} + +TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentTransformFeedbackVaryings) { + const GLenum kFormat = 1; + const int kProgramId = 10; + const int kBinaryLength = 20; + char test_binary[kBinaryLength]; + for (int i = 0; i < kBinaryLength; ++i) { + test_binary[i] = i; + } + ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); + + SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); + varyings_.push_back("test"); + cache_->SaveLinkedProgram(kProgramId, + vertex_shader_, + fragment_shader_, + NULL, + varyings_, + GL_INTERLEAVED_ATTRIBS, + base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, + base::Unretained(this))); + + EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( + kProgramId, + vertex_shader_, fragment_shader_, NULL, + varyings_, + GL_SEPARATE_ATTRIBS, + base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, + base::Unretained(this)))); + + varyings_.push_back("different!"); + EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( + kProgramId, + vertex_shader_, + fragment_shader_, NULL, + varyings_, + GL_INTERLEAVED_ATTRIBS, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); } @@ -481,8 +517,8 @@ TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) { SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, - fragment_shader_, NULL, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + fragment_shader_, NULL, varyings_, GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); @@ -490,7 +526,7 @@ TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) { const GLuint kEvictingBinaryLength = kCacheSizeBytes - kBinaryLength + 1; // save old source and modify for new program - const std::string& old_source = fragment_shader_->signature_source(); + const std::string& old_sig = fragment_shader_->last_compiled_signature(); fragment_shader_->set_source("al sdfkjdk"); TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true); @@ -506,25 +542,21 @@ TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) { SetExpectationsForSaveLinkedProgram(kEvictingProgramId, &emulator2); cache_->SaveLinkedProgram(kEvictingProgramId, vertex_shader_, - NULL, fragment_shader_, NULL, - NULL, + varyings_, + GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), - NULL, - fragment_shader_->signature_source(), - NULL, - NULL)); + vertex_shader_->last_compiled_signature(), + fragment_shader_->last_compiled_signature(), + NULL, varyings_, GL_NONE)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus( - old_source, - NULL, - fragment_shader_->signature_source(), - NULL, - NULL)); + old_sig, + fragment_shader_->last_compiled_signature(), + NULL, varyings_, GL_NONE)); } TEST_F(MemoryProgramCacheTest, SaveCorrectProgram) { @@ -539,17 +571,15 @@ TEST_F(MemoryProgramCacheTest, SaveCorrectProgram) { vertex_shader_->set_source("different!"); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, - fragment_shader_, NULL, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + fragment_shader_, NULL, varyings_, GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), - NULL, - fragment_shader_->signature_source(), - NULL, - NULL)); + vertex_shader_->last_compiled_signature(), + fragment_shader_->last_compiled_signature(), + NULL, varyings_, GL_NONE)); } TEST_F(MemoryProgramCacheTest, LoadCorrectProgram) { @@ -563,17 +593,15 @@ TEST_F(MemoryProgramCacheTest, LoadCorrectProgram) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, - fragment_shader_, NULL, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + fragment_shader_, NULL, varyings_, GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - vertex_shader_->signature_source(), - NULL, - fragment_shader_->signature_source(), - NULL, - NULL)); + vertex_shader_->last_compiled_signature(), + fragment_shader_->last_compiled_signature(), + NULL, varyings_, GL_NONE)); SetExpectationsForLoadLinkedProgram(kProgramId, &emulator); @@ -581,10 +609,10 @@ TEST_F(MemoryProgramCacheTest, LoadCorrectProgram) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, - NULL, fragment_shader_, NULL, - NULL, + varyings_, + GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); } @@ -600,8 +628,8 @@ TEST_F(MemoryProgramCacheTest, OverwriteOnNewSave) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, - fragment_shader_, NULL, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + fragment_shader_, NULL, varyings_, GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); @@ -612,8 +640,8 @@ TEST_F(MemoryProgramCacheTest, OverwriteOnNewSave) { } ProgramBinaryEmulator emulator2(kBinaryLength, kFormat, test_binary2); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator2); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, - fragment_shader_, NULL, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + fragment_shader_, NULL, varyings_, GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); @@ -621,10 +649,10 @@ TEST_F(MemoryProgramCacheTest, OverwriteOnNewSave) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, - NULL, fragment_shader_, NULL, - NULL, + varyings_, + GL_NONE, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); } diff --git a/chromium/gpu/command_buffer/service/memory_tracking.h b/chromium/gpu/command_buffer/service/memory_tracking.h index 151432523ff..a7447e4e5d5 100644 --- a/chromium/gpu/command_buffer/service/memory_tracking.h +++ b/chromium/gpu/command_buffer/service/memory_tracking.h @@ -7,9 +7,9 @@ #include <string> #include "base/basictypes.h" -#include "base/debug/trace_event.h" #include "base/logging.h" #include "base/memory/ref_counted.h" +#include "base/trace_event/trace_event.h" namespace gpu { namespace gles2 { diff --git a/chromium/gpu/command_buffer/service/mocks.h b/chromium/gpu/command_buffer/service/mocks.h index 87b31360df7..02a08dbad53 100644 --- a/chromium/gpu/command_buffer/service/mocks.h +++ b/chromium/gpu/command_buffer/service/mocks.h @@ -88,7 +88,6 @@ namespace gles2 { class MockShaderTranslator : public ShaderTranslatorInterface { public: MockShaderTranslator(); - virtual ~MockShaderTranslator(); MOCK_METHOD5(Init, bool( sh::GLenum shader_type, @@ -96,16 +95,19 @@ class MockShaderTranslator : public ShaderTranslatorInterface { const ShBuiltInResources* resources, GlslImplementationType glsl_implementation_type, ShCompileOptions driver_bug_workarounds)); - MOCK_CONST_METHOD7(Translate, bool( + MOCK_CONST_METHOD8(Translate, bool( const std::string& shader_source, std::string* info_log, std::string* translated_source, + int* shader_version, AttributeMap* attrib_map, UniformMap* uniform_map, VaryingMap* varying_map, NameMap* name_map)); MOCK_CONST_METHOD0( GetStringForOptionsThatWouldAffectCompilation, std::string()); + private: + ~MockShaderTranslator() override; }; class MockProgramCache : public ProgramCache { @@ -116,19 +118,19 @@ class MockProgramCache : public ProgramCache { MOCK_METHOD7(LoadLinkedProgram, ProgramLoadResult( GLuint program, Shader* shader_a, - const ShaderTranslatorInterface* translator_a, Shader* shader_b, - const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode, const ShaderCacheCallback& callback)); MOCK_METHOD7(SaveLinkedProgram, void( GLuint program, const Shader* shader_a, - const ShaderTranslatorInterface* translator_a, const Shader* shader_b, - const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode, const ShaderCacheCallback& callback)); MOCK_METHOD1(LoadProgram, void(const std::string&)); diff --git a/chromium/gpu/command_buffer/service/program_cache.cc b/chromium/gpu/command_buffer/service/program_cache.cc index abdcfc0cb5d..31802de2e0b 100644 --- a/chromium/gpu/command_buffer/service/program_cache.cc +++ b/chromium/gpu/command_buffer/service/program_cache.cc @@ -20,20 +20,22 @@ void ProgramCache::Clear() { } ProgramCache::LinkedProgramStatus ProgramCache::GetLinkedProgramStatus( - const std::string& untranslated_a, - const ShaderTranslatorInterface* translator_a, - const std::string& untranslated_b, - const ShaderTranslatorInterface* translator_b, - const std::map<std::string, GLint>* bind_attrib_location_map) const { + const std::string& shader_signature_a, + const std::string& shader_signature_b, + const std::map<std::string, GLint>* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode) const { char a_sha[kHashLength]; char b_sha[kHashLength]; - ComputeShaderHash(untranslated_a, translator_a, a_sha); - ComputeShaderHash(untranslated_b, translator_b, b_sha); + ComputeShaderHash(shader_signature_a, a_sha); + ComputeShaderHash(shader_signature_b, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, b_sha, bind_attrib_location_map, + transform_feedback_varyings, + transform_feedback_buffer_mode, sha); const std::string sha_string(sha, kHashLength); @@ -46,19 +48,21 @@ ProgramCache::LinkedProgramStatus ProgramCache::GetLinkedProgramStatus( } void ProgramCache::LinkedProgramCacheSuccess( - const std::string& shader_a, - const ShaderTranslatorInterface* translator_a, - const std::string& shader_b, - const ShaderTranslatorInterface* translator_b, - const LocationMap* bind_attrib_location_map) { + const std::string& shader_signature_a, + const std::string& shader_signature_b, + const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode) { char a_sha[kHashLength]; char b_sha[kHashLength]; - ComputeShaderHash(shader_a, translator_a, a_sha); - ComputeShaderHash(shader_b, translator_b, b_sha); + ComputeShaderHash(shader_signature_a, a_sha); + ComputeShaderHash(shader_signature_b, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, b_sha, bind_attrib_location_map, + transform_feedback_varyings, + transform_feedback_buffer_mode, sha); const std::string sha_string(sha, kHashLength); @@ -71,13 +75,9 @@ void ProgramCache::LinkedProgramCacheSuccess(const std::string& program_hash) { void ProgramCache::ComputeShaderHash( const std::string& str, - const ShaderTranslatorInterface* translator, char* result) const { - std::string s(( - translator ? translator->GetStringForOptionsThatWouldAffectCompilation() : - std::string()) + str); - base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(s.c_str()), - s.length(), reinterpret_cast<unsigned char*>(result)); + base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(str.c_str()), + str.length(), reinterpret_cast<unsigned char*>(result)); } void ProgramCache::Evict(const std::string& program_hash) { @@ -89,33 +89,43 @@ size_t CalculateMapSize(const std::map<std::string, GLint>* map) { if (!map) { return 0; } - std::map<std::string, GLint>::const_iterator it; size_t total = 0; - for (it = map->begin(); it != map->end(); ++it) { + for (auto it = map->begin(); it != map->end(); ++it) { total += 4 + it->first.length(); } return total; } + +size_t CalculateVaryingsSize(const std::vector<std::string>& varyings) { + size_t total = 0; + for (auto& varying : varyings) { + total += 1 + varying.length(); + } + return total; +} } // anonymous namespace void ProgramCache::ComputeProgramHash( const char* hashed_shader_0, const char* hashed_shader_1, const std::map<std::string, GLint>* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode, char* result) const { const size_t shader0_size = kHashLength; const size_t shader1_size = kHashLength; const size_t map_size = CalculateMapSize(bind_attrib_location_map); - const size_t total_size = shader0_size + shader1_size + map_size; + const size_t var_size = CalculateVaryingsSize(transform_feedback_varyings); + const size_t total_size = shader0_size + shader1_size + map_size + var_size + + sizeof(transform_feedback_buffer_mode); scoped_ptr<unsigned char[]> buffer(new unsigned char[total_size]); memcpy(buffer.get(), hashed_shader_0, shader0_size); memcpy(&buffer[shader0_size], hashed_shader_1, shader1_size); + size_t current_pos = shader0_size + shader1_size; if (map_size != 0) { // copy our map - size_t current_pos = shader0_size + shader1_size; - std::map<std::string, GLint>::const_iterator it; - for (it = bind_attrib_location_map->begin(); + for (auto it = bind_attrib_location_map->begin(); it != bind_attrib_location_map->end(); ++it) { const size_t name_size = it->first.length(); @@ -128,6 +138,18 @@ void ProgramCache::ComputeProgramHash( buffer[current_pos++] = static_cast<unsigned char>(value); } } + + if (var_size != 0) { + // copy transform feedback varyings + for (auto& varying : transform_feedback_varyings) { + const size_t name_size = varying.length(); + memcpy(&buffer.get()[current_pos], varying.c_str(), name_size); + current_pos += name_size; + buffer[current_pos++] = ' '; + } + } + memcpy(&buffer[current_pos], &transform_feedback_buffer_mode, + sizeof(transform_feedback_buffer_mode)); base::SHA1HashBytes(buffer.get(), total_size, reinterpret_cast<unsigned char*>(result)); } diff --git a/chromium/gpu/command_buffer/service/program_cache.h b/chromium/gpu/command_buffer/service/program_cache.h index 3fb5687e8b1..44593df6d84 100644 --- a/chromium/gpu/command_buffer/service/program_cache.h +++ b/chromium/gpu/command_buffer/service/program_cache.h @@ -18,7 +18,6 @@ namespace gpu { namespace gles2 { class Shader; -class ShaderTranslator; // Program cache base class for caching linked gpu programs class GPU_EXPORT ProgramCache { @@ -41,21 +40,21 @@ class GPU_EXPORT ProgramCache { virtual ~ProgramCache(); LinkedProgramStatus GetLinkedProgramStatus( - const std::string& untranslated_shader_a, - const ShaderTranslatorInterface* translator_a, - const std::string& untranslated_shader_b, - const ShaderTranslatorInterface* translator_b, - const LocationMap* bind_attrib_location_map) const; + const std::string& shader_signature_a, + const std::string& shader_signature_b, + const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode) const; // Loads the linked program from the cache. If the program is not found or // there was an error, PROGRAM_LOAD_FAILURE should be returned. virtual ProgramLoadResult LoadLinkedProgram( GLuint program, Shader* shader_a, - const ShaderTranslatorInterface* translator_a, Shader* shader_b, - const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode, const ShaderCacheCallback& shader_callback) = 0; // Saves the program into the cache. If successful, the implementation should @@ -63,10 +62,10 @@ class GPU_EXPORT ProgramCache { virtual void SaveLinkedProgram( GLuint program, const Shader* shader_a, - const ShaderTranslatorInterface* translator_a, const Shader* shader_b, - const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode, const ShaderCacheCallback& shader_callback) = 0; virtual void LoadProgram(const std::string& program) = 0; @@ -75,11 +74,11 @@ class GPU_EXPORT ProgramCache { void Clear(); // Only for testing - void LinkedProgramCacheSuccess(const std::string& shader_a, - const ShaderTranslatorInterface* translator_a, - const std::string& shader_b, - const ShaderTranslatorInterface* translator_b, - const LocationMap* bind_attrib_location_map); + void LinkedProgramCacheSuccess(const std::string& shader_signature_a, + const std::string& shader_signature_b, + const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode); protected: // called by implementing class after a shader was successfully cached @@ -87,7 +86,6 @@ class GPU_EXPORT ProgramCache { // result is not null terminated void ComputeShaderHash(const std::string& shader, - const ShaderTranslatorInterface* translator, char* result) const; // result is not null terminated. hashed shaders are expected to be @@ -96,6 +94,8 @@ class GPU_EXPORT ProgramCache { const char* hashed_shader_0, const char* hashed_shader_1, const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode, char* result) const; void Evict(const std::string& program_hash); diff --git a/chromium/gpu/command_buffer/service/program_cache_unittest.cc b/chromium/gpu/command_buffer/service/program_cache_unittest.cc index 525fea11d59..f4949ce28b8 100644 --- a/chromium/gpu/command_buffer/service/program_cache_unittest.cc +++ b/chromium/gpu/command_buffer/service/program_cache_unittest.cc @@ -18,39 +18,42 @@ class NoBackendProgramCache : public ProgramCache { ProgramLoadResult LoadLinkedProgram( GLuint /* program */, Shader* /* shader_a */, - const ShaderTranslatorInterface* /* translator_a */, Shader* /* shader_b */, - const ShaderTranslatorInterface* /* translator_b */, const LocationMap* /* bind_attrib_location_map */, + const std::vector<std::string>& /* transform_feedback_varyings */, + GLenum /* transform_feedback_buffer_mode */, const ShaderCacheCallback& /* callback */) override { return PROGRAM_LOAD_SUCCESS; } - void SaveLinkedProgram(GLuint /* program */, - const Shader* /* shader_a */, - const ShaderTranslatorInterface* /* translator_b */, - const Shader* /* shader_b */, - const ShaderTranslatorInterface* /* translator_b */, - const LocationMap* /* bind_attrib_location_map */, - const ShaderCacheCallback& /* callback */) override {} + void SaveLinkedProgram( + GLuint /* program */, + const Shader* /* shader_a */, + const Shader* /* shader_b */, + const LocationMap* /* bind_attrib_location_map */, + const std::vector<std::string>& /* transform_feedback_varyings */, + GLenum /* transform_feedback_buffer_mode */, + const ShaderCacheCallback& /* callback */) override {} void LoadProgram(const std::string& /* program */) override {} void ClearBackend() override {} void SaySuccessfullyCached(const std::string& shader1, - const ShaderTranslatorInterface* translator_1, const std::string& shader2, - const ShaderTranslatorInterface* translator_2, - std::map<std::string, GLint>* attrib_map) { + std::map<std::string, GLint>* attrib_map, + const std::vector<std::string>& varyings, + GLenum buffer_mode) { char a_sha[kHashLength]; char b_sha[kHashLength]; - ComputeShaderHash(shader1, translator_1, a_sha); - ComputeShaderHash(shader2, translator_2, b_sha); + ComputeShaderHash(shader1, a_sha); + ComputeShaderHash(shader2, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, b_sha, attrib_map, + varyings, + buffer_mode, sha); const std::string shaString(sha, kHashLength); @@ -58,18 +61,22 @@ class NoBackendProgramCache : public ProgramCache { } void ComputeShaderHash(const std::string& shader, - const ShaderTranslatorInterface* translator, char* result) const { - ProgramCache::ComputeShaderHash(shader, translator, result); + ProgramCache::ComputeShaderHash(shader, result); } - void ComputeProgramHash(const char* hashed_shader_0, - const char* hashed_shader_1, - const LocationMap* bind_attrib_location_map, - char* result) const { + void ComputeProgramHash( + const char* hashed_shader_0, + const char* hashed_shader_1, + const LocationMap* bind_attrib_location_map, + const std::vector<std::string>& transform_feedback_varyings, + GLenum transform_feedback_buffer_mode, + char* result) const { ProgramCache::ComputeProgramHash(hashed_shader_0, hashed_shader_1, bind_attrib_location_map, + transform_feedback_varyings, + transform_feedback_buffer_mode, result); } @@ -85,6 +92,7 @@ class ProgramCacheTest : public testing::Test { protected: scoped_ptr<NoBackendProgramCache> cache_; + std::vector<std::string> varyings_; }; TEST_F(ProgramCacheTest, LinkStatusSave) { @@ -95,8 +103,8 @@ TEST_F(ProgramCacheTest, LinkStatusSave) { std::string shader_b = shader2; EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus( - shader_a, NULL, shader_b, NULL, NULL)); - cache_->SaySuccessfullyCached(shader_a, NULL, shader_b, NULL, NULL); + shader_a, shader_b, NULL, varyings_, GL_NONE)); + cache_->SaySuccessfullyCached(shader_a, shader_b, NULL, varyings_, GL_NONE); shader_a.clear(); shader_b.clear(); @@ -104,96 +112,128 @@ TEST_F(ProgramCacheTest, LinkStatusSave) { // make sure it was copied EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - shader1, NULL, shader2, NULL, NULL)); + shader1, shader2, NULL, varyings_, GL_NONE)); } TEST_F(ProgramCacheTest, LinkUnknownOnFragmentSourceChange) { const std::string shader1 = "abcd1234"; std::string shader2 = "abcda sda b1~#4 bbbbb1234"; - cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); + cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_, GL_NONE); shader2 = "different!"; EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); + cache_->GetLinkedProgramStatus(shader1, shader2, NULL, + varyings_, GL_NONE)); } TEST_F(ProgramCacheTest, LinkUnknownOnVertexSourceChange) { std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; - cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); + cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_, GL_NONE); shader1 = "different!"; EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); + cache_->GetLinkedProgramStatus(shader1, shader2, NULL, + varyings_, GL_NONE)); } TEST_F(ProgramCacheTest, StatusEviction) { const std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; - cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); + cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_, GL_NONE); char a_sha[ProgramCache::kHashLength]; char b_sha[ProgramCache::kHashLength]; - cache_->ComputeShaderHash(shader1, NULL, a_sha); - cache_->ComputeShaderHash(shader2, NULL, b_sha); + cache_->ComputeShaderHash(shader1, a_sha); + cache_->ComputeShaderHash(shader2, b_sha); char sha[ProgramCache::kHashLength]; cache_->ComputeProgramHash(a_sha, b_sha, NULL, + varyings_, + GL_NONE, sha); cache_->Evict(std::string(sha, ProgramCache::kHashLength)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); + cache_->GetLinkedProgramStatus(shader1, shader2, NULL, + varyings_, GL_NONE)); } TEST_F(ProgramCacheTest, EvictionWithReusedShader) { const std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; const std::string shader3 = "asbjbbjj239a"; - cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); - cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL); + cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_, GL_NONE); + cache_->SaySuccessfullyCached(shader1, shader3, NULL, varyings_, GL_NONE); char a_sha[ProgramCache::kHashLength]; char b_sha[ProgramCache::kHashLength]; char c_sha[ProgramCache::kHashLength]; - cache_->ComputeShaderHash(shader1, NULL, a_sha); - cache_->ComputeShaderHash(shader2, NULL, b_sha); - cache_->ComputeShaderHash(shader3, NULL, c_sha); + cache_->ComputeShaderHash(shader1, a_sha); + cache_->ComputeShaderHash(shader2, b_sha); + cache_->ComputeShaderHash(shader3, c_sha); char sha[ProgramCache::kHashLength]; cache_->ComputeProgramHash(a_sha, b_sha, NULL, + varyings_, + GL_NONE, sha); cache_->Evict(std::string(sha, ProgramCache::kHashLength)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); + cache_->GetLinkedProgramStatus(shader1, shader2, NULL, + varyings_, GL_NONE)); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, - cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL)); + cache_->GetLinkedProgramStatus(shader1, shader3, NULL, + varyings_, GL_NONE)); cache_->ComputeProgramHash(a_sha, c_sha, NULL, + varyings_, + GL_NONE, sha); cache_->Evict(std::string(sha, ProgramCache::kHashLength)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); + cache_->GetLinkedProgramStatus(shader1, shader2, NULL, + varyings_, GL_NONE)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL)); + cache_->GetLinkedProgramStatus(shader1, shader3, NULL, + varyings_, GL_NONE)); } TEST_F(ProgramCacheTest, StatusClear) { const std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; const std::string shader3 = "asbjbbjj239a"; - cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); - cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL); + cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_, GL_NONE); + cache_->SaySuccessfullyCached(shader1, shader3, NULL, varyings_, GL_NONE); cache_->Clear(); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); + cache_->GetLinkedProgramStatus(shader1, shader2, NULL, + varyings_, GL_NONE)); + EXPECT_EQ(ProgramCache::LINK_UNKNOWN, + cache_->GetLinkedProgramStatus(shader1, shader3, NULL, + varyings_, GL_NONE)); +} + +TEST_F(ProgramCacheTest, LinkUnknownOnTransformFeedbackChange) { + const std::string shader1 = "abcd1234"; + std::string shader2 = "abcda sda b1~#4 bbbbb1234"; + varyings_.push_back("a"); + cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_, + GL_INTERLEAVED_ATTRIBS); + + EXPECT_EQ(ProgramCache::LINK_UNKNOWN, + cache_->GetLinkedProgramStatus(shader1, shader2, NULL, + varyings_, GL_SEPARATE_ATTRIBS)); + + varyings_.push_back("b"); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL)); + cache_->GetLinkedProgramStatus(shader1, shader2, NULL, + varyings_, GL_INTERLEAVED_ATTRIBS)); } } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/program_manager.cc b/chromium/gpu/command_buffer/service/program_manager.cc index f3c447cbd03..9a15f820515 100644 --- a/chromium/gpu/command_buffer/service/program_manager.cc +++ b/chromium/gpu/command_buffer/service/program_manager.cc @@ -14,6 +14,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/metrics/histogram.h" +#include "base/numerics/safe_math.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/time/time.h" @@ -23,7 +24,6 @@ #include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/program_cache.h" #include "gpu/command_buffer/service/shader_manager.h" -#include "gpu/command_buffer/service/shader_translator.h" #include "third_party/re2/re2/re2.h" using base::TimeDelta; @@ -66,7 +66,7 @@ bool GetUniformNameSansElement( return false; } - GLint index = 0; + base::CheckedNumeric<GLint> index = 0; size_t last = name.size() - 1; for (size_t pos = open_pos + 1; pos < last; ++pos) { int8 digit = name[pos] - '0'; @@ -75,8 +75,11 @@ bool GetUniformNameSansElement( } index = index * 10 + digit; } + if (!index.IsValid()) { + return false; + } - *element_index = index; + *element_index = index.ValueOrDie(); *new_name = name.substr(0, open_pos); return true; } @@ -103,6 +106,11 @@ bool IsBuiltInInvariant( return hit->second.isInvariant; } +uint32 ComputeOffset(const void* start, const void* position) { + return static_cast<const uint8*>(position) - + static_cast<const uint8*>(start); +} + } // anonymous namespace. Program::UniformInfo::UniformInfo() @@ -203,7 +211,8 @@ Program::Program(ProgramManager* manager, GLuint service_id) valid_(false), link_status_(false), uniforms_cleared_(false), - num_uniforms_(0) { + num_uniforms_(0), + transform_feedback_buffer_mode_(GL_NONE) { manager_->StartTracking(this); } @@ -272,8 +281,10 @@ void Program::ClearUniforms( } GLint location = uniform_info.element_locations[0]; GLsizei size = uniform_info.size; - uint32 unit_size = GLES2Util::GetGLDataTypeSizeForUniforms( - uniform_info.type); + uint32 unit_size = + GLES2Util::GetElementCountForUniformType(uniform_info.type) * + GLES2Util::GetElementSizeForUniformType(uniform_info.type); + DCHECK_LT(0u, unit_size); uint32 size_needed = size * unit_size; if (size_needed > zero_buffer->size()) { zero_buffer->resize(size_needed, 0u); @@ -296,9 +307,8 @@ void Program::ClearUniforms( case GL_BOOL: case GL_SAMPLER_2D: case GL_SAMPLER_CUBE: - case GL_SAMPLER_EXTERNAL_OES: - case GL_SAMPLER_3D_OES: - case GL_SAMPLER_2D_RECT_ARB: + case GL_SAMPLER_EXTERNAL_OES: // extension. + case GL_SAMPLER_2D_RECT_ARB: // extension. glUniform1iv(location, size, reinterpret_cast<const GLint*>(zero)); break; case GL_INT_VEC2: @@ -325,6 +335,60 @@ void Program::ClearUniforms( glUniformMatrix4fv( location, size, false, reinterpret_cast<const GLfloat*>(zero)); break; + + // ES3 types. + case GL_UNSIGNED_INT: + glUniform1uiv(location, size, reinterpret_cast<const GLuint*>(zero)); + break; + 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: + glUniform1iv(location, size, reinterpret_cast<const GLint*>(zero)); + break; + case GL_UNSIGNED_INT_VEC2: + glUniform2uiv(location, size, reinterpret_cast<const GLuint*>(zero)); + break; + case GL_UNSIGNED_INT_VEC3: + glUniform3uiv(location, size, reinterpret_cast<const GLuint*>(zero)); + break; + case GL_UNSIGNED_INT_VEC4: + glUniform4uiv(location, size, reinterpret_cast<const GLuint*>(zero)); + break; + case GL_FLOAT_MAT2x3: + glUniformMatrix2x3fv( + location, size, false, reinterpret_cast<const GLfloat*>(zero)); + break; + case GL_FLOAT_MAT3x2: + glUniformMatrix3x2fv( + location, size, false, reinterpret_cast<const GLfloat*>(zero)); + break; + case GL_FLOAT_MAT2x4: + glUniformMatrix2x4fv( + location, size, false, reinterpret_cast<const GLfloat*>(zero)); + break; + case GL_FLOAT_MAT4x2: + glUniformMatrix4x2fv( + location, size, false, reinterpret_cast<const GLfloat*>(zero)); + break; + case GL_FLOAT_MAT3x4: + glUniformMatrix3x4fv( + location, size, false, reinterpret_cast<const GLfloat*>(zero)); + break; + case GL_FLOAT_MAT4x3: + glUniformMatrix4x3fv( + location, size, false, reinterpret_cast<const GLfloat*>(zero)); + break; + default: NOTREACHED(); break; @@ -374,19 +438,16 @@ void Program::Update() { service_id_, ii, max_len, &length, &size, &type, name_buffer.get()); DCHECK(max_len == 0 || length < max_len); DCHECK(length == 0 || name_buffer[length] == '\0'); - if (!ProgramManager::IsInvalidPrefix(name_buffer.get(), length)) { - std::string original_name; - GetVertexAttribData(name_buffer.get(), &original_name, &type); - // TODO(gman): Should we check for error? - GLint location = glGetAttribLocation(service_id_, name_buffer.get()); - if (location > max_location) { - max_location = location; - } - attrib_infos_.push_back( - VertexAttrib(1, type, original_name, location)); - max_attrib_name_length_ = std::max( - max_attrib_name_length_, static_cast<GLsizei>(original_name.size())); + std::string original_name; + GetVertexAttribData(name_buffer.get(), &original_name, &type); + // TODO(gman): Should we check for error? + GLint location = glGetAttribLocation(service_id_, name_buffer.get()); + if (location > max_location) { + max_location = location; } + attrib_infos_.push_back(VertexAttrib(1, type, original_name, location)); + max_attrib_name_length_ = std::max( + max_attrib_name_length_, static_cast<GLsizei>(original_name.size())); } // Create attrib location to index map. @@ -400,8 +461,8 @@ void Program::Update() { } #if !defined(NDEBUG) - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableGPUServiceLoggingGPU)) { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableGPUServiceLoggingGPU)) { DVLOG(1) << "----: attribs for service_id: " << service_id(); for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { const VertexAttrib& info = attrib_infos_[ii]; @@ -429,13 +490,10 @@ void Program::Update() { &data.size, &data.type, name_buffer.get()); DCHECK(max_len == 0 || length < max_len); DCHECK(length == 0 || name_buffer[length] == '\0'); - if (!ProgramManager::IsInvalidPrefix(name_buffer.get(), length)) { - data.queried_name = std::string(name_buffer.get()); - GetCorrectedUniformData( - data.queried_name, - &data.corrected_name, &data.original_name, &data.size, &data.type); - uniform_data.push_back(data); - } + data.queried_name = std::string(name_buffer.get()); + GetCorrectedUniformData(data.queried_name, &data.corrected_name, + &data.original_name, &data.size, &data.type); + uniform_data.push_back(data); } // NOTE: We don't care if 2 uniforms are bound to the same location. @@ -450,8 +508,14 @@ void Program::Update() { size_t next_available_index = 0; for (size_t ii = 0; ii < uniform_data.size(); ++ii) { UniformData& data = uniform_data[ii]; - data.location = glGetUniformLocation( - service_id_, data.queried_name.c_str()); + // Force builtin uniforms (gl_DepthRange) to have invalid location. + if (ProgramManager::IsInvalidPrefix(data.queried_name.c_str(), + data.queried_name.size())) { + data.location = -1; + } else { + data.location = + glGetUniformLocation(service_id_, data.queried_name.c_str()); + } // remove "[0]" std::string short_name; int element_index = 0; @@ -478,8 +542,8 @@ void Program::Update() { } #if !defined(NDEBUG) - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableGPUServiceLoggingGPU)) { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableGPUServiceLoggingGPU)) { DVLOG(1) << "----: uniforms for service_id: " << service_id(); for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { const UniformInfo& info = uniform_infos_[ii]; @@ -506,70 +570,36 @@ void Program::ExecuteBindAttribLocationCalls() { } bool Program::Link(ShaderManager* manager, - ShaderTranslator* vertex_translator, - ShaderTranslator* fragment_translator, Program::VaryingsPackingOption varyings_packing_option, const ShaderCacheCallback& shader_callback) { ClearLinkStatus(); - if (!CanLink()) { + + if (!AttachedShadersExist()) { set_log_info("missing shaders"); return false; } - if (DetectAttribLocationBindingConflicts()) { - set_log_info("glBindAttribLocation() conflicts"); - return false; - } - std::string conflicting_name; - if (DetectUniformsMismatch(&conflicting_name)) { - std::string info_log = "Uniforms with the same name but different " - "type/precision: " + conflicting_name; - set_log_info(ProcessLogInfo(info_log).c_str()); - return false; - } - if (DetectVaryingsMismatch(&conflicting_name)) { - std::string info_log = "Varyings with the same name but different type, " - "or statically used varyings in fragment shader are " - "not declared in vertex shader: " + conflicting_name; - set_log_info(ProcessLogInfo(info_log).c_str()); - return false; - } - if (DetectBuiltInInvariantConflicts()) { - set_log_info("Invariant settings for certain built-in varyings " - "have to match"); - return false; - } - if (DetectGlobalNameConflicts(&conflicting_name)) { - std::string info_log = "Name conflicts between an uniform and an " - "attribute: " + conflicting_name; - set_log_info(ProcessLogInfo(info_log).c_str()); - return false; - } - if (!CheckVaryingsPacking(varyings_packing_option)) { - set_log_info("Varyings over maximum register limit"); - return false; - } - TimeTicks before_time = TimeTicks::HighResNow(); + TimeTicks before_time = TimeTicks::Now(); bool link = true; ProgramCache* cache = manager_->program_cache_; if (cache) { - DCHECK(!attached_shaders_[0]->signature_source().empty() && - !attached_shaders_[1]->signature_source().empty()); + DCHECK(!attached_shaders_[0]->last_compiled_source().empty() && + !attached_shaders_[1]->last_compiled_source().empty()); ProgramCache::LinkedProgramStatus status = cache->GetLinkedProgramStatus( - attached_shaders_[0]->signature_source(), - vertex_translator, - attached_shaders_[1]->signature_source(), - fragment_translator, - &bind_attrib_location_map_); + attached_shaders_[0]->last_compiled_signature(), + attached_shaders_[1]->last_compiled_signature(), + &bind_attrib_location_map_, + transform_feedback_varyings_, + transform_feedback_buffer_mode_); if (status == ProgramCache::LINK_SUCCEEDED) { ProgramCache::ProgramLoadResult success = cache->LoadLinkedProgram(service_id(), attached_shaders_[0].get(), - vertex_translator, attached_shaders_[1].get(), - fragment_translator, &bind_attrib_location_map_, + transform_feedback_varyings_, + transform_feedback_buffer_mode_, shader_callback); link = success != ProgramCache::PROGRAM_LOAD_SUCCESS; UMA_HISTOGRAM_BOOLEAN("GPU.ProgramCache.LoadBinarySuccess", !link); @@ -577,8 +607,53 @@ bool Program::Link(ShaderManager* manager, } if (link) { + CompileAttachedShaders(); + + if (!CanLink()) { + set_log_info("invalid shaders"); + return false; + } + if (DetectShaderVersionMismatch()) { + set_log_info("Versions of linked shaders have to match."); + return false; + } + if (DetectAttribLocationBindingConflicts()) { + set_log_info("glBindAttribLocation() conflicts"); + return false; + } + std::string conflicting_name; + if (DetectUniformsMismatch(&conflicting_name)) { + std::string info_log = "Uniforms with the same name but different " + "type/precision: " + conflicting_name; + set_log_info(ProcessLogInfo(info_log).c_str()); + return false; + } + if (DetectVaryingsMismatch(&conflicting_name)) { + std::string info_log = "Varyings with the same name but different type, " + "or statically used varyings in fragment shader " + "are not declared in vertex shader: " + + conflicting_name; + set_log_info(ProcessLogInfo(info_log).c_str()); + return false; + } + if (DetectBuiltInInvariantConflicts()) { + set_log_info("Invariant settings for certain built-in varyings " + "have to match"); + return false; + } + if (DetectGlobalNameConflicts(&conflicting_name)) { + std::string info_log = "Name conflicts between an uniform and an " + "attribute: " + conflicting_name; + set_log_info(ProcessLogInfo(info_log).c_str()); + return false; + } + if (!CheckVaryingsPacking(varyings_packing_option)) { + set_log_info("Varyings over maximum register limit"); + return false; + } + ExecuteBindAttribLocationCalls(); - before_time = TimeTicks::HighResNow(); + before_time = TimeTicks::Now(); if (cache && gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) { glProgramParameteri(service_id(), PROGRAM_BINARY_RETRIEVABLE_HINT, @@ -595,16 +670,16 @@ bool Program::Link(ShaderManager* manager, if (cache) { cache->SaveLinkedProgram(service_id(), attached_shaders_[0].get(), - vertex_translator, attached_shaders_[1].get(), - fragment_translator, &bind_attrib_location_map_, + transform_feedback_varyings_, + transform_feedback_buffer_mode_, shader_callback); } UMA_HISTOGRAM_CUSTOM_COUNTS( "GPU.ProgramCache.BinaryCacheMissTime", static_cast<base::HistogramBase::Sample>( - (TimeTicks::HighResNow() - before_time).InMicroseconds()), + (TimeTicks::Now() - before_time).InMicroseconds()), 0, static_cast<base::HistogramBase::Sample>( TimeDelta::FromSeconds(10).InMicroseconds()), @@ -613,7 +688,7 @@ bool Program::Link(ShaderManager* manager, UMA_HISTOGRAM_CUSTOM_COUNTS( "GPU.ProgramCache.BinaryCacheHitTime", static_cast<base::HistogramBase::Sample>( - (TimeTicks::HighResNow() - before_time).InMicroseconds()), + (TimeTicks::Now() - before_time).InMicroseconds()), 0, static_cast<base::HistogramBase::Sample>( TimeDelta::FromSeconds(1).InMicroseconds()), @@ -992,6 +1067,23 @@ void Program::DetachShaders(ShaderManager* shader_manager) { } } +void Program::CompileAttachedShaders() { + for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { + Shader* shader = attached_shaders_[ii].get(); + if (shader) { + shader->DoCompile(); + } + } +} + +bool Program::AttachedShadersExist() const { + for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { + if (!attached_shaders_[ii].get()) + return false; + } + return true; +} + bool Program::CanLink() const { for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { if (!attached_shaders_[ii].get() || !attached_shaders_[ii]->valid()) { @@ -1001,6 +1093,22 @@ bool Program::CanLink() const { return true; } +bool Program::DetectShaderVersionMismatch() const { + int version = Shader::kUndefinedShaderVersion; + for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { + Shader* shader = attached_shaders_[ii].get(); + if (shader) { + if (version != Shader::kUndefinedShaderVersion && + shader->shader_version() != version) { + return true; + } + version = shader->shader_version(); + DCHECK(version != Shader::kUndefinedShaderVersion); + } + } + return false; +} + bool Program::DetectAttribLocationBindingConflicts() const { std::set<GLint> location_binding_used; for (LocationMap::const_iterator it = bind_attrib_location_map_.begin(); @@ -1197,11 +1305,6 @@ bool Program::CheckVaryingsPacking( combined_map.size()); } -static uint32 ComputeOffset(const void* start, const void* position) { - return static_cast<const uint8*>(position) - - static_cast<const uint8*>(start); -} - void Program::GetProgramInfo( ProgramManager* manager, CommonDecoder::Bucket* bucket) const { // NOTE: It seems to me the math in here does not need check for overflow @@ -1286,6 +1389,312 @@ void Program::GetProgramInfo( DCHECK_EQ(ComputeOffset(header, strings), size); } +bool Program::GetUniformBlocks(CommonDecoder::Bucket* bucket) const { + // The data is packed into the bucket in the following order + // 1) header + // 2) N entries of block data (except for name and indices) + // 3) name1, indices1, name2, indices2, ..., nameN, indicesN + // + // We query all the data directly through GL calls, assuming they are + // cheap through MANGLE. + + DCHECK(bucket); + GLuint program = service_id(); + + uint32_t header_size = sizeof(UniformBlocksHeader); + bucket->SetSize(header_size); // In case we fail. + + uint32_t num_uniform_blocks = 0; + GLint param = GL_FALSE; + // We assume program is a valid program service id. + glGetProgramiv(program, GL_LINK_STATUS, ¶m); + if (param == GL_TRUE) { + param = 0; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, ¶m); + num_uniform_blocks = static_cast<uint32_t>(param); + } + if (num_uniform_blocks == 0) { + // Although spec allows an implementation to return uniform block info + // even if a link fails, for consistency, we disallow that. + return true; + } + + std::vector<UniformBlockInfo> blocks(num_uniform_blocks); + base::CheckedNumeric<uint32_t> size = sizeof(UniformBlockInfo); + size *= num_uniform_blocks; + uint32_t entry_size = size.ValueOrDefault(0); + size += header_size; + std::vector<std::string> names(num_uniform_blocks); + GLint max_name_length = 0; + glGetProgramiv( + program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_name_length); + std::vector<GLchar> buffer(max_name_length); + GLsizei length; + for (uint32_t ii = 0; ii < num_uniform_blocks; ++ii) { + param = 0; + glGetActiveUniformBlockiv(program, ii, GL_UNIFORM_BLOCK_BINDING, ¶m); + blocks[ii].binding = static_cast<uint32_t>(param); + + param = 0; + glGetActiveUniformBlockiv(program, ii, GL_UNIFORM_BLOCK_DATA_SIZE, ¶m); + blocks[ii].data_size = static_cast<uint32_t>(param); + + blocks[ii].name_offset = size.ValueOrDefault(0); + param = 0; + glGetActiveUniformBlockiv( + program, ii, GL_UNIFORM_BLOCK_NAME_LENGTH, ¶m); + DCHECK_GE(max_name_length, param); + memset(&buffer[0], 0, param); + length = 0; + glGetActiveUniformBlockName( + program, ii, static_cast<GLsizei>(param), &length, &buffer[0]); + DCHECK_EQ(param, length + 1); + names[ii] = std::string(&buffer[0], length); + // TODO(zmo): optimize the name mapping lookup. + const std::string* original_name = GetOriginalNameFromHashedName(names[ii]); + if (original_name) + names[ii] = *original_name; + blocks[ii].name_length = names[ii].size() + 1; + size += blocks[ii].name_length; + + param = 0; + glGetActiveUniformBlockiv( + program, ii, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, ¶m); + blocks[ii].active_uniforms = static_cast<uint32_t>(param); + blocks[ii].active_uniform_offset = size.ValueOrDefault(0); + base::CheckedNumeric<uint32_t> indices_size = blocks[ii].active_uniforms; + indices_size *= sizeof(uint32_t); + if (!indices_size.IsValid()) + return false; + size += indices_size.ValueOrDefault(0); + + param = 0; + glGetActiveUniformBlockiv( + program, ii, GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, ¶m); + blocks[ii].referenced_by_vertex_shader = static_cast<uint32_t>(param); + + param = 0; + glGetActiveUniformBlockiv( + program, ii, GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, ¶m); + blocks[ii].referenced_by_fragment_shader = static_cast<uint32_t>(param); + } + if (!size.IsValid()) + return false; + uint32_t total_size = size.ValueOrDefault(0); + DCHECK_LE(header_size + entry_size, total_size); + uint32_t data_size = total_size - header_size - entry_size; + + bucket->SetSize(total_size); + UniformBlocksHeader* header = + bucket->GetDataAs<UniformBlocksHeader*>(0, header_size); + UniformBlockInfo* entries = bucket->GetDataAs<UniformBlockInfo*>( + header_size, entry_size); + char* data = bucket->GetDataAs<char*>(header_size + entry_size, data_size); + DCHECK(header); + DCHECK(entries); + DCHECK(data); + + // Copy over data for the header and entries. + header->num_uniform_blocks = num_uniform_blocks; + memcpy(entries, &blocks[0], entry_size); + + std::vector<GLint> params; + for (uint32_t ii = 0; ii < num_uniform_blocks; ++ii) { + // Get active uniform name. + memcpy(data, names[ii].c_str(), names[ii].length() + 1); + data += names[ii].length() + 1; + + // Get active uniform indices. + if (params.size() < blocks[ii].active_uniforms) + params.resize(blocks[ii].active_uniforms); + uint32_t num_bytes = blocks[ii].active_uniforms * sizeof(GLint); + memset(¶ms[0], 0, num_bytes); + glGetActiveUniformBlockiv( + program, ii, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, ¶ms[0]); + uint32_t* indices = reinterpret_cast<uint32_t*>(data); + for (uint32_t uu = 0; uu < blocks[ii].active_uniforms; ++uu) { + indices[uu] = static_cast<uint32_t>(params[uu]); + } + data += num_bytes; + } + DCHECK_EQ(ComputeOffset(header, data), total_size); + return true; +} + +bool Program::GetTransformFeedbackVaryings( + CommonDecoder::Bucket* bucket) const { + // The data is packed into the bucket in the following order + // 1) header + // 2) N entries of varying data (except for name) + // 3) name1, name2, ..., nameN + // + // We query all the data directly through GL calls, assuming they are + // cheap through MANGLE. + + DCHECK(bucket); + GLuint program = service_id(); + + uint32_t header_size = sizeof(TransformFeedbackVaryingsHeader); + bucket->SetSize(header_size); // In case we fail. + + uint32_t num_transform_feedback_varyings = 0; + GLint param = GL_FALSE; + // We assume program is a valid program service id. + glGetProgramiv(program, GL_LINK_STATUS, ¶m); + if (param == GL_TRUE) { + param = 0; + glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS, ¶m); + num_transform_feedback_varyings = static_cast<uint32_t>(param); + } + if (num_transform_feedback_varyings == 0) { + return true; + } + + std::vector<TransformFeedbackVaryingInfo> varyings( + num_transform_feedback_varyings); + base::CheckedNumeric<uint32_t> size = sizeof(TransformFeedbackVaryingInfo); + size *= num_transform_feedback_varyings; + uint32_t entry_size = size.ValueOrDefault(0); + size += header_size; + std::vector<std::string> names(num_transform_feedback_varyings); + GLint max_name_length = 0; + glGetProgramiv( + program, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_name_length); + if (max_name_length < 1) + max_name_length = 1; + std::vector<char> buffer(max_name_length); + for (uint32_t ii = 0; ii < num_transform_feedback_varyings; ++ii) { + GLsizei var_size = 0; + GLsizei var_name_length = 0; + GLenum var_type = 0; + glGetTransformFeedbackVarying( + program, ii, max_name_length, + &var_name_length, &var_size, &var_type, &buffer[0]); + varyings[ii].size = static_cast<uint32_t>(var_size); + varyings[ii].type = static_cast<uint32_t>(var_type); + varyings[ii].name_offset = static_cast<uint32_t>(size.ValueOrDefault(0)); + DCHECK_GT(max_name_length, var_name_length); + names[ii] = std::string(&buffer[0], var_name_length); + // TODO(zmo): optimize the name mapping lookup. + const std::string* original_name = GetOriginalNameFromHashedName(names[ii]); + if (original_name) + names[ii] = *original_name; + varyings[ii].name_length = names[ii].size() + 1; + size += names[ii].size(); + size += 1; + } + if (!size.IsValid()) + return false; + uint32_t total_size = size.ValueOrDefault(0); + DCHECK_LE(header_size + entry_size, total_size); + uint32_t data_size = total_size - header_size - entry_size; + + bucket->SetSize(total_size); + TransformFeedbackVaryingsHeader* header = + bucket->GetDataAs<TransformFeedbackVaryingsHeader*>(0, header_size); + TransformFeedbackVaryingInfo* entries = + bucket->GetDataAs<TransformFeedbackVaryingInfo*>(header_size, entry_size); + char* data = bucket->GetDataAs<char*>(header_size + entry_size, data_size); + DCHECK(header); + DCHECK(entries); + DCHECK(data); + + // Copy over data for the header and entries. + header->num_transform_feedback_varyings = num_transform_feedback_varyings; + memcpy(entries, &varyings[0], entry_size); + + for (uint32_t ii = 0; ii < num_transform_feedback_varyings; ++ii) { + memcpy(data, names[ii].c_str(), names[ii].length() + 1); + data += names[ii].length() + 1; + } + DCHECK_EQ(ComputeOffset(header, data), total_size); + return true; +} + +bool Program::GetUniformsES3(CommonDecoder::Bucket* bucket) const { + // The data is packed into the bucket in the following order + // 1) header + // 2) N entries of UniformES3Info + // + // We query all the data directly through GL calls, assuming they are + // cheap through MANGLE. + + DCHECK(bucket); + GLuint program = service_id(); + + uint32_t header_size = sizeof(UniformsES3Header); + bucket->SetSize(header_size); // In case we fail. + + GLsizei count = 0; + GLint param = GL_FALSE; + // We assume program is a valid program service id. + glGetProgramiv(program, GL_LINK_STATUS, ¶m); + if (param == GL_TRUE) { + param = 0; + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count); + } + if (count == 0) { + return true; + } + + base::CheckedNumeric<uint32_t> size = sizeof(UniformES3Info); + size *= count; + uint32_t entry_size = size.ValueOrDefault(0); + size += header_size; + if (!size.IsValid()) + return false; + uint32_t total_size = size.ValueOrDefault(0); + bucket->SetSize(total_size); + UniformsES3Header* header = + bucket->GetDataAs<UniformsES3Header*>(0, header_size); + DCHECK(header); + header->num_uniforms = static_cast<uint32_t>(count); + + // Instead of GetDataAs<UniformES3Info*>, we do GetDataAs<int32_t>. This is + // because struct UniformES3Info is defined as five int32_t. + // By doing this, we can fill the structs through loops. + int32_t* entries = + bucket->GetDataAs<int32_t*>(header_size, entry_size); + DCHECK(entries); + const size_t kStride = sizeof(UniformES3Info) / sizeof(int32_t); + + const GLenum kPname[] = { + GL_UNIFORM_BLOCK_INDEX, + GL_UNIFORM_OFFSET, + GL_UNIFORM_ARRAY_STRIDE, + GL_UNIFORM_MATRIX_STRIDE, + GL_UNIFORM_IS_ROW_MAJOR, + }; + const GLint kDefaultValue[] = { -1, -1, -1, -1, 0 }; + const size_t kNumPnames = arraysize(kPname); + std::vector<GLuint> indices(count); + for (GLsizei ii = 0; ii < count; ++ii) { + indices[ii] = ii; + } + std::vector<GLint> params(count); + for (size_t pname_index = 0; pname_index < kNumPnames; ++pname_index) { + for (GLsizei ii = 0; ii < count; ++ii) { + params[ii] = kDefaultValue[pname_index]; + } + glGetActiveUniformsiv( + program, count, &indices[0], kPname[pname_index], ¶ms[0]); + for (GLsizei ii = 0; ii < count; ++ii) { + entries[kStride * ii + pname_index] = params[ii]; + } + } + return true; +} + +void Program::TransformFeedbackVaryings(GLsizei count, + const char* const* varyings, + GLenum buffer_mode) { + transform_feedback_varyings_.clear(); + for (GLsizei i = 0; i < count; ++i) { + transform_feedback_varyings_.push_back(std::string(varyings[i])); + } + transform_feedback_buffer_mode_ = buffer_mode; +} + Program::~Program() { if (manager_) { if (manager_->have_context_) { diff --git a/chromium/gpu/command_buffer/service/program_manager.h b/chromium/gpu/command_buffer/service/program_manager.h index 2f5deae65f2..a620ee2ae15 100644 --- a/chromium/gpu/command_buffer/service/program_manager.h +++ b/chromium/gpu/command_buffer/service/program_manager.h @@ -24,7 +24,6 @@ class ProgramCache; class ProgramManager; class Shader; class ShaderManager; -class ShaderTranslator; // This is used to track which attributes a particular program needs // so we can verify at glDrawXXX time that every attribute is either disabled @@ -149,6 +148,19 @@ class GPU_EXPORT Program : public base::RefCounted<Program> { void GetProgramInfo( ProgramManager* manager, CommonDecoder::Bucket* bucket) const; + // Gets all the UniformBlock info. + // Return false on overflow. + bool GetUniformBlocks(CommonDecoder::Bucket* bucket) const; + + // Gets all the TransformFeedbackVarying info. + // Return false on overflow. + bool GetTransformFeedbackVaryings(CommonDecoder::Bucket* bucket) const; + + // Gather all info through glGetActiveUniformsiv, except for size, type, + // name_length, which we gather through glGetActiveUniform in + // glGetProgramInfoCHROMIUM. + bool GetUniformsES3(CommonDecoder::Bucket* bucket) const; + // Sets the sampler values for a uniform. // This is safe to call for any location. If the location is not // a sampler uniform nothing will happen. @@ -171,12 +183,12 @@ class GPU_EXPORT Program : public base::RefCounted<Program> { bool AttachShader(ShaderManager* manager, Shader* shader); bool DetachShader(ShaderManager* manager, Shader* shader); + void CompileAttachedShaders(); + bool AttachedShadersExist() const; bool CanLink() const; // Performs glLinkProgram and related activities. bool Link(ShaderManager* manager, - ShaderTranslator* vertex_translator, - ShaderTranslator* fragment_shader, VaryingsPackingOption varyings_packing_option, const ShaderCacheCallback& shader_callback); @@ -201,6 +213,9 @@ class GPU_EXPORT Program : public base::RefCounted<Program> { // returns false if error. bool SetUniformLocationBinding(const std::string& name, GLint location); + // Detects if the shader version combination is not valid. + bool DetectShaderVersionMismatch() const; + // Detects if there are attribute location conflicts from // glBindAttribLocation() calls. // We only consider the declared attributes in the program. @@ -227,11 +242,22 @@ class GPU_EXPORT Program : public base::RefCounted<Program> { // varying registers. bool CheckVaryingsPacking(VaryingsPackingOption option) const; + void TransformFeedbackVaryings(GLsizei count, const char* const* varyings, + GLenum buffer_mode); + // Visible for testing const LocationMap& bind_attrib_location_map() const { return bind_attrib_location_map_; } + const std::vector<std::string>& transform_feedback_varyings() const { + return transform_feedback_varyings_; + } + + GLenum transform_feedback_buffer_mode() const { + return transform_feedback_buffer_mode_; + } + private: friend class base::RefCounted<Program>; friend class ProgramManager; @@ -361,6 +387,10 @@ class GPU_EXPORT Program : public base::RefCounted<Program> { // uniform-location binding map from glBindUniformLocationCHROMIUM() calls. LocationMap bind_uniform_location_map_; + + std::vector<std::string> transform_feedback_varyings_; + + GLenum transform_feedback_buffer_mode_; }; // Tracks the Programs. diff --git a/chromium/gpu/command_buffer/service/program_manager_unittest.cc b/chromium/gpu/command_buffer/service/program_manager_unittest.cc index 4acd2209ab8..6c296e6ad09 100644 --- a/chromium/gpu/command_buffer/service/program_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/program_manager_unittest.cc @@ -28,7 +28,7 @@ using ::testing::Pointee; using ::testing::Return; using ::testing::ReturnRef; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::StrEq; namespace gpu { @@ -38,6 +38,12 @@ namespace { const uint32 kMaxVaryingVectors = 8; void ShaderCacheCb(const std::string& key, const std::string& shader) {} + +uint32 ComputeOffset(const void* start, const void* position) { + return static_cast<const uint8*>(position) - + static_cast<const uint8*>(start); +} + } // namespace anonymous class ProgramManagerTest : public GpuServiceTest { @@ -214,7 +220,8 @@ class ProgramManagerWithShaderTest : public GpuServiceTest { } VarInfo; void SetUp() override { - GpuServiceTest::SetUp(); + // Need to be at leat 3.1 for UniformBlock related GL APIs. + GpuServiceTest::SetUpWithGLVersion("3.1", NULL); SetupDefaultShaderExpectations(); @@ -235,7 +242,7 @@ class ProgramManagerWithShaderTest : public GpuServiceTest { program_->AttachShader(&shader_manager_, vertex_shader); program_->AttachShader(&shader_manager_, fragment_shader); - program_->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + program_->Link(NULL, Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)); } @@ -265,7 +272,7 @@ class ProgramManagerWithShaderTest : public GpuServiceTest { SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, service_id); } - program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + program->Link(NULL, Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)); GLint link_status; program->GetProgramiv(GL_LINK_STATUS, &link_status); @@ -365,10 +372,10 @@ class ProgramManagerWithShaderTest : public GpuServiceTest { EXPECT_TRUE(vshader != NULL && fshader != NULL); // Set Status TestHelper::SetShaderStates( - gl_.get(), vshader, true, NULL, NULL, + gl_.get(), vshader, true, NULL, NULL, NULL, &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map, NULL); TestHelper::SetShaderStates( - gl_.get(), fshader, true, NULL, NULL, + gl_.get(), fshader, true, NULL, NULL, NULL, &frag_attrib_map, &frag_uniform_map, &frag_varying_map, NULL); // Set up program @@ -655,36 +662,38 @@ TEST_F(ProgramManagerWithShaderTest, GetUniformInfoByFakeLocation) { EXPECT_EQ(2, array_index); } -// Some GL drivers incorrectly return gl_DepthRange and possibly other uniforms -// that start with "gl_". Our implementation catches these and does not allow -// them back to client. +// Ensure that when GL drivers correctly return gl_DepthRange, or other +// builtin uniforms, our implementation passes them back to the client. TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsGLUnderscoreUniform) { static const char* kUniform2Name = "gl_longNameWeCanCheckFor"; static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = { - { kUniform1Name, - kUniform1Size, - kUniform1Type, - kUniform1FakeLocation, - kUniform1RealLocation, - kUniform1DesiredLocation, - kUniform1Name, - }, - { kUniform2Name, - kUniform2Size, - kUniform2Type, - kUniform2FakeLocation, - kUniform2RealLocation, - kUniform2DesiredLocation, - kUniform2NameWithArrayIndex, - }, - { kUniform3Name, - kUniform3Size, - kUniform3Type, - kUniform3FakeLocation, - kUniform3RealLocation, - kUniform3DesiredLocation, - kUniform3NameWithArrayIndex, - }, + { + kUniform1Name, + kUniform1Size, + kUniform1Type, + kUniform1FakeLocation, + kUniform1RealLocation, + kUniform1DesiredLocation, + kUniform1Name, + }, + { + kUniform2Name, + kUniform2Size, + kUniform2Type, + kUniform2FakeLocation, + -1, + kUniform2DesiredLocation, + kUniform2NameWithArrayIndex, + }, + { + kUniform3Name, + kUniform3Size, + kUniform3Type, + kUniform3FakeLocation, + kUniform3RealLocation, + kUniform3DesiredLocation, + kUniform3NameWithArrayIndex, + }, }; const size_t kNumUniforms = arraysize(kUniforms); static const GLuint kClientProgramId = 1234; @@ -708,19 +717,21 @@ TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsGLUnderscoreUniform) { ASSERT_TRUE(program != NULL); EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader)); EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader)); - program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + program->Link(NULL, Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)); GLint value = 0; program->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value); EXPECT_EQ(3, value); - // Check that we skipped the "gl_" uniform. + // Check that we didn't skip the "gl_" uniform. program->GetProgramiv(GL_ACTIVE_UNIFORMS, &value); - EXPECT_EQ(2, value); - // Check that our max length adds room for the array spec and is not as long - // as the "gl_" uniform we skipped. - // +4u is to account for "gl_" and NULL terminator. + EXPECT_EQ(3, value); + // Check that our max length adds room for the array spec and is as long + // as the "gl_" uniform we did not skip. program->GetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH, &value); - EXPECT_EQ(strlen(kUniform3Name) + 4u, static_cast<size_t>(value)); + EXPECT_EQ(strlen(kUniform2Name) + 4, static_cast<size_t>(value)); + // Verify the uniform has a "real" location of -1 + const auto* info = program->GetUniformInfo(kUniform2FakeLocation); + EXPECT_EQ(-1, info->element_locations[0]); } // Test the bug comparing similar array names is fixed. @@ -777,7 +788,7 @@ TEST_F(ProgramManagerWithShaderTest, SimilarArrayNames) { ASSERT_TRUE(program != NULL); EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader)); EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader)); - program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + program->Link(NULL, Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)); // Check that we get the correct locations. @@ -823,13 +834,13 @@ TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) { kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER); ASSERT_TRUE(vshader != NULL); TestHelper::SetShaderStates( - gl_.get(), vshader, true, NULL, NULL, + gl_.get(), vshader, true, NULL, NULL, NULL, &attrib_map, &uniform_map, &varying_map, NULL); Shader* fshader = shader_manager_.CreateShader( kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER); ASSERT_TRUE(fshader != NULL); TestHelper::SetShaderStates( - gl_.get(), fshader, true, NULL, NULL, + gl_.get(), fshader, true, NULL, NULL, NULL, &attrib_map, &uniform_map, &varying_map, NULL); static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = { { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, }, @@ -873,7 +884,7 @@ TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) { ASSERT_TRUE(program!= NULL); EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader)); EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader)); - program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + program->Link(NULL, Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)); // Check that we got the good type, not the bad. // Check Attribs @@ -1073,6 +1084,346 @@ TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetProgramInfo) { static_cast<uint32>(input - inputs)); } +TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformBlocksNone) { + CommonDecoder::Bucket bucket; + const Program* program = manager_.GetProgram(kClientProgramId); + ASSERT_TRUE(program != NULL); + // The program's previous link failed. + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_FALSE)) + .RetiresOnSaturation(); + EXPECT_TRUE(program->GetUniformBlocks(&bucket)); + EXPECT_EQ(sizeof(UniformBlocksHeader), bucket.size()); + UniformBlocksHeader* header = + bucket.GetDataAs<UniformBlocksHeader*>(0, sizeof(UniformBlocksHeader)); + EXPECT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_uniform_blocks); + // Zero uniform blocks. + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_BLOCKS, _)) + .WillOnce(SetArgPointee<2>(0)) + .RetiresOnSaturation(); + EXPECT_TRUE(program->GetUniformBlocks(&bucket)); + EXPECT_EQ(sizeof(UniformBlocksHeader), bucket.size()); + header = + bucket.GetDataAs<UniformBlocksHeader*>(0, sizeof(UniformBlocksHeader)); + EXPECT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_uniform_blocks); +} + +TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformBlocksValid) { + CommonDecoder::Bucket bucket; + const Program* program = manager_.GetProgram(kClientProgramId); + ASSERT_TRUE(program != NULL); + struct Data { + UniformBlocksHeader header; + UniformBlockInfo entry[2]; + char name0[4]; + uint32_t indices0[2]; + char name1[8]; + uint32_t indices1[1]; + }; + Data data; + // The names needs to be of size 4*k-1 to avoid padding in the struct Data. + // This is a testing only problem. + const char* kName[] = { "cow", "chicken" }; + const uint32_t kIndices0[] = { 1, 2 }; + const uint32_t kIndices1[] = { 3 }; + const uint32_t* kIndices[] = { kIndices0, kIndices1 }; + data.header.num_uniform_blocks = 2; + data.entry[0].binding = 0; + data.entry[0].data_size = 8; + data.entry[0].name_offset = ComputeOffset(&data, data.name0); + data.entry[0].name_length = arraysize(data.name0); + data.entry[0].active_uniforms = arraysize(data.indices0); + data.entry[0].active_uniform_offset = ComputeOffset(&data, data.indices0); + data.entry[0].referenced_by_vertex_shader = static_cast<uint32_t>(true); + data.entry[0].referenced_by_fragment_shader = static_cast<uint32_t>(false); + data.entry[1].binding = 1; + data.entry[1].data_size = 4; + data.entry[1].name_offset = ComputeOffset(&data, data.name1); + data.entry[1].name_length = arraysize(data.name1); + data.entry[1].active_uniforms = arraysize(data.indices1); + data.entry[1].active_uniform_offset = ComputeOffset(&data, data.indices1); + data.entry[1].referenced_by_vertex_shader = static_cast<uint32_t>(false); + data.entry[1].referenced_by_fragment_shader = static_cast<uint32_t>(true); + memcpy(data.name0, kName[0], arraysize(data.name0)); + data.indices0[0] = kIndices[0][0]; + data.indices0[1] = kIndices[0][1]; + memcpy(data.name1, kName[1], arraysize(data.name1)); + data.indices1[0] = kIndices[1][0]; + + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_BLOCKS, _)) + .WillOnce(SetArgPointee<2>(data.header.num_uniform_blocks)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, + GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, _)) + .WillOnce(SetArgPointee<2>( + 1 + std::max(strlen(kName[0]), strlen(kName[1])))) + .RetiresOnSaturation(); + for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) { + EXPECT_CALL(*(gl_.get()), + GetActiveUniformBlockiv( + kServiceProgramId, ii, GL_UNIFORM_BLOCK_BINDING, _)) + .WillOnce(SetArgPointee<3>(data.entry[ii].binding)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetActiveUniformBlockiv( + kServiceProgramId, ii, GL_UNIFORM_BLOCK_DATA_SIZE, _)) + .WillOnce(SetArgPointee<3>(data.entry[ii].data_size)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetActiveUniformBlockiv( + kServiceProgramId, ii, GL_UNIFORM_BLOCK_NAME_LENGTH, _)) + .WillOnce(SetArgPointee<3>(data.entry[ii].name_length)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetActiveUniformBlockName( + kServiceProgramId, ii, data.entry[ii].name_length, _, _)) + .WillOnce(DoAll( + SetArgPointee<3>(strlen(kName[ii])), + SetArrayArgument<4>( + kName[ii], kName[ii] + data.entry[ii].name_length))) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetActiveUniformBlockiv( + kServiceProgramId, ii, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgPointee<3>(data.entry[ii].active_uniforms)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetActiveUniformBlockiv( + kServiceProgramId, ii, + GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, _)) + .WillOnce(SetArgPointee<3>(data.entry[ii].referenced_by_vertex_shader)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetActiveUniformBlockiv( + kServiceProgramId, ii, + GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, _)) + .WillOnce(SetArgPointee<3>( + data.entry[ii].referenced_by_fragment_shader)) + .RetiresOnSaturation(); + } + for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) { + EXPECT_CALL(*(gl_.get()), + GetActiveUniformBlockiv( + kServiceProgramId, ii, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, _)) + .WillOnce(SetArrayArgument<3>( + kIndices[ii], kIndices[ii] + data.entry[ii].active_uniforms)) + .RetiresOnSaturation(); + } + program->GetUniformBlocks(&bucket); + EXPECT_EQ(sizeof(Data), bucket.size()); + Data* bucket_data = bucket.GetDataAs<Data*>(0, sizeof(Data)); + EXPECT_TRUE(bucket_data != NULL); + EXPECT_EQ(0, memcmp(&data, bucket_data, sizeof(Data))); +} + +TEST_F(ProgramManagerWithShaderTest, + ProgramInfoGetTransformFeedbackVaryingsNone) { + CommonDecoder::Bucket bucket; + const Program* program = manager_.GetProgram(kClientProgramId); + ASSERT_TRUE(program != NULL); + // The program's previous link failed. + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_FALSE)) + .RetiresOnSaturation(); + EXPECT_TRUE(program->GetTransformFeedbackVaryings(&bucket)); + EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader), bucket.size()); + TransformFeedbackVaryingsHeader* header = + bucket.GetDataAs<TransformFeedbackVaryingsHeader*>( + 0, sizeof(TransformFeedbackVaryingsHeader)); + EXPECT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_transform_feedback_varyings); + // Zero uniform blocks. + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetProgramiv( + kServiceProgramId, GL_TRANSFORM_FEEDBACK_VARYINGS, _)) + .WillOnce(SetArgPointee<2>(0)) + .RetiresOnSaturation(); + EXPECT_TRUE(program->GetTransformFeedbackVaryings(&bucket)); + EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader), bucket.size()); + header = bucket.GetDataAs<TransformFeedbackVaryingsHeader*>( + 0, sizeof(TransformFeedbackVaryingsHeader)); + EXPECT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_transform_feedback_varyings); +} + +TEST_F(ProgramManagerWithShaderTest, + ProgramInfoGetTransformFeedbackVaryingsValid) { + CommonDecoder::Bucket bucket; + const Program* program = manager_.GetProgram(kClientProgramId); + ASSERT_TRUE(program != NULL); + struct Data { + TransformFeedbackVaryingsHeader header; + TransformFeedbackVaryingInfo entry[2]; + char name0[4]; + char name1[8]; + }; + Data data; + // The names needs to be of size 4*k-1 to avoid padding in the struct Data. + // This is a testing only problem. + const char* kName[] = { "cow", "chicken" }; + data.header.num_transform_feedback_varyings = 2; + data.entry[0].size = 1; + data.entry[0].type = GL_FLOAT_VEC2; + data.entry[0].name_offset = ComputeOffset(&data, data.name0); + data.entry[0].name_length = arraysize(data.name0); + data.entry[1].size = 2; + data.entry[1].type = GL_FLOAT; + data.entry[1].name_offset = ComputeOffset(&data, data.name1); + data.entry[1].name_length = arraysize(data.name1); + memcpy(data.name0, kName[0], arraysize(data.name0)); + memcpy(data.name1, kName[1], arraysize(data.name1)); + + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetProgramiv( + kServiceProgramId, GL_TRANSFORM_FEEDBACK_VARYINGS, _)) + .WillOnce(SetArgPointee<2>(data.header.num_transform_feedback_varyings)) + .RetiresOnSaturation(); + GLsizei max_length = 1 + std::max(strlen(kName[0]), strlen(kName[1])); + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, + GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, _)) + .WillOnce(SetArgPointee<2>(max_length)) + .RetiresOnSaturation(); + for (uint32_t ii = 0; ii < data.header.num_transform_feedback_varyings; + ++ii) { + EXPECT_CALL(*(gl_.get()), + GetTransformFeedbackVarying( + kServiceProgramId, ii, max_length, _, _, _, _)) + .WillOnce(DoAll( + SetArgPointee<3>(data.entry[ii].name_length - 1), + SetArgPointee<4>(data.entry[ii].size), + SetArgPointee<5>(data.entry[ii].type), + SetArrayArgument<6>( + kName[ii], kName[ii] + data.entry[ii].name_length))) + .RetiresOnSaturation(); + } + program->GetTransformFeedbackVaryings(&bucket); + EXPECT_EQ(sizeof(Data), bucket.size()); + Data* bucket_data = bucket.GetDataAs<Data*>(0, sizeof(Data)); + EXPECT_TRUE(bucket_data != NULL); + EXPECT_EQ(0, memcmp(&data, bucket_data, sizeof(Data))); +} + +TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformsES3None) { + CommonDecoder::Bucket bucket; + const Program* program = manager_.GetProgram(kClientProgramId); + ASSERT_TRUE(program != NULL); + // The program's previous link failed. + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_FALSE)) + .RetiresOnSaturation(); + EXPECT_TRUE(program->GetUniformsES3(&bucket)); + EXPECT_EQ(sizeof(UniformsES3Header), bucket.size()); + UniformsES3Header* header = + bucket.GetDataAs<UniformsES3Header*>(0, sizeof(UniformsES3Header)); + EXPECT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_uniforms); + // Zero uniform blocks. + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgPointee<2>(0)) + .RetiresOnSaturation(); + EXPECT_TRUE(program->GetUniformsES3(&bucket)); + EXPECT_EQ(sizeof(UniformsES3Header), bucket.size()); + header = + bucket.GetDataAs<UniformsES3Header*>(0, sizeof(UniformsES3Header)); + EXPECT_TRUE(header != NULL); + EXPECT_EQ(0u, header->num_uniforms); +} + +TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformsES3Valid) { + CommonDecoder::Bucket bucket; + const Program* program = manager_.GetProgram(kClientProgramId); + ASSERT_TRUE(program != NULL); + struct Data { + UniformsES3Header header; + UniformES3Info entry[2]; + }; + Data data; + const GLint kBlockIndex[] = { -1, 2 }; + const GLint kOffset[] = { 3, 4 }; + const GLint kArrayStride[] = { 7, 8 }; + const GLint kMatrixStride[] = { 9, 10 }; + const GLint kIsRowMajor[] = { 0, 1 }; + data.header.num_uniforms = 2; + for (uint32_t ii = 0; ii < data.header.num_uniforms; ++ii) { + data.entry[ii].block_index = kBlockIndex[ii]; + data.entry[ii].offset = kOffset[ii]; + data.entry[ii].array_stride = kArrayStride[ii]; + data.entry[ii].matrix_stride = kMatrixStride[ii]; + data.entry[ii].is_row_major = kIsRowMajor[ii]; + } + + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); + EXPECT_CALL(*(gl_.get()), + GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgPointee<2>(data.header.num_uniforms)) + .RetiresOnSaturation(); + + const GLenum kPname[] = { + GL_UNIFORM_BLOCK_INDEX, + GL_UNIFORM_OFFSET, + GL_UNIFORM_ARRAY_STRIDE, + GL_UNIFORM_MATRIX_STRIDE, + GL_UNIFORM_IS_ROW_MAJOR, + }; + const GLint* kParams[] = { + kBlockIndex, + kOffset, + kArrayStride, + kMatrixStride, + kIsRowMajor, + }; + const size_t kNumIterations = arraysize(kPname); + for (size_t ii = 0; ii < kNumIterations; ++ii) { + EXPECT_CALL(*(gl_.get()), + GetActiveUniformsiv( + kServiceProgramId, data.header.num_uniforms, _, + kPname[ii], _)) + .WillOnce(SetArrayArgument<4>( + kParams[ii], kParams[ii] + data.header.num_uniforms)) + .RetiresOnSaturation(); + } + + program->GetUniformsES3(&bucket); + EXPECT_EQ(sizeof(Data), bucket.size()); + Data* bucket_data = bucket.GetDataAs<Data*>(0, sizeof(Data)); + EXPECT_TRUE(bucket_data != NULL); + EXPECT_EQ(0, memcmp(&data, bucket_data, sizeof(Data))); +} + // Some drivers optimize out unused uniform array elements, so their // location would be -1. TEST_F(ProgramManagerWithShaderTest, UnusedUniformArrayElements) { @@ -1148,7 +1499,8 @@ TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) { ASSERT_TRUE(vshader != NULL && fshader != NULL); // Set Status TestHelper::SetShaderStates( - gl_.get(), vshader, true, NULL, NULL, &attrib_map, NULL, NULL, NULL); + gl_.get(), vshader, true, NULL, NULL, NULL, &attrib_map, NULL, NULL, + NULL); // Check attrib infos got copied. for (AttributeMap::const_iterator it = attrib_map.begin(); it != attrib_map.end(); ++it) { @@ -1162,7 +1514,8 @@ TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) { EXPECT_EQ(it->second.name, variable_info->name); } TestHelper::SetShaderStates( - gl_.get(), fshader, true, NULL, NULL, &attrib_map, NULL, NULL, NULL); + gl_.get(), fshader, true, NULL, NULL, NULL, &attrib_map, NULL, NULL, + NULL); // Set up program const GLuint kClientProgramId = 6666; @@ -1237,10 +1590,10 @@ TEST_F(ProgramManagerWithShaderTest, UniformsPrecisionMismatch) { ASSERT_TRUE(vshader != NULL && fshader != NULL); // Set Status TestHelper::SetShaderStates( - gl_.get(), vshader, true, NULL, NULL, NULL, + gl_.get(), vshader, true, NULL, NULL, NULL, NULL, &vertex_uniform_map, NULL, NULL); TestHelper::SetShaderStates( - gl_.get(), fshader, true, NULL, NULL, NULL, + gl_.get(), fshader, true, NULL, NULL, NULL, NULL, &frag_uniform_map, NULL, NULL); // Set up program @@ -1477,7 +1830,7 @@ TEST_F(ProgramManagerWithShaderTest, ClearWithSamplerTypes) { const size_t kNumUniforms = arraysize(kUniforms); SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId); - program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + program->Link(NULL, Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)); SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms); manager_.ClearUniforms(program); @@ -1550,7 +1903,7 @@ TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) { const size_t kNumUniforms = arraysize(kUniforms); SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId); - program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + program->Link(NULL, Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)); EXPECT_EQ(kUniform1DesiredLocation, @@ -1611,10 +1964,10 @@ class ProgramManagerWithCacheTest : public GpuServiceTest { void SetProgramCached() { cache_->LinkedProgramCacheSuccess( vertex_shader_->source(), - NULL, fragment_shader_->source(), - NULL, - &program_->bind_attrib_location_map()); + &program_->bind_attrib_location_map(), + program_->transform_feedback_varyings(), + program_->transform_feedback_buffer_mode()); } void SetExpectationsForProgramCached() { @@ -1630,10 +1983,10 @@ class ProgramManagerWithCacheTest : public GpuServiceTest { EXPECT_CALL(*cache_.get(), SaveLinkedProgram( program->service_id(), vertex_shader, - NULL, fragment_shader, - NULL, &program->bind_attrib_location_map(), + program_->transform_feedback_varyings(), + program_->transform_feedback_buffer_mode(), _)).Times(1); } @@ -1650,10 +2003,10 @@ class ProgramManagerWithCacheTest : public GpuServiceTest { EXPECT_CALL(*cache_.get(), SaveLinkedProgram( program->service_id(), vertex_shader, - NULL, fragment_shader, - NULL, &program->bind_attrib_location_map(), + program_->transform_feedback_varyings(), + program_->transform_feedback_buffer_mode(), _)).Times(0); } @@ -1674,10 +2027,10 @@ class ProgramManagerWithCacheTest : public GpuServiceTest { EXPECT_CALL(*cache_.get(), LoadLinkedProgram(service_program_id, vertex_shader, - NULL, fragment_shader, - NULL, &program->bind_attrib_location_map(), + program_->transform_feedback_varyings(), + program_->transform_feedback_buffer_mode(), _)) .WillOnce(Return(result)); } @@ -1717,7 +2070,7 @@ class ProgramManagerWithCacheTest : public GpuServiceTest { ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1); EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1); EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _)) - .WillOnce(SetArgumentPointee<2>(GL_TRUE)); + .WillOnce(SetArgPointee<2>(GL_TRUE)); } void SetExpectationsForNoCompile(const Shader* shader) { @@ -1737,9 +2090,9 @@ class ProgramManagerWithCacheTest : public GpuServiceTest { ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1); EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1); EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _)) - .WillOnce(SetArgumentPointee<2>(GL_FALSE)); + .WillOnce(SetArgPointee<2>(GL_FALSE)); EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_INFO_LOG_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(0)); + .WillOnce(SetArgPointee<2>(0)); EXPECT_CALL(*gl_.get(), GetShaderInfoLog(shader_id, 0, _, _)) .Times(1); } @@ -1767,8 +2120,8 @@ TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) { SetShadersCompiled(); SetExpectationsForProgramLink(); SetExpectationsForProgramCached(); - EXPECT_TRUE(program_->Link(NULL, NULL, NULL, - Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb))); + EXPECT_TRUE(program_->Link(NULL, Program::kCountOnlyStaticallyUsed, + base::Bind(&ShaderCacheCb))); } TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) { @@ -1781,8 +2134,8 @@ TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) { SetExpectationsForNotCachingProgram(); SetExpectationsForProgramLoadSuccess(); - EXPECT_TRUE(program_->Link(NULL, NULL, NULL, - Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb))); + EXPECT_TRUE(program_->Link(NULL, Program::kCountOnlyStaticallyUsed, + base::Bind(&ShaderCacheCb))); } } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/query_manager.cc b/chromium/gpu/command_buffer/service/query_manager.cc index fdb5fa82f27..c74a65000c3 100644 --- a/chromium/gpu/command_buffer/service/query_manager.cc +++ b/chromium/gpu/command_buffer/service/query_manager.cc @@ -171,13 +171,13 @@ bool AllSamplesPassedQuery::End(base::subtle::Atomic32 submit_count) { bool AllSamplesPassedQuery::Process(bool did_finish) { GLuint available = 0; - glGetQueryObjectuivARB( + glGetQueryObjectuiv( service_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available); if (!available) { return true; } GLuint result = 0; - glGetQueryObjectuivARB( + glGetQueryObjectuiv( service_id_, GL_QUERY_RESULT_EXT, &result); return MarkAsCompleted(result != 0); @@ -185,7 +185,7 @@ bool AllSamplesPassedQuery::Process(bool did_finish) { void AllSamplesPassedQuery::Destroy(bool have_context) { if (have_context && !IsDeleted()) { - glDeleteQueriesARB(1, &service_id_); + glDeleteQueries(1, &service_id_); MarkAsDeleted(); } } @@ -216,12 +216,12 @@ CommandsIssuedQuery::CommandsIssuedQuery( } bool CommandsIssuedQuery::Begin() { - begin_time_ = base::TimeTicks::HighResNow(); + begin_time_ = base::TimeTicks::Now(); return true; } bool CommandsIssuedQuery::End(base::subtle::Atomic32 submit_count) { - base::TimeDelta elapsed = base::TimeTicks::HighResNow() - begin_time_; + base::TimeDelta elapsed = base::TimeTicks::Now() - begin_time_; MarkAsPending(submit_count); return MarkAsCompleted(elapsed.InMicroseconds()); } @@ -264,7 +264,7 @@ bool CommandLatencyQuery::Begin() { } bool CommandLatencyQuery::End(base::subtle::Atomic32 submit_count) { - base::TimeDelta now = base::TimeTicks::HighResNow() - base::TimeTicks(); + base::TimeDelta now = base::TimeTicks::Now() - base::TimeTicks(); MarkAsPending(submit_count); return MarkAsCompleted(now.InMicroseconds()); } @@ -408,6 +408,7 @@ class CommandsCompletedQuery : public QueryManager::Query { private: scoped_ptr<gfx::GLFence> fence_; + base::TimeTicks begin_time_; }; CommandsCompletedQuery::CommandsCompletedQuery(QueryManager* manager, @@ -416,7 +417,10 @@ CommandsCompletedQuery::CommandsCompletedQuery(QueryManager* manager, uint32 shm_offset) : Query(manager, target, shm_id, shm_offset) {} -bool CommandsCompletedQuery::Begin() { return true; } +bool CommandsCompletedQuery::Begin() { + begin_time_ = base::TimeTicks::Now(); + return true; +} bool CommandsCompletedQuery::End(base::subtle::Atomic32 submit_count) { fence_.reset(gfx::GLFence::Create()); @@ -428,13 +432,11 @@ bool CommandsCompletedQuery::Process(bool did_finish) { // Note: |did_finish| guarantees that the GPU has passed the fence but // we cannot assume that GLFence::HasCompleted() will return true yet as // that's not guaranteed by all GLFence implementations. - // - // TODO(reveman): Add UMA stats to determine how common it is that glFinish() - // needs to be called for these queries to complete. crbug.com/431845 if (!did_finish && fence_ && !fence_->HasCompleted()) return true; - return MarkAsCompleted(0); + base::TimeDelta elapsed = base::TimeTicks::Now() - begin_time_; + return MarkAsCompleted(elapsed.InMicroseconds()); } void CommandsCompletedQuery::Destroy(bool have_context) { @@ -506,7 +508,7 @@ QueryManager::Query* QueryManager::CreateQuery( break; default: { GLuint service_id = 0; - glGenQueriesARB(1, &service_id); + glGenQueries(1, &service_id); DCHECK_NE(0u, service_id); query = new AllSamplesPassedQuery( this, target, shm_id, shm_offset, service_id); @@ -580,12 +582,12 @@ GLenum QueryManager::AdjustTargetForEmulation(GLenum target) { void QueryManager::BeginQueryHelper(GLenum target, GLuint id) { target = AdjustTargetForEmulation(target); - glBeginQueryARB(target, id); + glBeginQuery(target, id); } void QueryManager::EndQueryHelper(GLenum target) { target = AdjustTargetForEmulation(target); - glEndQueryARB(target); + glEndQuery(target); } QueryManager::Query::Query( diff --git a/chromium/gpu/command_buffer/service/query_manager_unittest.cc b/chromium/gpu/command_buffer/service/query_manager_unittest.cc index 7c8e93cbc19..f6e36822195 100644 --- a/chromium/gpu/command_buffer/service/query_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/query_manager_unittest.cc @@ -38,7 +38,7 @@ class QueryManagerTest : public GpuServiceTest { protected: void SetUp() override { - GpuServiceTest::SetUp(); + GpuServiceTest::SetUpWithGLVersion("2.1", "GL_ARB_occlusion_query"); engine_.reset(new MockCommandBufferEngine()); decoder_.reset(new MockGLES2Decoder()); decoder_->set_engine(engine_.get()); @@ -61,7 +61,7 @@ class QueryManagerTest : public GpuServiceTest { QueryManager::Query* CreateQuery( GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset, GLuint service_id) { - EXPECT_CALL(*gl_, GenQueriesARB(1, _)) + EXPECT_CALL(*gl_, GenQueries(1, _)) .WillOnce(SetArgumentPointee<1>(service_id)) .RetiresOnSaturation(); return manager_->CreateQuery(target, client_id, shm_id, shm_offset); @@ -70,10 +70,10 @@ class QueryManagerTest : public GpuServiceTest { void QueueQuery(QueryManager::Query* query, GLuint service_id, base::subtle::Atomic32 submit_count) { - EXPECT_CALL(*gl_, BeginQueryARB(query->target(), service_id)) + EXPECT_CALL(*gl_, BeginQuery(query->target(), service_id)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, EndQueryARB(query->target())) + EXPECT_CALL(*gl_, EndQuery(query->target())) .Times(1) .RetiresOnSaturation(); EXPECT_TRUE(manager_->BeginQuery(query)); @@ -177,7 +177,7 @@ TEST_F(QueryManagerTest, Destroy) { CreateQuery(GL_ANY_SAMPLES_PASSED_EXT, kClient1Id, kSharedMemoryId, kSharedMemoryOffset, kService1Id)); ASSERT_TRUE(query.get() != NULL); - EXPECT_CALL(*gl_, DeleteQueriesARB(1, ::testing::Pointee(kService1Id))) + EXPECT_CALL(*gl_, DeleteQueries(1, ::testing::Pointee(kService1Id))) .Times(1) .RetiresOnSaturation(); manager_->Destroy(true); @@ -236,7 +236,7 @@ TEST_F(QueryManagerTest, ProcessPendingQuery) { // Process with return not available. // Expect 1 GL command. EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) .WillOnce(SetArgumentPointee<2>(0)) .RetiresOnSaturation(); EXPECT_TRUE(manager_->ProcessPendingQueries(false)); @@ -247,11 +247,11 @@ TEST_F(QueryManagerTest, ProcessPendingQuery) { // Process with return available. // Expect 2 GL commands. EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) .WillOnce(SetArgumentPointee<2>(1)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_EXT, _)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) .WillOnce(SetArgumentPointee<2>(kResult)) .RetiresOnSaturation(); EXPECT_TRUE(manager_->ProcessPendingQueries(false)); @@ -323,23 +323,23 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) { { InSequence s; EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) .WillOnce(SetArgumentPointee<2>(1)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_EXT, _)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) .WillOnce(SetArgumentPointee<2>(kResult1)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService2Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) .WillOnce(SetArgumentPointee<2>(1)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService2Id, GL_QUERY_RESULT_EXT, _)) + GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_EXT, _)) .WillOnce(SetArgumentPointee<2>(kResult2)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) .WillOnce(SetArgumentPointee<2>(0)) .RetiresOnSaturation(); EXPECT_TRUE(manager_->ProcessPendingQueries(false)); @@ -358,7 +358,7 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) { // Process with renaming query. No result. // Expect 1 GL commands. EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) .WillOnce(SetArgumentPointee<2>(0)) .RetiresOnSaturation(); EXPECT_TRUE(manager_->ProcessPendingQueries(false)); @@ -370,11 +370,11 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) { // Process with renaming query. With result. // Expect 2 GL commands. EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) .WillOnce(SetArgumentPointee<2>(1)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService3Id, GL_QUERY_RESULT_EXT, _)) + GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_EXT, _)) .WillOnce(SetArgumentPointee<2>(kResult3)) .RetiresOnSaturation(); EXPECT_TRUE(manager_->ProcessPendingQueries(false)); @@ -403,11 +403,11 @@ TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryId) { // Process with return available. // Expect 2 GL commands. EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) .WillOnce(SetArgumentPointee<2>(1)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_EXT, _)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) .WillOnce(SetArgumentPointee<2>(kResult)) .RetiresOnSaturation(); EXPECT_FALSE(manager_->ProcessPendingQueries(false)); @@ -432,11 +432,11 @@ TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryOffset) { // Process with return available. // Expect 2 GL commands. EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) .WillOnce(SetArgumentPointee<2>(1)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, - GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_EXT, _)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) .WillOnce(SetArgumentPointee<2>(kResult)) .RetiresOnSaturation(); EXPECT_FALSE(manager_->ProcessPendingQueries(false)); @@ -474,17 +474,17 @@ TEST_F(QueryManagerTest, ARBOcclusionQuery2) { scoped_ptr<QueryManager> manager( new QueryManager(decoder_.get(), feature_info.get())); - EXPECT_CALL(*gl_, GenQueriesARB(1, _)) + EXPECT_CALL(*gl_, GenQueries(1, _)) .WillOnce(SetArgumentPointee<1>(kService1Id)) .RetiresOnSaturation(); QueryManager::Query* query = manager->CreateQuery( kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); - EXPECT_CALL(*gl_, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, kService1Id)) + EXPECT_CALL(*gl_, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT, kService1Id)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT)) + EXPECT_CALL(*gl_, EndQuery(GL_ANY_SAMPLES_PASSED_EXT)) .Times(1) .RetiresOnSaturation(); EXPECT_TRUE(manager->BeginQuery(query)); @@ -508,17 +508,17 @@ TEST_F(QueryManagerTest, ARBOcclusionQuery) { scoped_ptr<QueryManager> manager( new QueryManager(decoder_.get(), feature_info.get())); - EXPECT_CALL(*gl_, GenQueriesARB(1, _)) + EXPECT_CALL(*gl_, GenQueries(1, _)) .WillOnce(SetArgumentPointee<1>(kService1Id)) .RetiresOnSaturation(); QueryManager::Query* query = manager->CreateQuery( kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); - EXPECT_CALL(*gl_, BeginQueryARB(GL_SAMPLES_PASSED_ARB, kService1Id)) + EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService1Id)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, EndQueryARB(GL_SAMPLES_PASSED_ARB)) + EXPECT_CALL(*gl_, EndQuery(GL_SAMPLES_PASSED_ARB)) .Times(1) .RetiresOnSaturation(); EXPECT_TRUE(manager->BeginQuery(query)); diff --git a/chromium/gpu/command_buffer/service/renderbuffer_manager.cc b/chromium/gpu/command_buffer/service/renderbuffer_manager.cc index ff8ae7b48f1..2af22de12c0 100644 --- a/chromium/gpu/command_buffer/service/renderbuffer_manager.cc +++ b/chromium/gpu/command_buffer/service/renderbuffer_manager.cc @@ -3,10 +3,12 @@ // found in the LICENSE file. #include "gpu/command_buffer/service/renderbuffer_manager.h" -#include "base/debug/trace_event.h" + #include "base/logging.h" #include "base/strings/stringprintf.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "ui/gl/gl_implementation.h" @@ -42,12 +44,12 @@ RenderbufferManager::RenderbufferManager( MemoryTracker* memory_tracker, GLint max_renderbuffer_size, GLint max_samples, - bool depth24_supported) + FeatureInfo* feature_info) : memory_tracker_( new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)), max_renderbuffer_size_(max_renderbuffer_size), max_samples_(max_samples), - depth24_supported_(depth24_supported), + feature_info_(feature_info), num_uncleared_renderbuffers_(0), renderbuffer_count_(0), have_context_(true) { @@ -209,7 +211,7 @@ bool RenderbufferManager::ComputeEstimatedRenderbufferSize(int width, GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat( GLenum impl_format) const { - if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { + if (!feature_info_->gl_version_info().BehavesLikeGLES()) { switch (impl_format) { case GL_DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT; @@ -221,7 +223,8 @@ GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat( } } else { // Upgrade 16-bit depth to 24-bit if possible. - if (impl_format == GL_DEPTH_COMPONENT16 && depth24_supported_) + if (impl_format == GL_DEPTH_COMPONENT16 && + feature_info_->feature_flags().oes_depth24) return GL_DEPTH_COMPONENT24; } return impl_format; diff --git a/chromium/gpu/command_buffer/service/renderbuffer_manager.h b/chromium/gpu/command_buffer/service/renderbuffer_manager.h index 71f830a559a..be4cc0974e4 100644 --- a/chromium/gpu/command_buffer/service/renderbuffer_manager.h +++ b/chromium/gpu/command_buffer/service/renderbuffer_manager.h @@ -17,6 +17,7 @@ namespace gpu { namespace gles2 { +class FeatureInfo; class RenderbufferManager; // Info about a Renderbuffer. @@ -128,7 +129,7 @@ class GPU_EXPORT RenderbufferManager { RenderbufferManager(MemoryTracker* memory_tracker, GLint max_renderbuffer_size, GLint max_samples, - bool depth24_supported); + FeatureInfo* feature_info); ~RenderbufferManager(); GLint max_renderbuffer_size() const { @@ -182,7 +183,8 @@ class GPU_EXPORT RenderbufferManager { GLint max_renderbuffer_size_; GLint max_samples_; - bool depth24_supported_; + + scoped_refptr<FeatureInfo> feature_info_; int num_uncleared_renderbuffers_; diff --git a/chromium/gpu/command_buffer/service/renderbuffer_manager_unittest.cc b/chromium/gpu/command_buffer/service/renderbuffer_manager_unittest.cc index 7c625e6c716..7633f681571 100644 --- a/chromium/gpu/command_buffer/service/renderbuffer_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/renderbuffer_manager_unittest.cc @@ -6,8 +6,10 @@ #include <set> #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gpu_service_test.h" #include "gpu/command_buffer/service/mocks.h" +#include "gpu/command_buffer/service/test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_mock.h" @@ -23,10 +25,19 @@ class RenderbufferManagerTestBase : public GpuServiceTest { static const GLint kMaxSamples = 4; protected: - void SetUpBase(MemoryTracker* memory_tracker, bool depth24_supported) { + void SetUpBase(MemoryTracker* memory_tracker, + bool depth24_supported, + bool use_gles) { GpuServiceTest::SetUp(); + feature_info_ = new FeatureInfo(); + TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( + gl_.get(), + depth24_supported ? "GL_OES_depth24" : "", + "", + use_gles ? "OpenGL ES 2.0" : "OpenGL 2.1"); + feature_info_->Initialize(); manager_.reset(new RenderbufferManager( - memory_tracker, kMaxSize, kMaxSamples, depth24_supported)); + memory_tracker, kMaxSize, kMaxSamples, feature_info_.get())); } void TearDown() override { @@ -35,6 +46,7 @@ class RenderbufferManagerTestBase : public GpuServiceTest { GpuServiceTest::TearDown(); } + scoped_refptr<FeatureInfo> feature_info_; scoped_ptr<RenderbufferManager> manager_; }; @@ -42,7 +54,8 @@ class RenderbufferManagerTest : public RenderbufferManagerTestBase { protected: void SetUp() override { bool depth24_supported = false; - SetUpBase(NULL, depth24_supported); + bool use_gles = false; + SetUpBase(NULL, depth24_supported, use_gles); } }; @@ -52,7 +65,8 @@ class RenderbufferManagerMemoryTrackerTest void SetUp() override { mock_memory_tracker_ = new StrictMock<MockMemoryTracker>(); bool depth24_supported = false; - SetUpBase(mock_memory_tracker_.get(), depth24_supported); + bool use_gles = false; + SetUpBase(mock_memory_tracker_.get(), depth24_supported, use_gles); } scoped_refptr<MockMemoryTracker> mock_memory_tracker_; @@ -291,29 +305,34 @@ TEST_F(RenderbufferManagerTest, AddToSignature) { .RetiresOnSaturation(); } -class RenderbufferManagerFormatTest : public RenderbufferManagerTestBase { +class RenderbufferManagerFormatGLESTest : public RenderbufferManagerTestBase { protected: void SetUp() override { bool depth24_supported = true; - SetUpBase(NULL, depth24_supported); + bool use_gles = true; + SetUpBase(NULL, depth24_supported, use_gles); } }; -TEST_F(RenderbufferManagerFormatTest, UpgradeDepthFormatOnGLES) { - gfx::GLImplementation prev_impl = gfx::GetGLImplementation(); - gfx::SetGLImplementation(gfx::kGLImplementationEGLGLES2); +TEST_F(RenderbufferManagerFormatGLESTest, UpgradeDepthFormatOnGLES) { GLenum impl_format = manager_->InternalRenderbufferFormatToImplFormat(GL_DEPTH_COMPONENT16); - gfx::SetGLImplementation(prev_impl); EXPECT_EQ(static_cast<GLenum>(GL_DEPTH_COMPONENT24), impl_format); } -TEST_F(RenderbufferManagerFormatTest, UseUnsizedDepthFormatOnNonGLES) { - gfx::GLImplementation prev_impl = gfx::GetGLImplementation(); - gfx::SetGLImplementation(gfx::kGLImplementationDesktopGL); +class RenderbufferManagerFormatNonGLESTest : + public RenderbufferManagerTestBase { + protected: + void SetUp() override { + bool depth24_supported = true; + bool use_gles = false; + SetUpBase(NULL, depth24_supported, use_gles); + } +}; + +TEST_F(RenderbufferManagerFormatNonGLESTest, UseUnsizedDepthFormatOnNonGLES) { GLenum impl_format = manager_->InternalRenderbufferFormatToImplFormat(GL_DEPTH_COMPONENT16); - gfx::SetGLImplementation(prev_impl); EXPECT_EQ(static_cast<GLenum>(GL_DEPTH_COMPONENT), impl_format); } diff --git a/chromium/gpu/command_buffer/service/shader_manager.cc b/chromium/gpu/command_buffer/service/shader_manager.cc index 2707b90b92d..23018ee2688 100644 --- a/chromium/gpu/command_buffer/service/shader_manager.cc +++ b/chromium/gpu/command_buffer/service/shader_manager.cc @@ -26,69 +26,112 @@ std::string GetTopVariableName(const std::string& fullname) { Shader::Shader(GLuint service_id, GLenum shader_type) : use_count_(0), + shader_state_(kShaderStateWaiting), + marked_for_deletion_(false), service_id_(service_id), shader_type_(shader_type), + shader_version_(kUndefinedShaderVersion), + source_type_(kANGLE), valid_(false) { } Shader::~Shader() { } -void Shader::DoCompile(ShaderTranslatorInterface* translator, - TranslatedShaderSourceType type) { +void Shader::Destroy() { + if (service_id_) { + DeleteServiceID(); + } +} + +void Shader::RequestCompile(scoped_refptr<ShaderTranslatorInterface> translator, + TranslatedShaderSourceType type) { + shader_state_ = kShaderStateCompileRequested; + translator_ = translator; + source_type_ = type; + last_compiled_source_ = source_; +} + +void Shader::DoCompile() { + // We require that RequestCompile() must be called before DoCompile(), + // so we can return early if the shader state is not what we expect. + if (shader_state_ != kShaderStateCompileRequested) { + return; + } + + // Signify the shader has been compiled, whether or not it is valid + // is dependent on the |valid_| member variable. + shader_state_ = kShaderStateCompiled; + valid_ = false; + // Translate GL ES 2.0 shader to Desktop GL shader and pass that to // glShaderSource and then glCompileShader. - const char* source_for_driver = source_.c_str(); + const char* source_for_driver = last_compiled_source_.c_str(); + ShaderTranslatorInterface* translator = translator_.get(); if (translator) { - valid_ = translator->Translate(source_, - &log_info_, - &translated_source_, - &attrib_map_, - &uniform_map_, - &varying_map_, - &name_map_); - if (!valid_) { + bool success = translator->Translate(last_compiled_source_, + &log_info_, + &translated_source_, + &shader_version_, + &attrib_map_, + &uniform_map_, + &varying_map_, + &name_map_); + if (!success) { return; } - signature_source_ = source_; source_for_driver = translated_source_.c_str(); } glShaderSource(service_id_, 1, &source_for_driver, NULL); glCompileShader(service_id_); - if (type == kANGLE) { + if (source_type_ == kANGLE) { GLint max_len = 0; glGetShaderiv(service_id_, GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, &max_len); - scoped_ptr<char[]> buffer(new char[max_len]); - GLint len = 0; - glGetTranslatedShaderSourceANGLE( - service_id_, max_len, &len, buffer.get()); - DCHECK(max_len == 0 || len < max_len); - DCHECK(len == 0 || buffer[len] == '\0'); - translated_source_ = std::string(buffer.get(), len); + source_for_driver = "\0"; + translated_source_.resize(max_len); + if (max_len) { + GLint len = 0; + glGetTranslatedShaderSourceANGLE( + service_id_, translated_source_.size(), + &len, &translated_source_.at(0)); + DCHECK(max_len == 0 || len < max_len); + DCHECK(len == 0 || translated_source_[len] == '\0'); + translated_source_.resize(len); + source_for_driver = translated_source_.c_str(); + } } GLint status = GL_FALSE; glGetShaderiv(service_id_, GL_COMPILE_STATUS, &status); - if (status != GL_TRUE) { + if (status == GL_TRUE) { + valid_ = true; + } else { + valid_ = false; + // We cannot reach here if we are using the shader translator. // All invalid shaders must be rejected by the translator. // All translated shaders must compile. + std::string translator_log = log_info_; + GLint max_len = 0; glGetShaderiv(service_id_, GL_INFO_LOG_LENGTH, &max_len); - scoped_ptr<char[]> buffer(new char[max_len]); - GLint len = 0; - glGetShaderInfoLog(service_id_, max_len, &len, buffer.get()); - DCHECK(max_len == 0 || len < max_len); - DCHECK(len == 0 || buffer[len] == '\0'); - valid_ = false; - log_info_ = std::string(buffer.get(), len); + log_info_.resize(max_len); + if (max_len) { + GLint len = 0; + glGetShaderInfoLog(service_id_, log_info_.size(), &len, &log_info_.at(0)); + DCHECK(max_len == 0 || len < max_len); + DCHECK(len == 0 || log_info_[len] == '\0'); + log_info_.resize(len); + } + LOG_IF(ERROR, translator) << "Shader translator allowed/produced an invalid shader " << "unless the driver is buggy:" - << "\n--original-shader--\n" << source_ + << "\n--Log from shader translator--\n" << translator_log + << "\n--original-shader--\n" << last_compiled_source_ << "\n--translated-shader--\n" << source_for_driver << "\n--info-log--\n" << log_info_; } @@ -101,10 +144,24 @@ void Shader::IncUseCount() { void Shader::DecUseCount() { --use_count_; DCHECK_GE(use_count_, 0); + if (service_id_ && use_count_ == 0 && marked_for_deletion_) { + DeleteServiceID(); + } +} + +void Shader::MarkForDeletion() { + DCHECK(!marked_for_deletion_); + DCHECK_NE(service_id_, 0u); + + marked_for_deletion_ = true; + if (use_count_ == 0) { + DeleteServiceID(); + } } -void Shader::MarkAsDeleted() { +void Shader::DeleteServiceID() { DCHECK_NE(service_id_, 0u); + glDeleteShader(service_id_); service_id_ = 0; } @@ -154,10 +211,7 @@ void ShaderManager::Destroy(bool have_context) { while (!shaders_.empty()) { if (have_context) { Shader* shader = shaders_.begin()->second.get(); - if (!shader->IsDeleted()) { - glDeleteShader(shader->service_id()); - shader->MarkAsDeleted(); - } + shader->Destroy(); } shaders_.erase(shaders_.begin()); } @@ -217,10 +271,10 @@ void ShaderManager::RemoveShader(Shader* shader) { } } -void ShaderManager::MarkAsDeleted(Shader* shader) { +void ShaderManager::Delete(Shader* shader) { DCHECK(shader); DCHECK(IsOwned(shader)); - shader->MarkAsDeleted(); + shader->MarkForDeletion(); RemoveShader(shader); } @@ -239,5 +293,3 @@ void ShaderManager::UnuseShader(Shader* shader) { } // namespace gles2 } // namespace gpu - - diff --git a/chromium/gpu/command_buffer/service/shader_manager.h b/chromium/gpu/command_buffer/service/shader_manager.h index c726767f348..c7355a815cc 100644 --- a/chromium/gpu/command_buffer/service/shader_manager.h +++ b/chromium/gpu/command_buffer/service/shader_manager.h @@ -29,17 +29,35 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { kGL, // GL or GLES }; - void DoCompile(ShaderTranslatorInterface* translator, - TranslatedShaderSourceType type); + enum ShaderState { + kShaderStateWaiting, + kShaderStateCompileRequested, + kShaderStateCompiled, // Signifies compile happened, not valid compile. + }; + + static const int kUndefinedShaderVersion = -1; + + void RequestCompile(scoped_refptr<ShaderTranslatorInterface> translator, + TranslatedShaderSourceType type); + + void DoCompile(); + + ShaderState shader_state() const { + return shader_state_; + } GLuint service_id() const { - return service_id_; + return marked_for_deletion_ ? 0 : service_id_; } GLenum shader_type() const { return shader_type_; } + int shader_version() const { + return shader_version_; + } + const std::string& source() const { return source_; } @@ -52,8 +70,16 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { return translated_source_; } - const std::string& signature_source() const { - return signature_source_; + std::string last_compiled_source() const { + return last_compiled_source_; + } + + std::string last_compiled_signature() const { + if (translator_.get()) { + return last_compiled_source_ + + translator_->GetStringForOptionsThatWouldAffectCompilation(); + } + return last_compiled_source_; } const sh::Attribute* GetAttribInfo(const std::string& name) const; @@ -73,11 +99,11 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { } bool valid() const { - return valid_; + return shader_state_ == kShaderStateCompiled && valid_; } bool IsDeleted() const { - return service_id_ == 0; + return marked_for_deletion_; } bool InUse() const { @@ -125,17 +151,39 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { Shader(GLuint service_id, GLenum shader_type); ~Shader(); + // Must be called only if we currently own the context. Forces the deletion + // of the underlying shader service id. + void Destroy(); + void IncUseCount(); void DecUseCount(); - void MarkAsDeleted(); + void MarkForDeletion(); + void DeleteServiceID(); int use_count_; + // The current state of the shader. + ShaderState shader_state_; + + // The shader has been marked for deletion. + bool marked_for_deletion_; + // The shader this Shader is tracking. GLuint service_id_; + // Type of shader - GL_VERTEX_SHADER or GL_FRAGMENT_SHADER. GLenum shader_type_; + // Version of the shader. Can be kUndefinedShaderVersion or version returned + // by ANGLE. + int shader_version_; + + // Translated source type when shader was last requested to be compiled. + TranslatedShaderSourceType source_type_; + + // Translator to use, set when shader was last requested to be compiled. + scoped_refptr<ShaderTranslatorInterface> translator_; + // True if compilation succeeded. bool valid_; @@ -143,7 +191,7 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { std::string source_; // The source the last compile used. - std::string signature_source_; + std::string last_compiled_source_; // The translated shader source. std::string translated_source_; @@ -185,7 +233,7 @@ class GPU_EXPORT ShaderManager { // Gets a client id for a given service id. bool GetClientId(GLuint service_id, GLuint* client_id) const; - void MarkAsDeleted(Shader* shader); + void Delete(Shader* shader); // Mark a shader as used void UseShader(Shader* shader); diff --git a/chromium/gpu/command_buffer/service/shader_manager_unittest.cc b/chromium/gpu/command_buffer/service/shader_manager_unittest.cc index 4218d504c68..87729b1babc 100644 --- a/chromium/gpu/command_buffer/service/shader_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/shader_manager_unittest.cc @@ -43,7 +43,10 @@ TEST_F(ShaderManagerTest, Basic) { // Check we get nothing for a non-existent shader. EXPECT_TRUE(manager_.GetShader(kClient2Id) == NULL); // Check we can't get the shader after we remove it. - manager_.MarkAsDeleted(shader1); + EXPECT_CALL(*gl_, DeleteShader(kService1Id)) + .Times(1) + .RetiresOnSaturation(); + manager_.Delete(shader1); EXPECT_TRUE(manager_.GetShader(kClient1Id) == NULL); } @@ -79,10 +82,19 @@ TEST_F(ShaderManagerTest, DeleteBug) { ASSERT_TRUE(shader1.get()); ASSERT_TRUE(shader2.get()); manager_.UseShader(shader1.get()); - manager_.MarkAsDeleted(shader1.get()); - manager_.MarkAsDeleted(shader2.get()); + manager_.Delete(shader1.get()); + + EXPECT_CALL(*gl_, DeleteShader(kService2Id)) + .Times(1) + .RetiresOnSaturation(); + manager_.Delete(shader2.get()); EXPECT_TRUE(manager_.IsOwned(shader1.get())); EXPECT_FALSE(manager_.IsOwned(shader2.get())); + + EXPECT_CALL(*gl_, DeleteShader(kService1Id)) + .Times(1) + .RetiresOnSaturation(); + manager_.UnuseShader(shader1.get()); } TEST_F(ShaderManagerTest, DoCompile) { @@ -127,16 +139,30 @@ TEST_F(ShaderManagerTest, DoCompile) { EXPECT_FALSE(shader1->InUse()); EXPECT_TRUE(shader1->source().empty()); EXPECT_TRUE(shader1->log_info().empty()); - EXPECT_TRUE(shader1->signature_source().empty()); + EXPECT_TRUE(shader1->last_compiled_source().empty()); EXPECT_TRUE(shader1->translated_source().empty()); EXPECT_EQ(0u, shader1->attrib_map().size()); EXPECT_EQ(0u, shader1->uniform_map().size()); EXPECT_EQ(0u, shader1->varying_map().size()); + EXPECT_EQ(Shader::kShaderStateWaiting, shader1->shader_state()); // Check we can set its source. shader1->set_source(kClient1Source); EXPECT_STREQ(kClient1Source, shader1->source().c_str()); - EXPECT_TRUE(shader1->signature_source().empty()); + EXPECT_TRUE(shader1->last_compiled_source().empty()); + + // Check that DoCompile() will not work if RequestCompile() was not called. + shader1->DoCompile(); + EXPECT_EQ(Shader::kShaderStateWaiting, shader1->shader_state()); + EXPECT_FALSE(shader1->valid()); + + // Check RequestCompile() will update the state and last compiled source, but + // still keep the actual compile state invalid. + scoped_refptr<ShaderTranslatorInterface> translator(new MockShaderTranslator); + shader1->RequestCompile(translator, Shader::kANGLE); + EXPECT_EQ(Shader::kShaderStateCompileRequested, shader1->shader_state()); + EXPECT_STREQ(kClient1Source, shader1->last_compiled_source().c_str()); + EXPECT_FALSE(shader1->valid()); // Check DoCompile() will set compilation states, log, translated source, // shader variables, and name mapping. @@ -163,12 +189,12 @@ TEST_F(ShaderManagerTest, DoCompile) { kVarying1StaticUse, kVarying1Name); TestHelper::SetShaderStates( - gl_.get(), shader1, true, &kLog, &kTranslatedSource, + gl_.get(), shader1, true, &kLog, &kTranslatedSource, NULL, &attrib_map, &uniform_map, &varying_map, NULL); EXPECT_TRUE(shader1->valid()); // When compilation succeeds, no log is recorded. EXPECT_STREQ("", shader1->log_info().c_str()); - EXPECT_STREQ(kClient1Source, shader1->signature_source().c_str()); + EXPECT_STREQ(kClient1Source, shader1->last_compiled_source().c_str()); EXPECT_STREQ(kTranslatedSource.c_str(), shader1->translated_source().c_str()); // Check varying infos got copied. @@ -210,7 +236,7 @@ TEST_F(ShaderManagerTest, DoCompile) { // Compile failure case. TestHelper::SetShaderStates( - gl_.get(), shader1, false, &kLog, &kTranslatedSource, + gl_.get(), shader1, false, &kLog, &kTranslatedSource, NULL, &attrib_map, &uniform_map, &varying_map, NULL); EXPECT_FALSE(shader1->valid()); EXPECT_STREQ(kLog.c_str(), shader1->log_info().c_str()); @@ -235,7 +261,10 @@ TEST_F(ShaderManagerTest, ShaderInfoUseCount) { EXPECT_TRUE(shader1->InUse()); manager_.UseShader(shader1); EXPECT_TRUE(shader1->InUse()); - manager_.MarkAsDeleted(shader1); + EXPECT_CALL(*gl_, DeleteShader(kService1Id)) + .Times(1) + .RetiresOnSaturation(); + manager_.Delete(shader1); EXPECT_TRUE(shader1->IsDeleted()); Shader* shader2 = manager_.GetShader(kClient1Id); EXPECT_EQ(shader1, shader2); @@ -258,7 +287,10 @@ TEST_F(ShaderManagerTest, ShaderInfoUseCount) { EXPECT_FALSE(shader1->InUse()); shader2 = manager_.GetShader(kClient1Id); EXPECT_EQ(shader1, shader2); - manager_.MarkAsDeleted(shader1); // this should delete the shader. + EXPECT_CALL(*gl_, DeleteShader(kService1Id)) + .Times(1) + .RetiresOnSaturation(); + manager_.Delete(shader1); // this should delete the shader. shader2 = manager_.GetShader(kClient1Id); EXPECT_TRUE(shader2 == NULL); } diff --git a/chromium/gpu/command_buffer/service/shader_translator.cc b/chromium/gpu/command_buffer/service/shader_translator.cc index f719f7d9976..dd1c710c0fe 100644 --- a/chromium/gpu/command_buffer/service/shader_translator.cc +++ b/chromium/gpu/command_buffer/service/shader_translator.cc @@ -9,10 +9,13 @@ #include <algorithm> #include "base/at_exit.h" -#include "base/debug/trace_event.h" +#include "base/command_line.h" #include "base/lazy_instance.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" +#include "base/trace_event/trace_event.h" +#include "gpu/command_buffer/service/gpu_switches.h" +#include "ui/gl/gl_implementation.h" namespace gpu { namespace gles2 { @@ -108,20 +111,32 @@ bool ShaderTranslator::Init( // Make sure Init is called only once. DCHECK(compiler_ == NULL); DCHECK(shader_type == GL_FRAGMENT_SHADER || shader_type == GL_VERTEX_SHADER); - DCHECK(shader_spec == SH_GLES2_SPEC || shader_spec == SH_WEBGL_SPEC); + DCHECK(shader_spec == SH_GLES2_SPEC || shader_spec == SH_WEBGL_SPEC || + shader_spec == SH_GLES3_SPEC || shader_spec == SH_WEBGL2_SPEC); DCHECK(resources != NULL); g_translator_initializer.Get(); - ShShaderOutput shader_output = - (glsl_implementation_type == kGlslES ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT); + ShShaderOutput shader_output; + if (glsl_implementation_type == kGlslES) { + shader_output = SH_ESSL_OUTPUT; + } else { + // TODO(kbr): clean up the tests of shader_spec and + // gfx::GetGLImplementation(). crbug.com/471960 + if (shader_spec == SH_WEBGL2_SPEC || + gfx::GetGLImplementation() == + gfx::kGLImplementationDesktopGLCoreProfile) { + shader_output = SH_GLSL_CORE_OUTPUT; + } else { + shader_output = SH_GLSL_COMPATIBILITY_OUTPUT; + } + } { TRACE_EVENT0("gpu", "ShConstructCompiler"); compiler_ = ShConstructCompiler( shader_type, shader_spec, shader_output, resources); } - compiler_options_ = *resources; implementation_is_glsl_es_ = (glsl_implementation_type == kGlslES); driver_bug_workarounds_ = driver_bug_workarounds; return compiler_ != NULL; @@ -133,6 +148,10 @@ int ShaderTranslator::GetCompileOptions() const { SH_LIMIT_EXPRESSION_COMPLEXITY | SH_LIMIT_CALL_STACK_DEPTH | SH_CLAMP_INDIRECT_ARRAY_BOUNDS; + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kGLShaderIntermOutput)) + compile_options |= SH_INTERMEDIATE_TREE; + compile_options |= driver_bug_workarounds_; return compile_options; @@ -141,6 +160,7 @@ int ShaderTranslator::GetCompileOptions() const { bool ShaderTranslator::Translate(const std::string& shader_source, std::string* info_log, std::string* translated_source, + int* shader_version, AttributeMap* attrib_map, UniformMap* uniform_map, VaryingMap* varying_map, @@ -160,6 +180,8 @@ bool ShaderTranslator::Translate(const std::string& shader_source, if (translated_source) { *translated_source = ShGetObjectCode(compiler_); } + // Get shader version. + *shader_version = ShGetShaderVersion(compiler_); // Get info for attribs, uniforms, and varyings. GetAttributes(compiler_, attrib_map); GetUniforms(compiler_, uniform_map); diff --git a/chromium/gpu/command_buffer/service/shader_translator.h b/chromium/gpu/command_buffer/service/shader_translator.h index 6075896b666..ac431e3e615 100644 --- a/chromium/gpu/command_buffer/service/shader_translator.h +++ b/chromium/gpu/command_buffer/service/shader_translator.h @@ -27,8 +27,10 @@ typedef base::hash_map<std::string, std::string> NameMap; // Translates a GLSL ES 2.0 shader to desktop GLSL shader, or just // validates GLSL ES 2.0 shaders on a true GLSL ES implementation. -class ShaderTranslatorInterface { +class ShaderTranslatorInterface + : public base::RefCounted<ShaderTranslatorInterface> { public: + ShaderTranslatorInterface() {} enum GlslImplementationType { kGlsl, kGlslES @@ -51,6 +53,7 @@ class ShaderTranslatorInterface { virtual bool Translate(const std::string& shader_source, std::string* info_log, std::string* translated_shader, + int* shader_version, AttributeMap* attrib_map, UniformMap* uniform_map, VaryingMap* varying_map, @@ -62,12 +65,15 @@ class ShaderTranslatorInterface { protected: virtual ~ShaderTranslatorInterface() {} + + private: + friend class base::RefCounted<ShaderTranslatorInterface>; + DISALLOW_COPY_AND_ASSIGN(ShaderTranslatorInterface); }; // Implementation of ShaderTranslatorInterface class GPU_EXPORT ShaderTranslator - : public base::RefCounted<ShaderTranslator>, - NON_EXPORTED_BASE(public ShaderTranslatorInterface) { + : NON_EXPORTED_BASE(public ShaderTranslatorInterface) { public: class DestructionObserver { public: @@ -93,6 +99,7 @@ class GPU_EXPORT ShaderTranslator bool Translate(const std::string& shader_source, std::string* info_log, std::string* translated_source, + int* shader_version, AttributeMap* attrib_map, UniformMap* uniform_map, VaryingMap* varying_map, @@ -104,18 +111,14 @@ class GPU_EXPORT ShaderTranslator void RemoveDestructionObserver(DestructionObserver* observer); private: - friend class base::RefCounted<ShaderTranslator>; - ~ShaderTranslator() override; + int GetCompileOptions() const; ShHandle compiler_; - ShBuiltInResources compiler_options_; bool implementation_is_glsl_es_; ShCompileOptions driver_bug_workarounds_; ObserverList<DestructionObserver> destruction_observers_; - - DISALLOW_COPY_AND_ASSIGN(ShaderTranslator); }; } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/shader_translator_cache.h b/chromium/gpu/command_buffer/service/shader_translator_cache.h index e804ef26b8c..6b0b1a57ef3 100644 --- a/chromium/gpu/command_buffer/service/shader_translator_cache.h +++ b/chromium/gpu/command_buffer/service/shader_translator_cache.h @@ -41,6 +41,7 @@ class GPU_EXPORT ShaderTranslatorCache private: friend class base::RefCounted<ShaderTranslatorCache>; + friend class ShaderTranslatorCacheTest_InitParamComparable_Test; ~ShaderTranslatorCache() override; // Parameters passed into ShaderTranslator::Init @@ -52,18 +53,18 @@ class GPU_EXPORT ShaderTranslatorCache glsl_implementation_type; ShCompileOptions driver_bug_workarounds; - ShaderTranslatorInitParams( - sh::GLenum shader_type, - ShShaderSpec shader_spec, - const ShBuiltInResources& resources, - ShaderTranslatorInterface::GlslImplementationType - glsl_implementation_type, - ShCompileOptions driver_bug_workarounds) - : shader_type(shader_type), - shader_spec(shader_spec), - resources(resources), - glsl_implementation_type(glsl_implementation_type), - driver_bug_workarounds(driver_bug_workarounds) { + ShaderTranslatorInitParams(sh::GLenum shader_type, + ShShaderSpec shader_spec, + const ShBuiltInResources& resources, + ShaderTranslatorInterface::GlslImplementationType + glsl_implementation_type, + ShCompileOptions driver_bug_workarounds) { + memset(this, 0, sizeof(*this)); + this->shader_type = shader_type; + this->shader_spec = shader_spec; + this->resources = resources; + this->glsl_implementation_type = glsl_implementation_type; + this->driver_bug_workarounds = driver_bug_workarounds; } ShaderTranslatorInitParams(const ShaderTranslatorInitParams& params) { @@ -77,6 +78,10 @@ class GPU_EXPORT ShaderTranslatorCache bool operator< (const ShaderTranslatorInitParams& params) const { return memcmp(¶ms, this, sizeof(*this)) < 0; } + + private: + ShaderTranslatorInitParams(); + ShaderTranslatorInitParams& operator=(const ShaderTranslatorInitParams&); }; typedef std::map<ShaderTranslatorInitParams, ShaderTranslator* > Cache; diff --git a/chromium/gpu/command_buffer/service/shader_translator_cache_unittest.cc b/chromium/gpu/command_buffer/service/shader_translator_cache_unittest.cc new file mode 100644 index 00000000000..c5233e510e8 --- /dev/null +++ b/chromium/gpu/command_buffer/service/shader_translator_cache_unittest.cc @@ -0,0 +1,56 @@ +// Copyright (c) 2014 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 <GLES2/gl2.h> + +#include "gpu/command_buffer/service/shader_translator_cache.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { +namespace gles2 { + +TEST(ShaderTranslatorCacheTest, InitParamComparable) { + // Tests that ShaderTranslatorInitParams padding or padding of its + // members does not affect the object equality or ordering. + + ShBuiltInResources a_resources; + memset(&a_resources, 88, sizeof(a_resources)); + ShInitBuiltInResources(&a_resources); + + ShBuiltInResources b_resources; + memset(&b_resources, 77, sizeof(b_resources)); + ShInitBuiltInResources(&b_resources); + + EXPECT_TRUE(memcmp(&a_resources, &b_resources, sizeof(a_resources)) == 0); + + ShCompileOptions driver_bug_workarounds = SH_VALIDATE; + + char a_storage[sizeof(ShaderTranslatorCache::ShaderTranslatorInitParams)]; + memset(a_storage, 55, sizeof(a_storage)); + ShaderTranslatorCache::ShaderTranslatorInitParams* a = + new (&a_storage) ShaderTranslatorCache::ShaderTranslatorInitParams( + GL_VERTEX_SHADER, + SH_GLES2_SPEC, + a_resources, + ShaderTranslatorInterface::kGlslES, + driver_bug_workarounds); + + ShaderTranslatorCache::ShaderTranslatorInitParams b( + GL_VERTEX_SHADER, + SH_GLES2_SPEC, + b_resources, + ShaderTranslatorInterface::kGlslES, + driver_bug_workarounds); + + EXPECT_TRUE(*a == b); + EXPECT_FALSE(*a < b || b < *a); + + memset(a_storage, 55, sizeof(a_storage)); + a = new (&a_storage) ShaderTranslatorCache::ShaderTranslatorInitParams(b); + + EXPECT_TRUE(*a == b); + EXPECT_FALSE(*a < b || b < *a); +} +} // namespace gles2 +} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/shader_translator_unittest.cc b/chromium/gpu/command_buffer/service/shader_translator_unittest.cc index 16c80a20dab..b9efe24707b 100644 --- a/chromium/gpu/command_buffer/service/shader_translator_unittest.cc +++ b/chromium/gpu/command_buffer/service/shader_translator_unittest.cc @@ -53,6 +53,7 @@ TEST_F(ShaderTranslatorTest, ValidVertexShader) { // A valid shader should be successfully translated. std::string info_log, translated_source; + int shader_version; AttributeMap attrib_map; UniformMap uniform_map; VaryingMap varying_map; @@ -60,6 +61,7 @@ TEST_F(ShaderTranslatorTest, ValidVertexShader) { EXPECT_TRUE(vertex_translator_->Translate(shader, &info_log, &translated_source, + &shader_version, &attrib_map, &uniform_map, &varying_map, @@ -86,6 +88,7 @@ TEST_F(ShaderTranslatorTest, InvalidVertexShader) { // An invalid shader should fail. std::string info_log, translated_source; + int shader_version; AttributeMap attrib_map; UniformMap uniform_map; VaryingMap varying_map; @@ -93,6 +96,7 @@ TEST_F(ShaderTranslatorTest, InvalidVertexShader) { EXPECT_FALSE(vertex_translator_->Translate(bad_shader, &info_log, &translated_source, + &shader_version, &attrib_map, &uniform_map, &varying_map, @@ -112,6 +116,7 @@ TEST_F(ShaderTranslatorTest, InvalidVertexShader) { EXPECT_TRUE(vertex_translator_->Translate(good_shader, &info_log, &translated_source, + &shader_version, &attrib_map, &uniform_map, &varying_map, @@ -128,6 +133,7 @@ TEST_F(ShaderTranslatorTest, ValidFragmentShader) { // A valid shader should be successfully translated. std::string info_log, translated_source; + int shader_version; AttributeMap attrib_map; UniformMap uniform_map; VaryingMap varying_map; @@ -135,6 +141,7 @@ TEST_F(ShaderTranslatorTest, ValidFragmentShader) { EXPECT_TRUE(fragment_translator_->Translate(shader, &info_log, &translated_source, + &shader_version, &attrib_map, &uniform_map, &varying_map, @@ -154,6 +161,7 @@ TEST_F(ShaderTranslatorTest, InvalidFragmentShader) { const char* shader = "foo-bar"; std::string info_log, translated_source; + int shader_version; AttributeMap attrib_map; UniformMap uniform_map; VaryingMap varying_map; @@ -162,6 +170,7 @@ TEST_F(ShaderTranslatorTest, InvalidFragmentShader) { EXPECT_FALSE(fragment_translator_->Translate(shader, &info_log, &translated_source, + &shader_version, &attrib_map, &uniform_map, &varying_map, @@ -185,6 +194,7 @@ TEST_F(ShaderTranslatorTest, GetAttributes) { "}"; std::string info_log, translated_source; + int shader_version; AttributeMap attrib_map; UniformMap uniform_map; VaryingMap varying_map; @@ -192,6 +202,7 @@ TEST_F(ShaderTranslatorTest, GetAttributes) { EXPECT_TRUE(vertex_translator_->Translate(shader, &info_log, &translated_source, + &shader_version, &attrib_map, &uniform_map, &varying_map, @@ -227,6 +238,7 @@ TEST_F(ShaderTranslatorTest, GetUniforms) { "}"; std::string info_log, translated_source; + int shader_version; AttributeMap attrib_map; UniformMap uniform_map; VaryingMap varying_map; @@ -234,6 +246,7 @@ TEST_F(ShaderTranslatorTest, GetUniforms) { EXPECT_TRUE(fragment_translator_->Translate(shader, &info_log, &translated_source, + &shader_version, &attrib_map, &uniform_map, &varying_map, @@ -280,6 +293,7 @@ TEST_F(ShaderTranslatorTest, BuiltInFunctionEmulation) { "}"; std::string info_log, translated_source; + int shader_version; AttributeMap attrib_map; UniformMap uniform_map; VaryingMap varying_map; @@ -287,6 +301,7 @@ TEST_F(ShaderTranslatorTest, BuiltInFunctionEmulation) { EXPECT_TRUE(vertex_translator_->Translate(shader, &info_log, &translated_source, + &shader_version, &attrib_map, &uniform_map, &varying_map, diff --git a/chromium/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc b/chromium/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc index 1026f455b66..174edaa6ee9 100644 --- a/chromium/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc +++ b/chromium/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc @@ -7,7 +7,7 @@ #include "base/bind.h" #include "base/callback.h" #include "gpu/command_buffer/service/texture_manager.h" -#include "ui/gfx/size.h" +#include "ui/gfx/geometry/size.h" #include "ui/gl/android/surface_texture.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_image.h" @@ -23,23 +23,23 @@ class GLImageImpl : public gfx::GLImage { const base::Closure& release_callback); // implement gfx::GLImage - virtual void Destroy(bool have_context) override; - virtual gfx::Size GetSize() override; - virtual bool BindTexImage(unsigned target) override; - virtual void ReleaseTexImage(unsigned target) override; - virtual bool CopyTexImage(unsigned target) override; - virtual void WillUseTexImage() override; - virtual void DidUseTexImage() override {} - virtual void WillModifyTexImage() override {} - virtual void DidModifyTexImage() override {} - virtual bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, - int z_order, - gfx::OverlayTransform transform, - const gfx::Rect& bounds_rect, - const gfx::RectF& crop_rect) override; + void Destroy(bool have_context) override; + gfx::Size GetSize() override; + bool BindTexImage(unsigned target) override; + void ReleaseTexImage(unsigned target) override; + bool CopyTexImage(unsigned target) override; + void WillUseTexImage() override; + void DidUseTexImage() override {} + void WillModifyTexImage() override {} + void DidModifyTexImage() override {} + bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, + int z_order, + gfx::OverlayTransform transform, + const gfx::Rect& bounds_rect, + const gfx::RectF& crop_rect) override; private: - virtual ~GLImageImpl(); + ~GLImageImpl() override; scoped_refptr<gfx::SurfaceTexture> surface_texture_; base::Closure release_callback_; diff --git a/chromium/gpu/command_buffer/service/sync_point_manager.cc b/chromium/gpu/command_buffer/service/sync_point_manager.cc new file mode 100644 index 00000000000..aa91bf1d3b3 --- /dev/null +++ b/chromium/gpu/command_buffer/service/sync_point_manager.cc @@ -0,0 +1,99 @@ +// 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. + +#include "gpu/command_buffer/service/sync_point_manager.h" + +#include <climits> + +#include "base/logging.h" +#include "base/rand_util.h" +#include "base/sequence_checker.h" + +namespace gpu { + +static const int kMaxSyncBase = INT_MAX; + +// static +SyncPointManager* SyncPointManager::Create(bool allow_threaded_calls) { + return new SyncPointManager(allow_threaded_calls); +} + +SyncPointManager::SyncPointManager(bool allow_threaded_calls) + : next_sync_point_(base::RandInt(1, kMaxSyncBase)) { + // To reduce the risk that a sync point created in a previous GPU process + // will be in flight in the next GPU process, randomize the starting sync + // point number. http://crbug.com/373452 + + if (!allow_threaded_calls) { + sequence_checker_.reset(new base::SequenceChecker); + } +} + +SyncPointManager::~SyncPointManager() { +} + +uint32 SyncPointManager::GenerateSyncPoint() { + base::AutoLock lock(lock_); + uint32 sync_point = next_sync_point_++; + // When an integer overflow occurs, don't return 0. + if (!sync_point) + sync_point = next_sync_point_++; + + // Note: wrapping would take days for a buggy/compromized renderer that would + // insert sync points in a loop, but if that were to happen, better explicitly + // crash the GPU process than risk worse. + // For normal operation (at most a few per frame), it would take ~a year to + // wrap. + CHECK(sync_point_map_.find(sync_point) == sync_point_map_.end()); + sync_point_map_.insert(std::make_pair(sync_point, ClosureList())); + return sync_point; +} + +void SyncPointManager::RetireSyncPoint(uint32 sync_point) { + CheckSequencedThread(); + ClosureList list; + { + base::AutoLock lock(lock_); + SyncPointMap::iterator it = sync_point_map_.find(sync_point); + if (it == sync_point_map_.end()) { + LOG(ERROR) << "Attempted to retire sync point that" + " didn't exist or was already retired."; + return; + } + list.swap(it->second); + sync_point_map_.erase(it); + } + for (ClosureList::iterator i = list.begin(); i != list.end(); ++i) + i->Run(); +} + +void SyncPointManager::AddSyncPointCallback(uint32 sync_point, + const base::Closure& callback) { + CheckSequencedThread(); + { + base::AutoLock lock(lock_); + SyncPointMap::iterator it = sync_point_map_.find(sync_point); + if (it != sync_point_map_.end()) { + it->second.push_back(callback); + return; + } + } + callback.Run(); +} + +bool SyncPointManager::IsSyncPointRetired(uint32 sync_point) { + CheckSequencedThread(); + { + base::AutoLock lock(lock_); + SyncPointMap::iterator it = sync_point_map_.find(sync_point); + return it == sync_point_map_.end(); + } +} + +void SyncPointManager::CheckSequencedThread() { + DCHECK(!sequence_checker_ || + sequence_checker_->CalledOnValidSequencedThread()); +} + +} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/sync_point_manager.h b/chromium/gpu/command_buffer/service/sync_point_manager.h new file mode 100644 index 00000000000..001ab176087 --- /dev/null +++ b/chromium/gpu/command_buffer/service/sync_point_manager.h @@ -0,0 +1,71 @@ +// 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. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ + +#include <vector> + +#include "base/callback.h" +#include "base/containers/hash_tables.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/synchronization/lock.h" +#include "gpu/gpu_export.h" + +namespace base { +class SequenceChecker; +} + +namespace gpu { + +// This class manages the sync points, which allow cross-channel +// synchronization. +class GPU_EXPORT SyncPointManager + : public base::RefCountedThreadSafe<SyncPointManager> { + public: + // InProcessCommandBuffer allows threaded calls since it can call into + // SyncPointManager from client threads, or from multiple service threads + // used in Android WebView. + static SyncPointManager* Create(bool allow_threaded_calls); + + // Generates a sync point, returning its ID. This can me called on any thread. + // IDs start at a random number. Never return 0. + uint32 GenerateSyncPoint(); + + // Retires a sync point. This will call all the registered callbacks for this + // sync point. This can only be called on the main thread. + void RetireSyncPoint(uint32 sync_point); + + // Adds a callback to the sync point. The callback will be called when the + // sync point is retired, or immediately (from within that function) if the + // sync point was already retired (or not created yet). This can only be + // called on the main thread. + void AddSyncPointCallback(uint32 sync_point, const base::Closure& callback); + + bool IsSyncPointRetired(uint32 sync_point); + + private: + friend class base::RefCountedThreadSafe<SyncPointManager>; + typedef std::vector<base::Closure> ClosureList; + typedef base::hash_map<uint32, ClosureList> SyncPointMap; + + explicit SyncPointManager(bool allow_threaded_calls); + ~SyncPointManager(); + void CheckSequencedThread(); + + scoped_ptr<base::SequenceChecker> sequence_checker_; + + // Protects the 2 fields below. Note: callbacks shouldn't be called with this + // held. + base::Lock lock_; + SyncPointMap sync_point_map_; + uint32 next_sync_point_; + + DISALLOW_COPY_AND_ASSIGN(SyncPointManager); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ diff --git a/chromium/gpu/command_buffer/service/test_helper.cc b/chromium/gpu/command_buffer/service/test_helper.cc index cea7b8afd45..e2fd7463f12 100644 --- a/chromium/gpu/command_buffer/service/test_helper.cc +++ b/chromium/gpu/command_buffer/service/test_helper.cc @@ -18,6 +18,7 @@ #include "gpu/command_buffer/service/texture_manager.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_mock.h" +#include "ui/gl/gl_version_info.h" using ::testing::_; using ::testing::DoAll; @@ -67,6 +68,8 @@ const GLint TestHelper::kMaxSamples; const GLint TestHelper::kMaxRenderbufferSize; const GLint TestHelper::kMaxTextureSize; const GLint TestHelper::kMaxCubeMapTextureSize; +const GLint TestHelper::kMaxRectangleTextureSize; +const GLint TestHelper::kMax3DTextureSize; const GLint TestHelper::kNumVertexAttribs; const GLint TestHelper::kNumTextureUnits; const GLint TestHelper::kMaxTextureImageUnits; @@ -79,6 +82,8 @@ const GLint TestHelper::kMaxVertexUniformVectors; const GLint TestHelper::kMaxVertexUniformComponents; #endif +std::vector<std::string> TestHelper::split_extensions_; + void TestHelper::SetupTextureInitializationExpectations( ::gfx::MockGLInterface* gl, GLenum target, @@ -269,14 +274,14 @@ void TestHelper::SetupContextGroupInitExpectations( SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", gl_version); - std::string l_version(base::StringToLowerASCII(std::string(gl_version))); - bool is_es3 = (l_version.substr(0, 12) == "opengl es 3."); + gfx::GLVersionInfo gl_info(gl_version, "", extensions); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE, _)) .WillOnce(SetArgumentPointee<1>(kMaxRenderbufferSize)) .RetiresOnSaturation(); if (strstr(extensions, "GL_EXT_framebuffer_multisample") || - strstr(extensions, "GL_EXT_multisampled_render_to_texture") || is_es3) { + strstr(extensions, "GL_EXT_multisampled_render_to_texture") || + gl_info.is_es3) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES, _)) .WillOnce(SetArgumentPointee<1>(kMaxSamples)) .RetiresOnSaturation(); @@ -297,21 +302,44 @@ void TestHelper::SetupContextGroupInitExpectations( EXPECT_CALL(*gl, GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, _)) .WillOnce(SetArgumentPointee<1>(kMaxCubeMapTextureSize)) .RetiresOnSaturation(); + if (gl_info.IsES3Capable()) { + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_3D_TEXTURE_SIZE, _)) + .WillOnce(SetArgumentPointee<1>(kMax3DTextureSize)) + .RetiresOnSaturation(); + } + if (strstr(extensions, "GL_ARB_texture_rectangle")) { + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, _)) + .WillOnce(SetArgumentPointee<1>(kMaxRectangleTextureSize)) + .RetiresOnSaturation(); + } EXPECT_CALL(*gl, GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, _)) .WillOnce(SetArgumentPointee<1>(kMaxTextureImageUnits)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, _)) .WillOnce(SetArgumentPointee<1>(kMaxVertexTextureImageUnits)) .RetiresOnSaturation(); - EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformComponents)) - .RetiresOnSaturation(); - EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_FLOATS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxVaryingFloats)) - .RetiresOnSaturation(); - EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformComponents)) - .RetiresOnSaturation(); + + if (gl_info.is_es) { + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformVectors)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_VECTORS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVaryingVectors)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformVectors)) + .RetiresOnSaturation(); + } else { + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformComponents)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_FLOATS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVaryingFloats)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformComponents)) + .RetiresOnSaturation(); + } bool use_default_textures = bind_generates_resource; SetupTextureManagerInitExpectations(gl, extensions, use_default_textures); @@ -329,36 +357,55 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( const char* gl_version) { InSequence sequence; - EXPECT_CALL(*gl, GetString(GL_EXTENSIONS)) - .WillOnce(Return(reinterpret_cast<const uint8*>(extensions))) - .RetiresOnSaturation(); - EXPECT_CALL(*gl, GetString(GL_RENDERER)) - .WillOnce(Return(reinterpret_cast<const uint8*>(gl_renderer))) - .RetiresOnSaturation(); EXPECT_CALL(*gl, GetString(GL_VERSION)) .WillOnce(Return(reinterpret_cast<const uint8*>(gl_version))) .RetiresOnSaturation(); - std::string l_version(base::StringToLowerASCII(std::string(gl_version))); - bool is_es3 = (l_version.substr(0, 12) == "opengl es 3."); + // Persistent storage is needed for the split extension string. + split_extensions_.clear(); + if (extensions) { + Tokenize(extensions, " ", &split_extensions_); + } + + gfx::GLVersionInfo gl_info(gl_version, gl_renderer, extensions); + if (!gl_info.is_es && gl_info.major_version >= 3) { + EXPECT_CALL(*gl, GetIntegerv(GL_NUM_EXTENSIONS, _)) + .WillOnce(SetArgumentPointee<1>(split_extensions_.size())) + .RetiresOnSaturation(); + for (size_t ii = 0; ii < split_extensions_.size(); ++ii) { + EXPECT_CALL(*gl, GetStringi(GL_EXTENSIONS, ii)) + .WillOnce(Return(reinterpret_cast<const uint8*>( + split_extensions_[ii].c_str()))) + .RetiresOnSaturation(); + } + } else { + EXPECT_CALL(*gl, GetString(GL_EXTENSIONS)) + .WillOnce(Return(reinterpret_cast<const uint8*>(extensions))) + .RetiresOnSaturation(); + } + + EXPECT_CALL(*gl, GetString(GL_RENDERER)) + .WillOnce(Return(reinterpret_cast<const uint8*>(gl_renderer))) + .RetiresOnSaturation(); if (strstr(extensions, "GL_ARB_texture_float") || - (is_es3 && strstr(extensions, "GL_EXT_color_buffer_float"))) { - static const GLuint gl_ids[] = {101, 102}; + (gl_info.is_es3 && strstr(extensions, "GL_EXT_color_buffer_float"))) { + static const GLuint tx_ids[] = {101, 102}; + static const GLuint fb_ids[] = {103, 104}; const GLsizei width = 16; EXPECT_CALL(*gl, GetIntegerv(GL_FRAMEBUFFER_BINDING, _)) - .WillOnce(SetArgumentPointee<1>(gl_ids[0])) + .WillOnce(SetArgumentPointee<1>(fb_ids[0])) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_TEXTURE_BINDING_2D, _)) - .WillOnce(SetArgumentPointee<1>(gl_ids[0])) + .WillOnce(SetArgumentPointee<1>(tx_ids[0])) .RetiresOnSaturation(); EXPECT_CALL(*gl, GenTextures(1, _)) - .WillOnce(SetArrayArgument<1>(gl_ids + 1, gl_ids + 2)) + .WillOnce(SetArrayArgument<1>(tx_ids + 1, tx_ids + 2)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GenFramebuffersEXT(1, _)) - .WillOnce(SetArrayArgument<1>(gl_ids + 1, gl_ids + 2)) + .WillOnce(SetArrayArgument<1>(fb_ids + 1, fb_ids + 2)) .RetiresOnSaturation(); - EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, gl_ids[1])) + EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_ids[1])) .Times(1) .RetiresOnSaturation(); EXPECT_CALL(*gl, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, @@ -369,11 +416,11 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( GL_RGBA, GL_FLOAT, _)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, gl_ids[1])) + EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, fb_ids[1])) .Times(1) .RetiresOnSaturation(); EXPECT_CALL(*gl, FramebufferTexture2DEXT(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl_ids[1], 0)) + GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tx_ids[1], 0)) .Times(1) .RetiresOnSaturation(); EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)) @@ -383,7 +430,7 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( GL_RGB, GL_FLOAT, _)) .Times(1) .RetiresOnSaturation(); - if (is_es3) { + if (gl_info.is_es3) { EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)) .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)) .RetiresOnSaturation(); @@ -398,13 +445,13 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( EXPECT_CALL(*gl, DeleteTextures(1, _)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, gl_ids[0])) + EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, fb_ids[0])) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, gl_ids[0])) + EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_ids[0])) .Times(1) .RetiresOnSaturation(); -#if DCHECK_IS_ON +#if DCHECK_IS_ON() EXPECT_CALL(*gl, GetError()) .WillOnce(Return(GL_NO_ERROR)) .RetiresOnSaturation(); @@ -413,7 +460,7 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( if (strstr(extensions, "GL_EXT_draw_buffers") || strstr(extensions, "GL_ARB_draw_buffers") || - (is_es3 && strstr(extensions, "GL_NV_draw_buffers"))) { + (gl_info.is_es3 && strstr(extensions, "GL_NV_draw_buffers"))) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, _)) .WillOnce(SetArgumentPointee<1>(8)) .RetiresOnSaturation(); @@ -421,6 +468,59 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( .WillOnce(SetArgumentPointee<1>(8)) .RetiresOnSaturation(); } + + if (gl_info.is_es3 || strstr(extensions, "GL_EXT_texture_rg") || + (strstr(extensions, "GL_ARB_texture_rg"))) { + static const GLuint tx_ids[] = {101, 102}; + static const GLuint fb_ids[] = {103, 104}; + const GLsizei width = 1; + EXPECT_CALL(*gl, GetIntegerv(GL_FRAMEBUFFER_BINDING, _)) + .WillOnce(SetArgumentPointee<1>(fb_ids[0])) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, GetIntegerv(GL_TEXTURE_BINDING_2D, _)) + .WillOnce(SetArgumentPointee<1>(tx_ids[0])) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, GenTextures(1, _)) + .WillOnce(SetArrayArgument<1>(tx_ids + 1, tx_ids + 2)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_ids[1])) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, _, width, width, 0, + GL_RED_EXT, GL_UNSIGNED_BYTE, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, GenFramebuffersEXT(1, _)) + .WillOnce(SetArrayArgument<1>(fb_ids + 1, fb_ids + 2)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, fb_ids[1])) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, FramebufferTexture2DEXT(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tx_ids[1], 0)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)) + .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, DeleteFramebuffersEXT(1, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, DeleteTextures(1, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, fb_ids[0])) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_ids[0])) + .Times(1) + .RetiresOnSaturation(); +#if DCHECK_IS_ON() + EXPECT_CALL(*gl, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); +#endif + } } void TestHelper::SetupExpectationsForClearingUniforms( @@ -578,10 +678,7 @@ void TestHelper::SetupProgramSuccessExpectations( for (int pass = 0; pass < 2; ++pass) { for (size_t ii = 0; ii < num_uniforms; ++ii) { const UniformInfo& info = uniforms[ii]; - if (ProgramManager::IsInvalidPrefix(info.name, strlen(info.name))) { - continue; - } - if (pass == 0) { + if (pass == 0 && info.real_location != -1) { EXPECT_CALL(*gl, GetUniformLocation(service_id, StrEq(info.name))) .WillOnce(Return(info.real_location)) .RetiresOnSaturation(); @@ -677,6 +774,7 @@ void TestHelper::SetShaderStates( bool expected_valid, const std::string* const expected_log_info, const std::string* const expected_translated_source, + const int* const expected_shader_version, const AttributeMap* const expected_attrib_map, const UniformMap* const expected_uniform_map, const VaryingMap* const expected_varying_map, @@ -688,6 +786,9 @@ void TestHelper::SetShaderStates( const std::string* translated_source = (expected_translated_source && expected_valid) ? expected_translated_source : &empty_translated_source; + int default_shader_version = 100; + const int* shader_version = (expected_shader_version && expected_valid) ? + expected_shader_version : &default_shader_version; const AttributeMap empty_attrib_map; const AttributeMap* attrib_map = (expected_attrib_map && expected_valid) ? expected_attrib_map : &empty_attrib_map; @@ -701,20 +802,23 @@ void TestHelper::SetShaderStates( const NameMap* name_map = (expected_name_map && expected_valid) ? expected_name_map : &empty_name_map; - MockShaderTranslator translator; - EXPECT_CALL(translator, Translate(_, - NotNull(), // log_info - NotNull(), // translated_source - NotNull(), // attrib_map - NotNull(), // uniform_map - NotNull(), // varying_map - NotNull())) // name_map + MockShaderTranslator* mock_translator = new MockShaderTranslator; + scoped_refptr<ShaderTranslatorInterface> translator(mock_translator); + EXPECT_CALL(*mock_translator, Translate(_, + NotNull(), // log_info + NotNull(), // translated_source + NotNull(), // shader_version + NotNull(), // attrib_map + NotNull(), // uniform_map + NotNull(), // varying_map + NotNull())) // name_map .WillOnce(DoAll(SetArgumentPointee<1>(*log_info), SetArgumentPointee<2>(*translated_source), - SetArgumentPointee<3>(*attrib_map), - SetArgumentPointee<4>(*uniform_map), - SetArgumentPointee<5>(*varying_map), - SetArgumentPointee<6>(*name_map), + SetArgumentPointee<3>(*shader_version), + SetArgumentPointee<4>(*attrib_map), + SetArgumentPointee<5>(*uniform_map), + SetArgumentPointee<6>(*varying_map), + SetArgumentPointee<7>(*name_map), Return(expected_valid))) .RetiresOnSaturation(); if (expected_valid) { @@ -730,13 +834,14 @@ void TestHelper::SetShaderStates( .WillOnce(SetArgumentPointee<2>(GL_TRUE)) .RetiresOnSaturation(); } - shader->DoCompile(&translator, Shader::kGL); + shader->RequestCompile(translator, Shader::kGL); + shader->DoCompile(); } // static void TestHelper::SetShaderStates( ::gfx::MockGLInterface* gl, Shader* shader, bool valid) { - SetShaderStates(gl, shader, valid, NULL, NULL, NULL, NULL, NULL, NULL); + SetShaderStates(gl, shader, valid, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } // static diff --git a/chromium/gpu/command_buffer/service/test_helper.h b/chromium/gpu/command_buffer/service/test_helper.h index f83ed23cada..a074deb8846 100644 --- a/chromium/gpu/command_buffer/service/test_helper.h +++ b/chromium/gpu/command_buffer/service/test_helper.h @@ -5,6 +5,9 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_TEST_HELPER_H_ #define GPU_COMMAND_BUFFER_SERVICE_TEST_HELPER_H_ +#include <string> +#include <vector> + #include "gpu/command_buffer/service/shader_translator.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_mock.h" @@ -35,6 +38,8 @@ class TestHelper { static const GLint kMaxRenderbufferSize = 1024; static const GLint kMaxTextureSize = 2048; static const GLint kMaxCubeMapTextureSize = 256; + static const GLint kMax3DTextureSize = 256; + static const GLint kMaxRectangleTextureSize = 64; static const GLint kNumVertexAttribs = 16; static const GLint kNumTextureUnits = 8; static const GLint kMaxTextureImageUnits = 8; @@ -114,6 +119,7 @@ class TestHelper { bool expected_valid, const std::string* const expected_log_info, const std::string* const expected_translated_source, + const int* const expected_shader_version, const AttributeMap* const expected_attrib_map, const UniformMap* const expected_uniform_map, const VaryingMap* const expected_varying_map, @@ -139,6 +145,8 @@ class TestHelper { static void SetupTextureDestructionExpectations(::gfx::MockGLInterface* gl, GLenum target, bool use_default_textures); + + static std::vector<std::string> split_extensions_; }; // This object temporaritly Sets what gfx::GetGLImplementation returns. During diff --git a/chromium/gpu/command_buffer/service/texture_definition.cc b/chromium/gpu/command_buffer/service/texture_definition.cc index edd42717d37..311bb41ef6c 100644 --- a/chromium/gpu/command_buffer/service/texture_definition.cc +++ b/chromium/gpu/command_buffer/service/texture_definition.cc @@ -6,9 +6,11 @@ #include <list> +#include "base/lazy_instance.h" #include "base/memory/linked_ptr.h" #include "base/memory/scoped_ptr.h" #include "base/synchronization/lock.h" +#include "base/threading/thread_local.h" #include "gpu/command_buffer/service/texture_manager.h" #include "ui/gl/gl_image.h" #include "ui/gl/gl_implementation.h" @@ -118,15 +120,15 @@ class NativeImageBufferEGL : public NativeImageBuffer { void AddClient(gfx::GLImage* client) override; void RemoveClient(gfx::GLImage* client) override; bool IsClient(gfx::GLImage* client) override; - void BindToTexture(GLenum target) override; + void BindToTexture(GLenum target) const override; - EGLDisplay egl_display_; - EGLImageKHR egl_image_; + const EGLDisplay egl_display_; + const EGLImageKHR egl_image_; base::Lock lock_; struct ClientInfo { - ClientInfo(gfx::GLImage* client); + explicit ClientInfo(gfx::GLImage* client); ~ClientInfo(); gfx::GLImage* client; @@ -154,13 +156,16 @@ scoped_refptr<NativeImageBufferEGL> NativeImageBufferEGL::Create( const EGLint egl_attrib_list[] = { EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; EGLClientBuffer egl_buffer = reinterpret_cast<EGLClientBuffer>(texture_id); - EGLenum egl_target = EGL_GL_TEXTURE_2D_KHR; // TODO + EGLenum egl_target = EGL_GL_TEXTURE_2D_KHR; EGLImageKHR egl_image = eglCreateImageKHR( egl_display, egl_context, egl_target, egl_buffer, egl_attrib_list); - if (egl_image == EGL_NO_IMAGE_KHR) + if (egl_image == EGL_NO_IMAGE_KHR) { + LOG(ERROR) << "eglCreateImageKHR for cross-thread sharing failed: 0x" + << std::hex << eglGetError(); return NULL; + } return new NativeImageBufferEGL(egl_display, egl_image); } @@ -217,7 +222,7 @@ bool NativeImageBufferEGL::IsClient(gfx::GLImage* client) { return false; } -void NativeImageBufferEGL::BindToTexture(GLenum target) { +void NativeImageBufferEGL::BindToTexture(GLenum target) const { DCHECK(egl_image_ != EGL_NO_IMAGE_KHR); glEGLImageTargetTexture2DOES(target, egl_image_); DCHECK_EQ(static_cast<EGLint>(EGL_SUCCESS), eglGetError()); @@ -235,11 +240,17 @@ class NativeImageBufferStub : public NativeImageBuffer { void AddClient(gfx::GLImage* client) override {} void RemoveClient(gfx::GLImage* client) override {} bool IsClient(gfx::GLImage* client) override { return true; } - void BindToTexture(GLenum target) override {} + void BindToTexture(GLenum target) const override {} DISALLOW_COPY_AND_ASSIGN(NativeImageBufferStub); }; +bool g_avoid_egl_target_texture_reuse = false; + +#if DCHECK_IS_ON() +base::LazyInstance<base::ThreadLocalBoolean> g_inside_scoped_update_texture; +#endif + } // anonymous namespace // static @@ -257,6 +268,44 @@ scoped_refptr<NativeImageBuffer> NativeImageBuffer::Create(GLuint texture_id) { } } +// static +void TextureDefinition::AvoidEGLTargetTextureReuse() { + g_avoid_egl_target_texture_reuse = true; +} + +ScopedUpdateTexture::ScopedUpdateTexture() { +#if DCHECK_IS_ON() + DCHECK(!g_inside_scoped_update_texture.Get().Get()); + g_inside_scoped_update_texture.Get().Set(true); +#endif +} + +ScopedUpdateTexture::~ScopedUpdateTexture() { +#if DCHECK_IS_ON() + DCHECK(g_inside_scoped_update_texture.Get().Get()); + g_inside_scoped_update_texture.Get().Set(false); +#endif + // We have to make sure the changes are visible to other clients in this share + // group. As far as the clients are concerned, the mailbox semantics only + // demand a single flush from the client after changes are first made, + // and it is not visible to them when another share group boundary is crossed. + // We could probably track this and be a bit smarter about when to flush + // though. + glFlush(); +} + +TextureDefinition::LevelInfo::LevelInfo() + : target(0), + internal_format(0), + width(0), + height(0), + depth(0), + border(0), + format(0), + type(0), + cleared(false) { +} + TextureDefinition::LevelInfo::LevelInfo(GLenum target, GLenum internal_format, GLsizei width, @@ -295,100 +344,77 @@ TextureDefinition::TextureDefinition( const scoped_refptr<NativeImageBuffer>& image_buffer) : version_(version), target_(texture->target()), - image_buffer_(image_buffer.get() - ? image_buffer - : NativeImageBuffer::Create(texture->service_id())), + image_buffer_(image_buffer), min_filter_(texture->min_filter()), mag_filter_(texture->mag_filter()), wrap_s_(texture->wrap_s()), wrap_t_(texture->wrap_t()), usage_(texture->usage()), - immutable_(texture->IsImmutable()) { - // TODO - DCHECK(!texture->face_infos_.empty()); - DCHECK(!texture->face_infos_[0].level_infos.empty()); - DCHECK(!texture->NeedsMips()); - DCHECK(texture->face_infos_[0].level_infos[0].width); - DCHECK(texture->face_infos_[0].level_infos[0].height); + immutable_(texture->IsImmutable()), + defined_(texture->IsDefined()) { + DCHECK_IMPLIES(image_buffer_.get(), defined_); + if (!image_buffer_.get() && defined_) { + image_buffer_ = NativeImageBuffer::Create(texture->service_id()); + DCHECK(image_buffer_.get()); + } const Texture::FaceInfo& first_face = texture->face_infos_[0]; - scoped_refptr<gfx::GLImage> gl_image( - new GLImageSync(image_buffer_, - gfx::Size(first_face.level_infos[0].width, - first_face.level_infos[0].height))); - texture->SetLevelImage(NULL, target_, 0, gl_image.get()); - - // TODO: all levels - level_infos_.clear(); + if (image_buffer_.get()) { + scoped_refptr<gfx::GLImage> gl_image( + new GLImageSync(image_buffer_, + gfx::Size(first_face.level_infos[0].width, + first_face.level_infos[0].height))); + texture->SetLevelImage(NULL, target_, 0, gl_image.get()); + } + const Texture::LevelInfo& level = first_face.level_infos[0]; - LevelInfo info(level.target, - level.internal_format, - level.width, - level.height, - level.depth, - level.border, - level.format, - level.type, - level.cleared); - std::vector<LevelInfo> infos; - infos.push_back(info); - level_infos_.push_back(infos); + level_info_ = LevelInfo(level.target, level.internal_format, level.width, + level.height, level.depth, level.border, level.format, + level.type, level.cleared); } TextureDefinition::~TextureDefinition() { } Texture* TextureDefinition::CreateTexture() const { - if (!image_buffer_.get()) - return NULL; - GLuint texture_id; glGenTextures(1, &texture_id); Texture* texture(new Texture(texture_id)); - UpdateTexture(texture); + ScopedUpdateTexture scoped_update_texture; + UpdateTextureInternal(texture); return texture; } -void TextureDefinition::UpdateTexture(Texture* texture) const { +void TextureDefinition::UpdateTextureInternal(Texture* texture) const { +#if DCHECK_IS_ON() + DCHECK(g_inside_scoped_update_texture.Get().Get()); +#endif gfx::ScopedTextureBinder texture_binder(target_, texture->service_id()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s_); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t_); - if (image_buffer_.get()) - image_buffer_->BindToTexture(target_); - // We have to make sure the changes are visible to other clients in this share - // group. As far as the clients are concerned, the mailbox semantics only - // demand a single flush from the client after changes are first made, - // and it is not visible to them when another share group boundary is crossed. - // We could probably track this and be a bit smarter about when to flush - // though. - glFlush(); - texture->face_infos_.resize(1); - for (size_t i = 0; i < level_infos_.size(); i++) { - const LevelInfo& base_info = level_infos_[i][0]; - const size_t levels_needed = TextureManager::ComputeMipMapCount( - base_info.target, base_info.width, base_info.height, base_info.depth); - DCHECK(level_infos_.size() <= levels_needed); - texture->face_infos_[0].level_infos.resize(levels_needed); - for (size_t n = 0; n < level_infos_.size(); n++) { - const LevelInfo& info = level_infos_[i][n]; - texture->SetLevelInfo(NULL, - info.target, - i, - info.internal_format, - info.width, - info.height, - info.depth, - info.border, - info.format, - info.type, - info.cleared); + if (image_buffer_.get()) { + gfx::GLImage* existing_image = texture->GetLevelImage(target_, 0); + // Don't need to re-bind if already bound before. + if (!existing_image || !image_buffer_->IsClient(existing_image)) { + image_buffer_->BindToTexture(target_); } } + + if (defined_) { + texture->face_infos_.resize(1); + texture->face_infos_[0].level_infos.resize(1); + texture->SetLevelInfo(NULL, level_info_.target, 0, + level_info_.internal_format, level_info_.width, + level_info_.height, level_info_.depth, + level_info_.border, level_info_.format, + level_info_.type, level_info_.cleared); + } + if (image_buffer_.get()) { texture->SetLevelImage( NULL, @@ -396,7 +422,7 @@ void TextureDefinition::UpdateTexture(Texture* texture) const { 0, new GLImageSync( image_buffer_, - gfx::Size(level_infos_[0][0].width, level_infos_[0][0].height))); + gfx::Size(level_info_.width, level_info_.height))); } texture->target_ = target_; @@ -408,15 +434,44 @@ void TextureDefinition::UpdateTexture(Texture* texture) const { texture->usage_ = usage_; } +void TextureDefinition::UpdateTexture(Texture* texture) const { + GLuint old_service_id = 0u; + if (image_buffer_.get() && g_avoid_egl_target_texture_reuse) { + GLuint service_id = 0u; + glGenTextures(1, &service_id); + old_service_id = texture->service_id(); + texture->SetServiceId(service_id); + + DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), target_); + GLint bound_id = 0; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_id); + if (bound_id == static_cast<GLint>(old_service_id)) { + glBindTexture(target_, service_id); + } + texture->SetLevelImage(NULL, target_, 0, NULL); + } + + UpdateTextureInternal(texture); + + if (old_service_id) { + glDeleteTextures(1, &old_service_id); + } +} + bool TextureDefinition::Matches(const Texture* texture) const { DCHECK(target_ == texture->target()); if (texture->min_filter_ != min_filter_ || texture->mag_filter_ != mag_filter_ || texture->wrap_s_ != wrap_s_ || - texture->wrap_t_ != wrap_t_) { + texture->wrap_t_ != wrap_t_ || + texture->SafeToRenderFrom() != SafeToRenderFrom()) { return false; } + // Texture became defined. + if (!image_buffer_.get() && texture->IsDefined()) + return false; + // All structural changes should have orphaned the texture. if (image_buffer_.get() && !texture->GetLevelImage(texture->target(), 0)) return false; @@ -424,5 +479,9 @@ bool TextureDefinition::Matches(const Texture* texture) const { return true; } +bool TextureDefinition::SafeToRenderFrom() const { + return level_info_.cleared; +} + } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/texture_definition.h b/chromium/gpu/command_buffer/service/texture_definition.h index ff891fc4ff3..e5311846295 100644 --- a/chromium/gpu/command_buffer/service/texture_definition.h +++ b/chromium/gpu/command_buffer/service/texture_definition.h @@ -26,7 +26,7 @@ class NativeImageBuffer : public base::RefCountedThreadSafe<NativeImageBuffer> { virtual void AddClient(gfx::GLImage* client) = 0; virtual void RemoveClient(gfx::GLImage* client) = 0; virtual bool IsClient(gfx::GLImage* client) = 0; - virtual void BindToTexture(GLenum target) = 0; + virtual void BindToTexture(GLenum target) const = 0; protected: friend class base::RefCountedThreadSafe<NativeImageBuffer>; @@ -36,10 +36,21 @@ class NativeImageBuffer : public base::RefCountedThreadSafe<NativeImageBuffer> { DISALLOW_COPY_AND_ASSIGN(NativeImageBuffer); }; +class ScopedUpdateTexture { + public: + ScopedUpdateTexture(); + ~ScopedUpdateTexture(); + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedUpdateTexture); +}; + // An immutable description that can be used to create a texture that shares // the underlying image buffer(s). class TextureDefinition { public: + static void AvoidEGLTargetTextureReuse(); + TextureDefinition(); TextureDefinition(Texture* texture, unsigned int version, @@ -47,6 +58,8 @@ class TextureDefinition { virtual ~TextureDefinition(); Texture* CreateTexture() const; + + // Must be wrapped with ScopedUpdateTexture. void UpdateTexture(Texture* texture) const; unsigned int version() const { return version_; } @@ -58,7 +71,11 @@ class TextureDefinition { scoped_refptr<NativeImageBuffer> image() const { return image_buffer_; } private: + bool SafeToRenderFrom() const; + void UpdateTextureInternal(Texture* texture) const; + struct LevelInfo { + LevelInfo(); LevelInfo(GLenum target, GLenum internal_format, GLsizei width, @@ -81,8 +98,6 @@ class TextureDefinition { bool cleared; }; - typedef std::vector<std::vector<LevelInfo> > LevelInfos; - unsigned int version_; GLenum target_; scoped_refptr<NativeImageBuffer> image_buffer_; @@ -92,7 +107,10 @@ class TextureDefinition { GLenum wrap_t_; GLenum usage_; bool immutable_; - LevelInfos level_infos_; + bool defined_; + + // Only support textures with one face and one level. + LevelInfo level_info_; }; } // namespage gles2 diff --git a/chromium/gpu/command_buffer/service/texture_manager.cc b/chromium/gpu/command_buffer/service/texture_manager.cc index 4dbf5289e13..90b7d2a236b 100644 --- a/chromium/gpu/command_buffer/service/texture_manager.cc +++ b/chromium/gpu/command_buffer/service/texture_manager.cc @@ -29,14 +29,21 @@ struct TextureSignature { GLint level_; GLenum min_filter_; GLenum mag_filter_; + GLenum wrap_r_; GLenum wrap_s_; GLenum wrap_t_; GLenum usage_; GLenum internal_format_; + GLenum compare_func_; + GLenum compare_mode_; GLsizei width_; GLsizei height_; GLsizei depth_; + GLfloat max_lod_; + GLfloat min_lod_; + GLint base_level_; GLint border_; + GLint max_level_; GLenum format_; GLenum type_; bool has_image_; @@ -52,14 +59,21 @@ struct TextureSignature { GLint level, GLenum min_filter, GLenum mag_filter, + GLenum wrap_r, GLenum wrap_s, GLenum wrap_t, GLenum usage, GLenum internal_format, + GLenum compare_func, + GLenum compare_mode, GLsizei width, GLsizei height, GLsizei depth, + GLfloat max_lod, + GLfloat min_lod, + GLint base_level, GLint border, + GLint max_level, GLenum format, GLenum type, bool has_image, @@ -71,14 +85,21 @@ struct TextureSignature { level_ = level; min_filter_ = min_filter; mag_filter_ = mag_filter; + wrap_r_ = wrap_r; wrap_s_ = wrap_s; wrap_t_ = wrap_t; usage_ = usage; internal_format_ = internal_format; + compare_func_ = compare_func; + compare_mode_ = compare_mode; width_ = width; height_ = height; depth_ = depth; + max_lod_ = max_lod; + min_lod_ = min_lod; + base_level_ = base_level; border_ = border; + max_level_ = max_level; format_ = format; type_ = type; has_image_ = has_image; @@ -133,10 +154,17 @@ Texture::Texture(GLuint service_id) target_(0), min_filter_(GL_NEAREST_MIPMAP_LINEAR), mag_filter_(GL_LINEAR), + wrap_r_(GL_REPEAT), wrap_s_(GL_REPEAT), wrap_t_(GL_REPEAT), usage_(GL_NONE), pool_(GL_TEXTURE_POOL_UNMANAGED_CHROMIUM), + compare_func_(GL_LEQUAL), + compare_mode_(GL_NONE), + max_lod_(1000.0f), + min_lod_(-1000.0f), + base_level_(0), + max_level_(1000), max_level_set_(-1), texture_complete_(false), texture_mips_dirty_(false), @@ -305,14 +333,21 @@ void Texture::AddToSignature( level, min_filter_, mag_filter_, + wrap_r_, wrap_s_, wrap_t_, usage_, info.internal_format, + compare_func_, + compare_mode_, info.width, info.height, info.depth, + max_lod_, + min_lod_, + base_level_, info.border, + max_level_, info.format, info.type, info.image.get() != NULL, @@ -626,7 +661,7 @@ void Texture::SetLevelInfo( estimated_size_ -= info.estimated_size; GLES2Util::ComputeImageDataSizes( - width, height, format, type, 4, &info.estimated_size, NULL, NULL); + width, height, 1, format, type, 4, &info.estimated_size, NULL, NULL); estimated_size_ += info.estimated_size; UpdateMipCleared(&info, cleared); @@ -647,28 +682,35 @@ bool Texture::ValidForTexture( GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, + GLsizei depth, GLenum type) const { size_t face_index = GLES2Util::GLTargetToFaceIndex(target); if (level >= 0 && face_index < face_infos_.size() && static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) { const LevelInfo& info = face_infos_[face_index].level_infos[level]; - int32 right; - int32 top; - return SafeAddInt32(xoffset, width, &right) && - SafeAddInt32(yoffset, height, &top) && + int32 max_x; + int32 max_y; + int32 max_z; + return SafeAddInt32(xoffset, width, &max_x) && + SafeAddInt32(yoffset, height, &max_y) && + SafeAddInt32(zoffset, depth, &max_z) && xoffset >= 0 && yoffset >= 0 && - right <= info.width && - top <= info.height && + zoffset >= 0 && + max_x <= info.width && + max_y <= info.height && + max_z <= info.depth && type == info.type; } return false; } bool Texture::GetLevelSize( - GLint target, GLint level, GLsizei* width, GLsizei* height) const { + GLint target, GLint level, + GLsizei* width, GLsizei* height, GLsizei* depth) const { DCHECK(width); DCHECK(height); size_t face_index = GLES2Util::GLTargetToFaceIndex(target); @@ -678,6 +720,8 @@ bool Texture::GetLevelSize( if (info.target != 0) { *width = info.width; *height = info.height; + if (depth) + *depth = info.depth; return true; } } @@ -736,6 +780,12 @@ GLenum Texture::SetParameteri( pool_ = param; GetMemTracker()->TrackMemAlloc(estimated_size()); break; + case GL_TEXTURE_WRAP_R: + if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { + return GL_INVALID_ENUM; + } + wrap_r_ = param; + break; case GL_TEXTURE_WRAP_S: if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { return GL_INVALID_ENUM; @@ -748,6 +798,30 @@ GLenum Texture::SetParameteri( } wrap_t_ = param; break; + case GL_TEXTURE_COMPARE_FUNC: + if (!feature_info->validators()->texture_compare_func.IsValid(param)) { + return GL_INVALID_ENUM; + } + compare_func_ = param; + break; + case GL_TEXTURE_COMPARE_MODE: + if (!feature_info->validators()->texture_compare_mode.IsValid(param)) { + return GL_INVALID_ENUM; + } + compare_mode_ = param; + break; + case GL_TEXTURE_BASE_LEVEL: + if (param < 0) { + return GL_INVALID_VALUE; + } + base_level_ = param; + break; + case GL_TEXTURE_MAX_LEVEL: + if (param < 0) { + return GL_INVALID_VALUE; + } + max_level_ = param; + break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (param < 1) { return GL_INVALID_VALUE; @@ -782,6 +856,12 @@ GLenum Texture::SetParameterf( GLint iparam = static_cast<GLint>(param); return SetParameteri(feature_info, pname, iparam); } + case GL_TEXTURE_MIN_LOD: + min_lod_ = param; + break; + case GL_TEXTURE_MAX_LOD: + max_lod_ = param; + break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (param < 1.f) { return GL_INVALID_VALUE; @@ -944,8 +1024,8 @@ bool Texture::ClearLevel( // but only the decoder knows all the state (like unpack_alignment_) that's // needed to be able to call GL correctly. bool cleared = decoder->ClearLevel( - service_id_, target_, info.target, info.level, info.internal_format, - info.format, info.type, info.width, info.height, immutable_); + this, info.target, info.level, info.internal_format, info.format, + info.type, info.width, info.height, immutable_); UpdateMipCleared(&info, cleared); return info.cleared; } @@ -1028,6 +1108,8 @@ TextureManager::TextureManager(MemoryTracker* memory_tracker, FeatureInfo* feature_info, GLint max_texture_size, GLint max_cube_map_texture_size, + GLint max_rectangle_texture_size, + GLint max_3d_texture_size, bool use_default_textures) : memory_tracker_managed_( new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)), @@ -1037,6 +1119,8 @@ TextureManager::TextureManager(MemoryTracker* memory_tracker, framebuffer_manager_(NULL), max_texture_size_(max_texture_size), max_cube_map_texture_size_(max_cube_map_texture_size), + max_rectangle_texture_size_(max_rectangle_texture_size), + max_3d_texture_size_(max_3d_texture_size), max_levels_(ComputeMipMapCount(GL_TEXTURE_2D, max_texture_size, max_texture_size, @@ -1045,6 +1129,11 @@ TextureManager::TextureManager(MemoryTracker* memory_tracker, max_cube_map_texture_size, max_cube_map_texture_size, max_cube_map_texture_size)), + max_3d_levels_(ComputeMipMapCount(GL_TEXTURE_3D, + // Same as GL_TEXTURE_2D_ARRAY + max_3d_texture_size, + max_3d_texture_size, + max_3d_texture_size)), use_default_textures_(use_default_textures), num_unrenderable_textures_(0), num_unsafe_textures_(0), @@ -1547,6 +1636,12 @@ TextureRef* TextureManager::GetTextureInfoForTarget( case GL_TEXTURE_RECTANGLE_ARB: texture = unit.bound_texture_rectangle_arb.get(); break; + case GL_TEXTURE_3D: + texture = unit.bound_texture_3d.get(); + break; + case GL_TEXTURE_2D_ARRAY: + texture = unit.bound_texture_2d_array.get(); + break; default: NOTREACHED(); return NULL; @@ -1642,8 +1737,8 @@ void TextureManager::ValidateAndDoTexImage2D( } GLenum TextureManager::AdjustTexFormat(GLenum format) const { - // TODO: GLES 3 allows for internal format and format to differ. This logic - // may need to change as a result. + // TODO(bajones): GLES 3 allows for internal format and format to differ. + // This logic may need to change as a result. if (gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) { if (format == GL_SRGB_EXT) return GL_RGB; @@ -1665,7 +1760,8 @@ void TextureManager::DoTexImage2D( GLenum tex_type = 0; GLenum tex_format = 0; bool level_is_same = - texture->GetLevelSize(args.target, args.level, &tex_width, &tex_height) && + texture->GetLevelSize( + args.target, args.level, &tex_width, &tex_height, nullptr) && texture->GetLevelType(args.target, args.level, &tex_type, &tex_format) && args.width == tex_width && args.height == tex_height && args.type == tex_type && args.format == tex_format; @@ -1716,13 +1812,13 @@ void TextureManager::DoTexImage2D( ScopedTextureUploadTimer::ScopedTextureUploadTimer( DecoderTextureState* texture_state) : texture_state_(texture_state), - begin_time_(base::TimeTicks::HighResNow()) { + begin_time_(base::TimeTicks::Now()) { } ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { texture_state_->texture_upload_count++; texture_state_->total_texture_upload_time += - base::TimeTicks::HighResNow() - begin_time_; + base::TimeTicks::Now() - begin_time_; } } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/texture_manager.h b/chromium/gpu/command_buffer/service/texture_manager.h index 3ab546763f9..5feeadc4d2c 100644 --- a/chromium/gpu/command_buffer/service/texture_manager.h +++ b/chromium/gpu/command_buffer/service/texture_manager.h @@ -48,6 +48,10 @@ class GPU_EXPORT Texture { return mag_filter_; } + GLenum wrap_r() const { + return wrap_r_; + } + GLenum wrap_s() const { return wrap_s_; } @@ -64,6 +68,30 @@ class GPU_EXPORT Texture { return pool_; } + GLenum compare_func() const { + return compare_func_; + } + + GLenum compare_mode() const { + return compare_mode_; + } + + GLfloat max_lod() const { + return max_lod_; + } + + GLfloat min_lod() const { + return min_lod_; + } + + GLint base_level() const { + return base_level_; + } + + GLint max_level() const { + return max_level_; + } + int num_uncleared_mips() const { return num_uncleared_mips_; } @@ -97,10 +125,12 @@ class GPU_EXPORT Texture { return cleared_; } - // Get the width and height for a particular level. Returns false if level + // Get the width/height/depth for a particular level. Returns false if level // does not exist. + // |depth| is optional and can be nullptr. bool GetLevelSize( - GLint target, GLint level, GLsizei* width, GLsizei* height) const; + GLint target, GLint level, + GLsizei* width, GLsizei* height, GLsizei* depth) const; // Get the type of a level. Returns false if level does not exist. bool GetLevelType( @@ -121,8 +151,10 @@ class GPU_EXPORT Texture { GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, + GLsizei depth, GLenum type) const; bool IsValid() const { @@ -314,6 +346,7 @@ class GPU_EXPORT Texture { // Parameters: // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP or // GL_TEXTURE_EXTERNAL_OES or GL_TEXTURE_RECTANGLE_ARB + // GL_TEXTURE_2D_ARRAY or GL_TEXTURE_3D (for GLES3) // max_levels: The maximum levels this type of target can have. void SetTarget( const FeatureInfo* feature_info, GLenum target, GLint max_levels); @@ -381,15 +414,23 @@ class GPU_EXPORT Texture { int num_npot_faces_; // The target. 0 if unset, otherwise GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP. + // Or GL_TEXTURE_2D_ARRAY or GL_TEXTURE_3D (for GLES3). GLenum target_; // Texture parameters. GLenum min_filter_; GLenum mag_filter_; + GLenum wrap_r_; GLenum wrap_s_; GLenum wrap_t_; GLenum usage_; GLenum pool_; + GLenum compare_func_; + GLenum compare_mode_; + GLfloat max_lod_; + GLfloat min_lod_; + GLint base_level_; + GLint max_level_; // The maximum level that has been set. GLint max_level_set_; @@ -530,6 +571,8 @@ class GPU_EXPORT TextureManager { FeatureInfo* feature_info, GLsizei max_texture_size, GLsizei max_cube_map_texture_size, + GLsizei max_rectangle_texture_size, + GLsizei max_3d_texture_size, bool use_default_textures); ~TextureManager(); @@ -550,6 +593,9 @@ class GPU_EXPORT TextureManager { return max_levels_; case GL_TEXTURE_EXTERNAL_OES: return 1; + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + return max_3d_levels_; default: return max_cube_map_levels_; } @@ -561,6 +607,11 @@ class GPU_EXPORT TextureManager { case GL_TEXTURE_2D: case GL_TEXTURE_EXTERNAL_OES: return max_texture_size_; + case GL_TEXTURE_RECTANGLE: + return max_rectangle_texture_size_; + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + return max_3d_texture_size_; default: return max_cube_map_texture_size_; } @@ -591,6 +642,7 @@ class GPU_EXPORT TextureManager { // Sets the Texture's target // Parameters: // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP + // GL_TEXTURE_2D_ARRAY or GL_TEXTURE_3D (for GLES3) // max_levels: The maximum levels this type of target can have. void SetTarget( TextureRef* ref, @@ -831,8 +883,11 @@ class GPU_EXPORT TextureManager { GLsizei max_texture_size_; GLsizei max_cube_map_texture_size_; + GLsizei max_rectangle_texture_size_; + GLsizei max_3d_texture_size_; GLint max_levels_; GLint max_cube_map_levels_; + GLint max_3d_levels_; const bool use_default_textures_; diff --git a/chromium/gpu/command_buffer/service/texture_manager_unittest.cc b/chromium/gpu/command_buffer/service/texture_manager_unittest.cc index 3278b4eef34..b89e5e9579a 100644 --- a/chromium/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/texture_manager_unittest.cc @@ -47,7 +47,9 @@ class TextureManagerTest : public GpuServiceTest { public: static const GLint kMaxTextureSize = 16; static const GLint kMaxCubeMapTextureSize = 8; + static const GLint kMaxRectangleTextureSize = 16; static const GLint kMaxExternalTextureSize = 16; + static const GLint kMax3DTextureSize = 256; static const GLint kMax2dLevels = 5; static const GLint kMaxCubeMapLevels = 4; static const GLint kMaxExternalLevels = 1; @@ -64,6 +66,8 @@ class TextureManagerTest : public GpuServiceTest { feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures)); TestHelper::SetupTextureManagerInitExpectations( gl_.get(), "", kUseDefaultTextures); @@ -93,6 +97,7 @@ class TextureManagerTest : public GpuServiceTest { #ifndef COMPILER_MSVC const GLint TextureManagerTest::kMaxTextureSize; const GLint TextureManagerTest::kMaxCubeMapTextureSize; +const GLint TextureManagerTest::kMaxRectangleTextureSize; const GLint TextureManagerTest::kMaxExternalTextureSize; const GLint TextureManagerTest::kMax2dLevels; const GLint TextureManagerTest::kMaxCubeMapLevels; @@ -172,6 +177,8 @@ TEST_F(TextureManagerTest, UseDefaultTexturesTrue) { feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, use_default_textures); manager.Initialize(); @@ -191,6 +198,8 @@ TEST_F(TextureManagerTest, UseDefaultTexturesFalse) { feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, use_default_textures); manager.Initialize(); @@ -209,6 +218,8 @@ TEST_F(TextureManagerTest, TextureUsageExt) { feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures); manager.Initialize(); const GLuint kClient1Id = 1; @@ -235,6 +246,8 @@ TEST_F(TextureManagerTest, Destroy) { feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures); manager.Initialize(); // Check we can create texture. @@ -287,6 +300,8 @@ TEST_F(TextureManagerTest, MaxValues) { manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_Z)); EXPECT_EQ(kMaxCubeMapTextureSize, manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)); + EXPECT_EQ(kMaxRectangleTextureSize, + manager_->MaxSizeForTarget(GL_TEXTURE_RECTANGLE_ARB)); EXPECT_EQ(kMaxExternalTextureSize, manager_->MaxSizeForTarget(GL_TEXTURE_EXTERNAL_OES)); } @@ -371,6 +386,8 @@ TEST_F(TextureManagerTest, ValidForTargetNPOT) { feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures); // Check NPOT width on level 0 EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 0, 5, 2, 1)); @@ -387,6 +404,8 @@ class TextureTestBase : public GpuServiceTest { public: static const GLint kMaxTextureSize = 16; static const GLint kMaxCubeMapTextureSize = 8; + static const GLint kMaxRectangleTextureSize = 16; + static const GLint kMax3DTextureSize = 256; static const GLint kMax2dLevels = 5; static const GLint kMaxCubeMapLevels = 4; static const GLuint kClient1Id = 1; @@ -411,6 +430,8 @@ class TextureTestBase : public GpuServiceTest { feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures)); decoder_.reset(new ::testing::StrictMock<gles2::MockGLES2Decoder>()); error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>()); @@ -844,6 +865,8 @@ TEST_F(TextureTest, NPOT2DNPOTOK) { feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); @@ -1018,31 +1041,37 @@ TEST_F(TextureTest, POTCubeMap) { } TEST_F(TextureTest, GetLevelSize) { - manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); + manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_3D); manager_->SetLevelInfo(texture_ref_.get(), - GL_TEXTURE_2D, + GL_TEXTURE_3D, 1, GL_RGBA, 4, 5, - 1, + 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); GLsizei width = -1; GLsizei height = -1; + GLsizei depth = -1; Texture* texture = texture_ref_->texture(); - EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, -1, &width, &height)); - EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 1000, &width, &height)); - EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); + EXPECT_FALSE( + texture->GetLevelSize(GL_TEXTURE_3D, -1, &width, &height, &depth)); + EXPECT_FALSE( + texture->GetLevelSize(GL_TEXTURE_3D, 1000, &width, &height, &depth)); + EXPECT_FALSE( + texture->GetLevelSize(GL_TEXTURE_3D, 0, &width, &height, &depth)); + EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_3D, 1, &width, &height, &depth)); EXPECT_EQ(4, width); EXPECT_EQ(5, height); + EXPECT_EQ(6, depth); manager_->RemoveTexture(kClient1Id); - EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); + EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_3D, 1, &width, &height, &depth)); EXPECT_EQ(4, width); EXPECT_EQ(5, height); + EXPECT_EQ(6, depth); } TEST_F(TextureTest, GetLevelType) { @@ -1081,7 +1110,7 @@ TEST_F(TextureTest, ValidForTexture) { GL_RGBA, 4, 5, - 1, + 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, @@ -1090,40 +1119,49 @@ TEST_F(TextureTest, ValidForTexture) { Texture* texture = texture_ref_->texture(); EXPECT_FALSE(texture->ValidForTexture( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, - 1, 0, 0, 4, 5, GL_UNSIGNED_BYTE)); + 1, 0, 0, 0, 4, 5, 6, GL_UNSIGNED_BYTE)); // Check bad level. EXPECT_FALSE(texture->ValidForTexture( - GL_TEXTURE_2D, 0, 0, 0, 4, 5, GL_UNSIGNED_BYTE)); + GL_TEXTURE_2D, 0, 0, 0, 0, 4, 5, 6, GL_UNSIGNED_BYTE)); // Check bad xoffset. EXPECT_FALSE(texture->ValidForTexture( - GL_TEXTURE_2D, 1, -1, 0, 4, 5, GL_UNSIGNED_BYTE)); + GL_TEXTURE_2D, 1, -1, 0, 0, 4, 5, 6, GL_UNSIGNED_BYTE)); // Check bad xoffset + width > width. EXPECT_FALSE(texture->ValidForTexture( - GL_TEXTURE_2D, 1, 1, 0, 4, 5, GL_UNSIGNED_BYTE)); + GL_TEXTURE_2D, 1, 1, 0, 0, 4, 5, 6, GL_UNSIGNED_BYTE)); // Check bad yoffset. EXPECT_FALSE(texture->ValidForTexture( - GL_TEXTURE_2D, 1, 0, -1, 4, 5, GL_UNSIGNED_BYTE)); + GL_TEXTURE_2D, 1, 0, -1, 0, 4, 5, 6, GL_UNSIGNED_BYTE)); // Check bad yoffset + height > height. EXPECT_FALSE(texture->ValidForTexture( - GL_TEXTURE_2D, 1, 0, 1, 4, 5, GL_UNSIGNED_BYTE)); + GL_TEXTURE_2D, 1, 0, 1, 0, 4, 5, 6, GL_UNSIGNED_BYTE)); + // Check bad zoffset. + EXPECT_FALSE(texture->ValidForTexture( + GL_TEXTURE_2D, 1, 0, 0, -1, 4, 5, 6, GL_UNSIGNED_BYTE)); + // Check bad zoffset + depth > depth. + EXPECT_FALSE(texture->ValidForTexture( + GL_TEXTURE_2D, 1, 0, 0, 1, 4, 5, 6, GL_UNSIGNED_BYTE)); // Check bad width. EXPECT_FALSE(texture->ValidForTexture( - GL_TEXTURE_2D, 1, 0, 0, 5, 5, GL_UNSIGNED_BYTE)); + GL_TEXTURE_2D, 1, 0, 0, 0, 5, 5, 6, GL_UNSIGNED_BYTE)); // Check bad height. EXPECT_FALSE(texture->ValidForTexture( - GL_TEXTURE_2D, 1, 0, 0, 4, 6, GL_UNSIGNED_BYTE)); + GL_TEXTURE_2D, 1, 0, 0, 0, 4, 6, 6, GL_UNSIGNED_BYTE)); + // Check bad depth. + EXPECT_FALSE(texture->ValidForTexture( + GL_TEXTURE_2D, 1, 0, 0, 0, 4, 5, 7, GL_UNSIGNED_BYTE)); // Check bad type. EXPECT_FALSE(texture->ValidForTexture( - GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_UNSIGNED_SHORT_4_4_4_4)); + GL_TEXTURE_2D, 1, 0, 0, 0, 4, 5, 6, GL_UNSIGNED_SHORT_4_4_4_4)); // Check valid full size EXPECT_TRUE(texture->ValidForTexture( - GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_UNSIGNED_BYTE)); + GL_TEXTURE_2D, 1, 0, 0, 0, 4, 5, 6, GL_UNSIGNED_BYTE)); // Check valid particial size. EXPECT_TRUE(texture->ValidForTexture( - GL_TEXTURE_2D, 1, 1, 1, 2, 3, GL_UNSIGNED_BYTE)); + GL_TEXTURE_2D, 1, 1, 1, 1, 2, 3, 4, GL_UNSIGNED_BYTE)); manager_->RemoveTexture(kClient1Id); EXPECT_TRUE(texture->ValidForTexture( - GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_UNSIGNED_BYTE)); + GL_TEXTURE_2D, 1, 0, 0, 0, 4, 5, 6, GL_UNSIGNED_BYTE)); } TEST_F(TextureTest, FloatNotLinear) { @@ -1135,6 +1173,8 @@ TEST_F(TextureTest, FloatNotLinear) { feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); @@ -1165,6 +1205,8 @@ TEST_F(TextureTest, FloatLinear) { feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); @@ -1187,6 +1229,8 @@ TEST_F(TextureTest, HalfFloatNotLinear) { feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); @@ -1217,6 +1261,8 @@ TEST_F(TextureTest, HalfFloatLinear) { feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); @@ -1239,6 +1285,8 @@ TEST_F(TextureTest, EGLImageExternal) { feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); @@ -1259,6 +1307,8 @@ TEST_F(TextureTest, DepthTexture) { feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, + kMaxRectangleTextureSize, + kMax3DTextureSize, kUseDefaultTextures); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); @@ -1491,7 +1541,7 @@ TEST_F(TextureTest, SafeUnsafe) { } TEST_F(TextureTest, ClearTexture) { - EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _, _)) + EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _)) .WillRepeatedly(Return(true)); manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); manager_->SetLevelInfo(texture_ref_.get(), @@ -1960,7 +2010,7 @@ class ProduceConsumeTextureTest : public TextureTest, LevelInfo info; info.target = target; EXPECT_TRUE(texture->GetLevelSize(target, level, &info.width, - &info.height)); + &info.height, &info.depth)); EXPECT_TRUE(texture->GetLevelType(target, level, &info.type, &info.format)); info.cleared = texture->IsLevelCleared(target, level); @@ -2024,7 +2074,7 @@ TEST_F(ProduceConsumeTextureTest, ProduceConsume2D) { texture = restored_texture->texture(); EXPECT_EQ(64U + 16U + 4U, texture->estimated_size()); GLint w, h; - EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 3, &w, &h)); + EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 3, &w, &h, nullptr)); // However the old texture ref still exists if it was referenced somewhere. EXPECT_EQ(1024U + 256U + 64U + 16U + 4U, @@ -2053,7 +2103,7 @@ TEST_F(ProduceConsumeTextureTest, ProduceConsumeClearRectangle) { // See if we can clear the previously uncleared level now. EXPECT_EQ(level0, GetLevelInfo(restored_texture.get(), GL_TEXTURE_RECTANGLE_ARB, 0)); - EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _, _)) + EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _)) .WillRepeatedly(Return(true)); EXPECT_TRUE(manager_->ClearTextureLevel( decoder_.get(), restored_texture.get(), GL_TEXTURE_RECTANGLE_ARB, 0)); @@ -2199,6 +2249,8 @@ class SharedTextureTest : public GpuServiceTest { feature_info_.get(), TextureManagerTest::kMaxTextureSize, TextureManagerTest::kMaxCubeMapTextureSize, + TextureManagerTest::kMaxRectangleTextureSize, + TextureManagerTest::kMax3DTextureSize, kUseDefaultTextures)); memory_tracker2_ = new CountingMemoryTracker; texture_manager2_.reset( @@ -2206,6 +2258,8 @@ class SharedTextureTest : public GpuServiceTest { feature_info_.get(), TextureManagerTest::kMaxTextureSize, TextureManagerTest::kMaxCubeMapTextureSize, + TextureManagerTest::kMaxRectangleTextureSize, + TextureManagerTest::kMax3DTextureSize, kUseDefaultTextures)); TestHelper::SetupTextureManagerInitExpectations( gl_.get(), "", kUseDefaultTextures); diff --git a/chromium/gpu/command_buffer/service/transfer_buffer_manager.cc b/chromium/gpu/command_buffer/service/transfer_buffer_manager.cc index 4404a9eb6c4..e9c83e01d00 100644 --- a/chromium/gpu/command_buffer/service/transfer_buffer_manager.cc +++ b/chromium/gpu/command_buffer/service/transfer_buffer_manager.cc @@ -8,8 +8,8 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" -#include "base/debug/trace_event.h" #include "base/process/process_handle.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/common/cmd_buffer_common.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" diff --git a/chromium/gpu/command_buffer/service/valuebuffer_manager.cc b/chromium/gpu/command_buffer/service/valuebuffer_manager.cc index eb4db093f70..96a50aa0db2 100644 --- a/chromium/gpu/command_buffer/service/valuebuffer_manager.cc +++ b/chromium/gpu/command_buffer/service/valuebuffer_manager.cc @@ -2,59 +2,113 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "gpu/command_buffer/service/valuebuffer_manager.h" - +#include "gpu/command_buffer/service/gl_utils.h" #include "gpu/command_buffer/service/program_manager.h" +#include "gpu/command_buffer/service/valuebuffer_manager.h" namespace gpu { namespace gles2 { -Valuebuffer::Valuebuffer(ValuebufferManager* manager, GLuint client_id) +SubscriptionRefSet::Observer::~Observer() { +} + +SubscriptionRefSet::SubscriptionRefSet() { +} + +SubscriptionRefSet::~SubscriptionRefSet() { + // Make sure no valuebuffers are still holding references to targets + DCHECK(reference_set_.empty()); +} + +void SubscriptionRefSet::AddSubscription(unsigned int target) { + RefSet::iterator it = reference_set_.find(target); + if (it == reference_set_.end()) { + reference_set_.insert(std::make_pair(target, 1)); + FOR_EACH_OBSERVER(Observer, observers_, OnAddSubscription(target)); + } else { + ++it->second; + } +} + +void SubscriptionRefSet::RemoveSubscription(unsigned int target) { + RefSet::iterator it = reference_set_.find(target); + DCHECK(it != reference_set_.end()); + if (it->second == 1) { + reference_set_.erase(it); + FOR_EACH_OBSERVER(Observer, observers_, OnRemoveSubscription(target)); + } else { + --it->second; + } +} + +void SubscriptionRefSet::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void SubscriptionRefSet::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +Valuebuffer::Valuebuffer(ValuebufferManager* manager, unsigned int client_id) : manager_(manager), client_id_(client_id), has_been_bound_(false) { manager_->StartTracking(this); + active_state_map_ = new ValueStateMap(); } Valuebuffer::~Valuebuffer() { if (manager_) { + for (SubscriptionSet::const_iterator it = subscriptions_.begin(); + it != subscriptions_.end(); ++it) { + manager_->NotifyRemoveSubscription(*it); + } manager_->StopTracking(this); manager_ = NULL; } } -void Valuebuffer::AddSubscription(GLenum subscription) { - subscriptions_.insert(subscription); +void Valuebuffer::AddSubscription(unsigned int subscription) { + if (subscriptions_.find(subscription) == subscriptions_.end()) { + subscriptions_.insert(subscription); + manager_->NotifyAddSubscription(subscription); + } } -void Valuebuffer::RemoveSubscription(GLenum subscription) { - subscriptions_.erase(subscription); +void Valuebuffer::RemoveSubscription(unsigned int subscription) { + SubscriptionSet::iterator it = subscriptions_.find(subscription); + if (subscriptions_.find(subscription) != subscriptions_.end()) { + subscriptions_.erase(it); + manager_->NotifyRemoveSubscription(subscription); + } } -bool Valuebuffer::IsSubscribed(GLenum subscription) { +bool Valuebuffer::IsSubscribed(unsigned int subscription) { return subscriptions_.find(subscription) != subscriptions_.end(); } -const ValueState *Valuebuffer::GetState(GLenum target) const { - StateMap::const_iterator it = active_state_map_.find(target); - return it != active_state_map_.end() ? &it->second : NULL; +const ValueState* Valuebuffer::GetState(unsigned int target) const { + return active_state_map_->GetState(target); } -void Valuebuffer::UpdateState(const StateMap& pending_state) { +void Valuebuffer::UpdateState(const ValueStateMap* pending_state) { + DCHECK(pending_state); for (SubscriptionSet::const_iterator it = subscriptions_.begin(); it != subscriptions_.end(); ++it) { - StateMap::const_iterator pending_state_it = pending_state.find((*it)); - if (pending_state_it != pending_state.end()) { - active_state_map_[pending_state_it->first] = pending_state_it->second; + const ValueState *state = pending_state->GetState(*it); + if (state != NULL) { + active_state_map_->UpdateState(*it, *state); } } } -ValuebufferManager::ValuebufferManager() - : valuebuffer_count_(0) { +ValuebufferManager::ValuebufferManager(SubscriptionRefSet* ref_set, + ValueStateMap* state_map) + : valuebuffer_count_(0), + pending_state_map_(state_map), + subscription_ref_set_(ref_set) { } ValuebufferManager::~ValuebufferManager() { DCHECK(valuebuffer_map_.empty()); - DCHECK(pending_state_map_.empty()); // If this triggers, that means something is keeping a reference to // a Valuebuffer belonging to this. CHECK_EQ(valuebuffer_count_, 0u); @@ -62,7 +116,6 @@ ValuebufferManager::~ValuebufferManager() { void ValuebufferManager::Destroy() { valuebuffer_map_.clear(); - pending_state_map_.clear(); } void ValuebufferManager::StartTracking(Valuebuffer* /* valuebuffer */) { @@ -73,19 +126,26 @@ void ValuebufferManager::StopTracking(Valuebuffer* /* valuebuffer */) { --valuebuffer_count_; } -void ValuebufferManager::CreateValuebuffer(GLuint client_id) { +void ValuebufferManager::NotifyAddSubscription(unsigned int target) { + subscription_ref_set_->AddSubscription(target); +} +void ValuebufferManager::NotifyRemoveSubscription(unsigned int target) { + subscription_ref_set_->RemoveSubscription(target); +} + +void ValuebufferManager::CreateValuebuffer(unsigned int client_id) { scoped_refptr<Valuebuffer> valuebuffer(new Valuebuffer(this, client_id)); std::pair<ValuebufferMap::iterator, bool> result = valuebuffer_map_.insert(std::make_pair(client_id, valuebuffer)); DCHECK(result.second); } -Valuebuffer* ValuebufferManager::GetValuebuffer(GLuint client_id) { +Valuebuffer* ValuebufferManager::GetValuebuffer(unsigned int client_id) { ValuebufferMap::iterator it = valuebuffer_map_.find(client_id); return it != valuebuffer_map_.end() ? it->second.get() : NULL; } -void ValuebufferManager::RemoveValuebuffer(GLuint client_id) { +void ValuebufferManager::RemoveValuebuffer(unsigned int client_id) { ValuebufferMap::iterator it = valuebuffer_map_.find(client_id); if (it != valuebuffer_map_.end()) { Valuebuffer* valuebuffer = it->second.get(); @@ -96,15 +156,10 @@ void ValuebufferManager::RemoveValuebuffer(GLuint client_id) { void ValuebufferManager::UpdateValuebufferState(Valuebuffer* valuebuffer) { DCHECK(valuebuffer); - valuebuffer->UpdateState(pending_state_map_); -} - -void ValuebufferManager::UpdateValueState( - GLenum target, const ValueState& state) { - pending_state_map_[target] = state; + valuebuffer->UpdateState(pending_state_map_.get()); } -uint32 ValuebufferManager::ApiTypeForSubscriptionTarget(GLenum target) { +uint32 ValuebufferManager::ApiTypeForSubscriptionTarget(unsigned int target) { switch (target) { case GL_MOUSE_POSITION_CHROMIUM: return Program::kUniform2i; diff --git a/chromium/gpu/command_buffer/service/valuebuffer_manager.h b/chromium/gpu/command_buffer/service/valuebuffer_manager.h index 3cc4ac194a8..d67616a104b 100644 --- a/chromium/gpu/command_buffer/service/valuebuffer_manager.h +++ b/chromium/gpu/command_buffer/service/valuebuffer_manager.h @@ -9,24 +9,59 @@ #include "base/containers/hash_tables.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "gpu/command_buffer/service/gl_utils.h" +#include "base/observer_list.h" +#include "gpu/command_buffer/common/value_state.h" #include "gpu/gpu_export.h" +namespace content { +class GpuChannel; +} + namespace gpu { namespace gles2 { class ValuebufferManager; -union ValueState { - float float_value[4]; - int int_value[4]; +class GPU_EXPORT SubscriptionRefSet + : public base::RefCounted<SubscriptionRefSet> { + public: + class GPU_EXPORT Observer { + public: + virtual ~Observer(); + + virtual void OnAddSubscription(unsigned int target) = 0; + virtual void OnRemoveSubscription(unsigned int target) = 0; + }; + + SubscriptionRefSet(); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + protected: + virtual ~SubscriptionRefSet(); + + private: + friend class base::RefCounted<SubscriptionRefSet>; + friend class ValuebufferManager; + + typedef base::hash_map<unsigned int, int> RefSet; + + void AddSubscription(unsigned int target); + void RemoveSubscription(unsigned int target); + + RefSet reference_set_; + + ObserverList<Observer, true> observers_; + + DISALLOW_COPY_AND_ASSIGN(SubscriptionRefSet); }; class GPU_EXPORT Valuebuffer : public base::RefCounted<Valuebuffer> { public: - Valuebuffer(ValuebufferManager* manager, GLuint client_id); + Valuebuffer(ValuebufferManager* manager, unsigned int client_id); - GLuint client_id() const { return client_id_; } + unsigned int client_id() const { return client_id_; } bool IsDeleted() const { return client_id_ == 0; } @@ -34,26 +69,25 @@ class GPU_EXPORT Valuebuffer : public base::RefCounted<Valuebuffer> { bool IsValid() const { return has_been_bound_ && !IsDeleted(); } - void AddSubscription(GLenum subscription); - void RemoveSubscription(GLenum subscription); + void AddSubscription(unsigned int subscription); + void RemoveSubscription(unsigned int subscription); // Returns true if this Valuebuffer is subscribed to subscription - bool IsSubscribed(GLenum subscription); + bool IsSubscribed(unsigned int subscription); // Returns the active state for a given target in this Valuebuffer // returns NULL if target state doesn't exist - const ValueState* GetState(GLenum target) const; + const ValueState* GetState(unsigned int target) const; private: friend class ValuebufferManager; friend class base::RefCounted<Valuebuffer>; - typedef base::hash_map<GLenum, ValueState> StateMap; - typedef base::hash_set<GLenum> SubscriptionSet; + typedef base::hash_set<unsigned int> SubscriptionSet; ~Valuebuffer(); - void UpdateState(const StateMap& pending_state); + void UpdateState(const ValueStateMap* pending_state); void MarkAsDeleted() { client_id_ = 0; } @@ -61,58 +95,64 @@ class GPU_EXPORT Valuebuffer : public base::RefCounted<Valuebuffer> { ValuebufferManager* manager_; // Client side Valuebuffer id. - GLuint client_id_; + unsigned int client_id_; // Whether this Valuebuffer has ever been bound. bool has_been_bound_; SubscriptionSet subscriptions_; - StateMap active_state_map_; + scoped_refptr<ValueStateMap> active_state_map_; }; class GPU_EXPORT ValuebufferManager { public: - ValuebufferManager(); + ValuebufferManager(SubscriptionRefSet* ref_set, ValueStateMap* state_map); ~ValuebufferManager(); // Must call before destruction. void Destroy(); // Creates a Valuebuffer for the given Valuebuffer ids. - void CreateValuebuffer(GLuint client_id); + void CreateValuebuffer(unsigned int client_id); // Gets the Valuebuffer for the given Valuebuffer id. - Valuebuffer* GetValuebuffer(GLuint client_id); + Valuebuffer* GetValuebuffer(unsigned int client_id); // Removes a Valuebuffer for the given Valuebuffer id. - void RemoveValuebuffer(GLuint client_id); + void RemoveValuebuffer(unsigned int client_id); // Updates the value state for the given Valuebuffer void UpdateValuebufferState(Valuebuffer* valuebuffer); - // Gets the state for the given subscription target - void UpdateValueState(GLenum target, const ValueState& state); - - static uint32 ApiTypeForSubscriptionTarget(GLenum target); + static uint32 ApiTypeForSubscriptionTarget(unsigned int target); private: friend class Valuebuffer; - typedef base::hash_map<GLuint, scoped_refptr<Valuebuffer>> ValuebufferMap; + typedef base::hash_map<unsigned int, scoped_refptr<Valuebuffer>> + ValuebufferMap; void StartTracking(Valuebuffer* valuebuffer); void StopTracking(Valuebuffer* valuebuffer); + void NotifyAddSubscription(unsigned int target); + void NotifyRemoveSubscription(unsigned int target); + // Counts the number of Valuebuffer allocated with 'this' as its manager. // Allows to check no Valuebuffer will outlive this. - unsigned valuebuffer_count_; + unsigned int valuebuffer_count_; // Info for each Valuebuffer in the system. ValuebufferMap valuebuffer_map_; // Current value state in the system - Valuebuffer::StateMap pending_state_map_; + // Updated by GpuChannel + scoped_refptr<ValueStateMap> pending_state_map_; + + // Subscription targets which are currently subscribed and how + // many value buffers are currently subscribed to each + scoped_refptr<SubscriptionRefSet> subscription_ref_set_; DISALLOW_COPY_AND_ASSIGN(ValuebufferManager); }; diff --git a/chromium/gpu/command_buffer/service/valuebuffer_manager_unittest.cc b/chromium/gpu/command_buffer/service/valuebuffer_manager_unittest.cc index ead5df5d166..c5d0c6c0f98 100644 --- a/chromium/gpu/command_buffer/service/valuebuffer_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/valuebuffer_manager_unittest.cc @@ -9,11 +9,13 @@ #include "base/strings/string_util.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/common/value_state.h" #include "gpu/command_buffer/service/common_decoder.h" #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gpu_service_test.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/test_helper.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_mock.h" @@ -21,49 +23,74 @@ namespace gpu { namespace gles2 { +class MockSubscriptionRefSetObserver : public SubscriptionRefSet::Observer { + public: + MOCK_METHOD1(OnAddSubscription, void(unsigned int target)); + MOCK_METHOD1(OnRemoveSubscription, void(unsigned int target)); +}; + class ValuebufferManagerTest : public GpuServiceTest { public: - ValuebufferManagerTest() : manager_() {} - ~ValuebufferManagerTest() override { manager_.Destroy(); } + ValuebufferManagerTest() {} + ~ValuebufferManagerTest() override {} + + void SetUp() override { + GpuServiceTest::SetUp(); + subscription_ref_set_ = new SubscriptionRefSet(); + pending_state_map_ = new ValueStateMap(); + subscription_ref_set_->AddObserver(&mock_observer_); + manager_.reset(new ValuebufferManager(subscription_ref_set_.get(), + pending_state_map_.get())); + } + + void TearDown() override { + manager_->Destroy(); + subscription_ref_set_->RemoveObserver(&mock_observer_); + GpuServiceTest::TearDown(); + } protected: - ValuebufferManager manager_; + MockSubscriptionRefSetObserver mock_observer_; + + scoped_refptr<SubscriptionRefSet> subscription_ref_set_; + scoped_refptr<ValueStateMap> pending_state_map_; + scoped_ptr<ValuebufferManager> manager_; }; TEST_F(ValuebufferManagerTest, Basic) { const GLuint kClient1Id = 1; const GLuint kClient2Id = 2; // Check we can create a Valuebuffer - manager_.CreateValuebuffer(kClient1Id); - Valuebuffer* valuebuffer0 = manager_.GetValuebuffer(kClient1Id); + manager_->CreateValuebuffer(kClient1Id); + Valuebuffer* valuebuffer0 = manager_->GetValuebuffer(kClient1Id); ASSERT_TRUE(valuebuffer0 != NULL); EXPECT_EQ(kClient1Id, valuebuffer0->client_id()); // Check we get nothing for a non-existent Valuebuffer. // Check trying to a remove non-existent Valuebuffer does not crash - manager_.RemoveValuebuffer(kClient2Id); + manager_->RemoveValuebuffer(kClient2Id); // Check we can't get the renderbuffer after we remove it. - manager_.RemoveValuebuffer(kClient1Id); - EXPECT_TRUE(manager_.GetValuebuffer(kClient1Id) == NULL); + manager_->RemoveValuebuffer(kClient1Id); + EXPECT_TRUE(manager_->GetValuebuffer(kClient1Id) == NULL); } TEST_F(ValuebufferManagerTest, Destroy) { const GLuint kClient1Id = 1; // Check we can create Valuebuffer. - manager_.CreateValuebuffer(kClient1Id); - Valuebuffer* valuebuffer0 = manager_.GetValuebuffer(kClient1Id); + manager_->CreateValuebuffer(kClient1Id); + Valuebuffer* valuebuffer0 = manager_->GetValuebuffer(kClient1Id); ASSERT_TRUE(valuebuffer0 != NULL); EXPECT_EQ(kClient1Id, valuebuffer0->client_id()); - manager_.Destroy(); + manager_->Destroy(); // Check the resources were released. - Valuebuffer* valuebuffer1 = manager_.GetValuebuffer(kClient1Id); + Valuebuffer* valuebuffer1 = manager_->GetValuebuffer(kClient1Id); ASSERT_TRUE(valuebuffer1 == NULL); } TEST_F(ValuebufferManagerTest, ValueBuffer) { const GLuint kClient1Id = 1; // Check we can create a Valuebuffer - manager_.CreateValuebuffer(kClient1Id); - Valuebuffer* valuebuffer0 = manager_.GetValuebuffer(kClient1Id); + manager_->CreateValuebuffer(kClient1Id); + Valuebuffer* valuebuffer0 = manager_->GetValuebuffer(kClient1Id); ASSERT_TRUE(valuebuffer0 != NULL); EXPECT_EQ(kClient1Id, valuebuffer0->client_id()); EXPECT_FALSE(valuebuffer0->IsValid()); @@ -75,26 +102,51 @@ TEST_F(ValuebufferManagerTest, UpdateState) { valuestate1.int_value[0] = 111; ValueState valuestate2; valuestate2.int_value[0] = 222; - manager_.CreateValuebuffer(kClient1Id); - Valuebuffer* valuebuffer0 = manager_.GetValuebuffer(kClient1Id); + manager_->CreateValuebuffer(kClient1Id); + Valuebuffer* valuebuffer0 = manager_->GetValuebuffer(kClient1Id); ASSERT_TRUE(valuebuffer0 != NULL); EXPECT_EQ(kClient1Id, valuebuffer0->client_id()); valuebuffer0->AddSubscription(GL_MOUSE_POSITION_CHROMIUM); ASSERT_TRUE(valuebuffer0->GetState(GL_MOUSE_POSITION_CHROMIUM) == NULL); - manager_.UpdateValueState(GL_MOUSE_POSITION_CHROMIUM, valuestate1); - manager_.UpdateValuebufferState(valuebuffer0); + pending_state_map_->UpdateState(GL_MOUSE_POSITION_CHROMIUM, valuestate1); + manager_->UpdateValuebufferState(valuebuffer0); const ValueState* new_state1 = valuebuffer0->GetState(GL_MOUSE_POSITION_CHROMIUM); ASSERT_TRUE(new_state1 != NULL); ASSERT_TRUE(new_state1->int_value[0] == 111); // Ensure state changes - manager_.UpdateValueState(GL_MOUSE_POSITION_CHROMIUM, valuestate2); - manager_.UpdateValuebufferState(valuebuffer0); + pending_state_map_->UpdateState(GL_MOUSE_POSITION_CHROMIUM, valuestate2); + manager_->UpdateValuebufferState(valuebuffer0); const ValueState* new_state2 = valuebuffer0->GetState(GL_MOUSE_POSITION_CHROMIUM); ASSERT_TRUE(new_state2 != NULL); ASSERT_TRUE(new_state2->int_value[0] == 222); } +TEST_F(ValuebufferManagerTest, NotifySubscriptionRefs) { + const GLuint kClientId1 = 1; + const GLuint kClientId2 = 2; + manager_->CreateValuebuffer(kClientId1); + Valuebuffer* valuebuffer1 = manager_->GetValuebuffer(kClientId1); + ASSERT_TRUE(valuebuffer1 != NULL); + manager_->CreateValuebuffer(kClientId2); + Valuebuffer* valuebuffer2 = manager_->GetValuebuffer(kClientId2); + ASSERT_TRUE(valuebuffer2 != NULL); + EXPECT_CALL(mock_observer_, OnAddSubscription(GL_MOUSE_POSITION_CHROMIUM)) + .Times(1); + valuebuffer1->AddSubscription(GL_MOUSE_POSITION_CHROMIUM); + EXPECT_CALL(mock_observer_, OnAddSubscription(GL_MOUSE_POSITION_CHROMIUM)) + .Times(0); + valuebuffer2->AddSubscription(GL_MOUSE_POSITION_CHROMIUM); + EXPECT_CALL(mock_observer_, OnRemoveSubscription(GL_MOUSE_POSITION_CHROMIUM)) + .Times(0); + valuebuffer1->RemoveSubscription(GL_MOUSE_POSITION_CHROMIUM); + // Ensure the manager still thinks a buffer has a reference to the + // subscription target. + EXPECT_CALL(mock_observer_, OnRemoveSubscription(GL_MOUSE_POSITION_CHROMIUM)) + .Times(1); + valuebuffer2->RemoveSubscription(GL_MOUSE_POSITION_CHROMIUM); +} + } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/vertex_array_manager.cc b/chromium/gpu/command_buffer/service/vertex_array_manager.cc index 1560c043c25..0809eda2861 100644 --- a/chromium/gpu/command_buffer/service/vertex_array_manager.cc +++ b/chromium/gpu/command_buffer/service/vertex_array_manager.cc @@ -3,8 +3,9 @@ // found in the LICENSE file. #include "gpu/command_buffer/service/vertex_array_manager.h" -#include "base/debug/trace_event.h" + #include "base/logging.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/buffer_manager.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" diff --git a/chromium/gpu/command_buffer/service/vertex_array_manager_unittest.cc b/chromium/gpu/command_buffer/service/vertex_array_manager_unittest.cc index 24592b685e5..0d3d1d0a9d0 100644 --- a/chromium/gpu/command_buffer/service/vertex_array_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/vertex_array_manager_unittest.cc @@ -29,7 +29,7 @@ class VertexArrayManagerTest : public GpuServiceTest { protected: void SetUp() override { - GpuServiceTest::SetUp(); + GpuServiceTest::SetUpWithGLVersion("2.1", "GL_ARB_vertex_array_object"); manager_.reset(new VertexArrayManager()); } diff --git a/chromium/gpu/command_buffer/service/vertex_attrib_manager.cc b/chromium/gpu/command_buffer/service/vertex_attrib_manager.cc index 8725c4f9533..f0714f10d81 100644 --- a/chromium/gpu/command_buffer/service/vertex_attrib_manager.cc +++ b/chromium/gpu/command_buffer/service/vertex_attrib_manager.cc @@ -35,6 +35,7 @@ VertexAttrib::VertexAttrib() gl_stride_(0), real_stride_(16), divisor_(0), + integer_(GL_FALSE), is_client_side_array_(false), list_(NULL) { } @@ -49,7 +50,8 @@ void VertexAttrib::SetInfo( GLboolean normalized, GLsizei gl_stride, GLsizei real_stride, - GLsizei offset) { + GLsizei offset, + GLboolean integer) { DCHECK_GT(real_stride, 0); buffer_ = buffer; size_ = size; @@ -58,6 +60,7 @@ void VertexAttrib::SetInfo( gl_stride_ = gl_stride; real_stride_ = real_stride; offset_ = offset; + integer_ = integer; } void VertexAttrib::Unbind(Buffer* buffer) { diff --git a/chromium/gpu/command_buffer/service/vertex_attrib_manager.h b/chromium/gpu/command_buffer/service/vertex_attrib_manager.h index 73fa4807d6e..f7fd4955dca 100644 --- a/chromium/gpu/command_buffer/service/vertex_attrib_manager.h +++ b/chromium/gpu/command_buffer/service/vertex_attrib_manager.h @@ -65,6 +65,10 @@ class GPU_EXPORT VertexAttrib { return divisor_; } + GLboolean integer() const { + return integer_; + } + bool enabled() const { return enabled_; } @@ -112,7 +116,8 @@ class GPU_EXPORT VertexAttrib { GLboolean normalized, GLsizei gl_stride, GLsizei real_stride, - GLsizei offset); + GLsizei offset, + GLboolean integer); void SetDivisor(GLsizei divisor) { divisor_ = divisor; @@ -147,6 +152,8 @@ class GPU_EXPORT VertexAttrib { GLsizei divisor_; + GLboolean integer_; + // Will be true if this was assigned to a client side array. bool is_client_side_array_; @@ -197,7 +204,8 @@ class GPU_EXPORT VertexAttribManager : GLboolean normalized, GLsizei gl_stride, GLsizei real_stride, - GLsizei offset) { + GLsizei offset, + GLboolean integer) { VertexAttrib* attrib = GetVertexAttrib(index); if (attrib) { if (attrib->type() == GL_FIXED) { @@ -206,8 +214,8 @@ class GPU_EXPORT VertexAttribManager : if (type == GL_FIXED) { ++num_fixed_attribs_; } - attrib->SetInfo( - buffer, size, type, normalized, gl_stride, real_stride, offset); + attrib->SetInfo(buffer, size, type, normalized, gl_stride, real_stride, + offset, integer); } } diff --git a/chromium/gpu/command_buffer/service/vertex_attrib_manager_unittest.cc b/chromium/gpu/command_buffer/service/vertex_attrib_manager_unittest.cc index b82858e5edd..81ad6cd2940 100644 --- a/chromium/gpu/command_buffer/service/vertex_attrib_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/vertex_attrib_manager_unittest.cc @@ -105,7 +105,7 @@ TEST_F(VertexAttribManagerTest, SetAttribInfo) { VertexAttrib* attrib = manager_->GetVertexAttrib(1); - manager_->SetAttribInfo(1, buffer, 3, GL_SHORT, GL_TRUE, 32, 32, 4); + manager_->SetAttribInfo(1, buffer, 3, GL_SHORT, GL_TRUE, 32, 32, 4, GL_TRUE); EXPECT_EQ(buffer, attrib->buffer()); EXPECT_EQ(4, attrib->offset()); @@ -113,6 +113,7 @@ TEST_F(VertexAttribManagerTest, SetAttribInfo) { EXPECT_EQ(static_cast<GLenum>(GL_SHORT), attrib->type()); EXPECT_EQ(GL_TRUE, attrib->normalized()); EXPECT_EQ(32, attrib->gl_stride()); + EXPECT_EQ(GL_TRUE, attrib->integer()); // The VertexAttribManager must be destroyed before the BufferManager // so it releases its buffers. @@ -122,13 +123,13 @@ TEST_F(VertexAttribManagerTest, SetAttribInfo) { TEST_F(VertexAttribManagerTest, HaveFixedAttribs) { EXPECT_FALSE(manager_->HaveFixedAttribs()); - manager_->SetAttribInfo(1, NULL, 4, GL_FIXED, GL_FALSE, 0, 16, 0); + manager_->SetAttribInfo(1, NULL, 4, GL_FIXED, GL_FALSE, 0, 16, 0, GL_FALSE); EXPECT_TRUE(manager_->HaveFixedAttribs()); - manager_->SetAttribInfo(3, NULL, 4, GL_FIXED, GL_FALSE, 0, 16, 0); + manager_->SetAttribInfo(3, NULL, 4, GL_FIXED, GL_FALSE, 0, 16, 0, GL_FALSE); EXPECT_TRUE(manager_->HaveFixedAttribs()); - manager_->SetAttribInfo(1, NULL, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); + manager_->SetAttribInfo(1, NULL, 4, GL_FLOAT, GL_FALSE, 0, 16, 0, GL_FALSE); EXPECT_TRUE(manager_->HaveFixedAttribs()); - manager_->SetAttribInfo(3, NULL, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); + manager_->SetAttribInfo(3, NULL, 4, GL_FLOAT, GL_FALSE, 0, 16, 0, GL_FALSE); EXPECT_FALSE(manager_->HaveFixedAttribs()); } @@ -145,7 +146,7 @@ TEST_F(VertexAttribManagerTest, CanAccess) { manager_->Enable(1, true); EXPECT_FALSE(attrib->CanAccess(0)); - manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); + manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 0, GL_FALSE); EXPECT_FALSE(attrib->CanAccess(0)); EXPECT_TRUE(buffer_manager.SetTarget(buffer, GL_ARRAY_BUFFER)); @@ -160,7 +161,7 @@ TEST_F(VertexAttribManagerTest, CanAccess) { EXPECT_TRUE(attrib->CanAccess(0)); EXPECT_FALSE(attrib->CanAccess(1)); - manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 1); + manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 1, GL_FALSE); EXPECT_FALSE(attrib->CanAccess(0)); TestHelper::DoBufferData( @@ -168,9 +169,9 @@ TEST_F(VertexAttribManagerTest, CanAccess) { NULL, GL_NO_ERROR); EXPECT_TRUE(attrib->CanAccess(0)); EXPECT_FALSE(attrib->CanAccess(1)); - manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); + manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 0, GL_FALSE); EXPECT_TRUE(attrib->CanAccess(1)); - manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 20, 0); + manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 20, 0, GL_FALSE); EXPECT_TRUE(attrib->CanAccess(0)); EXPECT_FALSE(attrib->CanAccess(1)); @@ -193,8 +194,10 @@ TEST_F(VertexAttribManagerTest, Unbind) { VertexAttrib* attrib3 = manager_->GetVertexAttrib(3); // Attach to 2 buffers. - manager_->SetAttribInfo(1, buffer1, 3, GL_SHORT, GL_TRUE, 32, 32, 4); - manager_->SetAttribInfo(3, buffer1, 3, GL_SHORT, GL_TRUE, 32, 32, 4); + manager_->SetAttribInfo( + 1, buffer1, 3, GL_SHORT, GL_TRUE, 32, 32, 4, GL_FALSE); + manager_->SetAttribInfo( + 3, buffer1, 3, GL_SHORT, GL_TRUE, 32, 32, 4, GL_FALSE); // Check they were attached. EXPECT_EQ(buffer1, attrib1->buffer()); EXPECT_EQ(buffer1, attrib3->buffer()); |