diff options
author | zmo <zmo@chromium.org> | 2014-12-05 13:51:49 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-12-05 21:52:09 +0000 |
commit | 68fcdc610840bc39b061e7842f78089171ed5e90 (patch) | |
tree | 53495a79dea992b0e4edf78e1ad5b70bb211ef8a | |
parent | e236ebfe96028dbe5e317d5f3c881ba48d246a01 (diff) | |
download | chromium_src-68fcdc610840bc39b061e7842f78089171ed5e90.zip chromium_src-68fcdc610840bc39b061e7842f78089171ed5e90.tar.gz chromium_src-68fcdc610840bc39b061e7842f78089171ed5e90.tar.bz2 |
Add framebuffer object related commands to command buffer.
glInvalidateFramebuffer, glInvalidateSubFramebuffer, glReadBuffer.
All other commands in this group have already been added.
Also, code generator has to be modified to remove the incorrect assumption
that the data pointer is the last arg of a function. This assumption is not
true for glInvalidateSubFramebuffer.
Also, separate the bindings of glDiscardFramebufferEXT and glInvalidateFramebuffer so we have better control of them.
BUG=429053
TEST=gpu_unittests
R=kbr@chromium.org,bajones@chromium.org,sievers@chromium.org
Review URL: https://codereview.chromium.org/780433006
Cr-Commit-Position: refs/heads/master@{#307088}
27 files changed, 892 insertions, 245 deletions
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index f7b0c5d..454c67b 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h @@ -98,6 +98,8 @@ #define glGetVertexAttribiv GLES2_GET_FUN(GetVertexAttribiv) #define glGetVertexAttribPointerv GLES2_GET_FUN(GetVertexAttribPointerv) #define glHint GLES2_GET_FUN(Hint) +#define glInvalidateFramebuffer GLES2_GET_FUN(InvalidateFramebuffer) +#define glInvalidateSubFramebuffer GLES2_GET_FUN(InvalidateSubFramebuffer) #define glIsBuffer GLES2_GET_FUN(IsBuffer) #define glIsEnabled GLES2_GET_FUN(IsEnabled) #define glIsFramebuffer GLES2_GET_FUN(IsFramebuffer) @@ -109,6 +111,7 @@ #define glLinkProgram GLES2_GET_FUN(LinkProgram) #define glPixelStorei GLES2_GET_FUN(PixelStorei) #define glPolygonOffset GLES2_GET_FUN(PolygonOffset) +#define glReadBuffer GLES2_GET_FUN(ReadBuffer) #define glReadPixels GLES2_GET_FUN(ReadPixels) #define glReleaseShaderCompiler GLES2_GET_FUN(ReleaseShaderCompiler) #define glRenderbufferStorage GLES2_GET_FUN(RenderbufferStorage) diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 7a3db58..e6e2adb 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -2017,6 +2017,20 @@ _FUNCTION_INFO = { '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', @@ -2133,6 +2147,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' @@ -2742,8 +2759,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, @@ -3132,12 +3147,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") @@ -3149,12 +3162,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") @@ -5526,13 +5537,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") @@ -5560,18 +5571,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) @@ -5600,7 +5619,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()); } @@ -5608,9 +5627,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) @@ -5653,28 +5674,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") @@ -5701,7 +5718,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": @@ -5722,13 +5739,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") @@ -6978,6 +7002,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 @@ -7124,6 +7155,9 @@ class Function(object): """Gets the last original argument to this function.""" return self.original_args[len(self.original_args) - 1] + def GetLastOriginalPointerArg(self): + return self.last_original_pointer_arg + def __MaybePrependComma(self, arg_string, add_comma): """Adds a comma if arg_string is not empty and add_comma is true.""" comma = "" diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 727d39a..c1a1114 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -378,6 +378,21 @@ void GLES2GetVertexAttribPointerv(GLuint index, GLenum pname, void** 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); } @@ -411,6 +426,9 @@ void GLES2PixelStorei(GLenum pname, GLint 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, @@ -1415,6 +1433,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), }, @@ -1459,6 +1485,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glPolygonOffset), }, { + "glReadBuffer", + reinterpret_cast<GLES2FunctionPointer>(glReadBuffer), + }, + { "glReadPixels", reinterpret_cast<GLES2FunctionPointer>(glReadPixels), }, diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index b8e3b66..dc43a41 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -813,6 +813,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) { @@ -902,6 +932,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, diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 66cfcef..48bccd5 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -278,6 +278,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; @@ -300,6 +312,8 @@ 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, diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index d67e7ed..6220b6c 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h @@ -1032,6 +1032,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::GetStringFrameBufferTarget(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::GetStringFrameBufferTarget(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"); @@ -1157,6 +1213,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(" diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index f48e9ab..3d0eaa2 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -810,6 +810,42 @@ TEST_F(GLES2ImplementationTest, Hint) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, InvalidateFramebuffer) { + GLenum data[2][1] = {{0}}; + struct Cmds { + cmds::InvalidateFramebufferImmediate cmd; + GLenum data[2][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]); + gl_->InvalidateFramebuffer(GL_FRAMEBUFFER, 2, &data[0][0]); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, InvalidateSubFramebuffer) { + GLenum data[2][1] = {{0}}; + struct Cmds { + cmds::InvalidateSubFramebufferImmediate cmd; + GLenum data[2][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))); +} + TEST_F(GLES2ImplementationTest, IsBuffer) { struct Cmds { cmds::IsBuffer cmd; @@ -987,6 +1023,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; diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index f8c2707..5970747 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h @@ -206,6 +206,16 @@ 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; @@ -217,6 +227,7 @@ virtual void LineWidth(GLfloat width) = 0; virtual void LinkProgram(GLuint program) = 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, diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 5d8a40a..01a7e07 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -201,6 +201,16 @@ 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; @@ -212,6 +222,7 @@ void LineWidth(GLfloat width) override; void LinkProgram(GLuint program) 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, diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index b4792ca..a5797f0 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -331,6 +331,20 @@ void GLES2InterfaceStub::GetVertexAttribPointerv(GLuint /* index */, } 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; } @@ -361,6 +375,8 @@ 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 */, diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 72860f1..b88ec6a 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h @@ -201,6 +201,16 @@ 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; @@ -212,6 +222,7 @@ void LineWidth(GLfloat width) override; void LinkProgram(GLuint program) 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, diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 28e6f43..70729c3d 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h @@ -577,6 +577,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); @@ -632,6 +653,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, diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index dc613b9..03b851f 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt @@ -88,6 +88,8 @@ GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenumVer GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenumVertexAttribute pname, GLint* 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 (GLenumFrameBufferTarget target, GLsizeiNotNegative count, const GLenum* attachments); +GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenumFrameBufferTarget 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); @@ -99,6 +101,7 @@ GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); GL_APICALL void GL_APIENTRY glLinkProgram (GLidProgram program); 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 glReadBuffer (GLenum src); 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 glReleaseShaderCompiler (void); GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenumRenderBufferTarget target, GLenumRenderBufferFormat internalformat, GLsizei width, GLsizei height); diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index c451b98..923d5a1 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -3962,6 +3962,131 @@ 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); +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; +}; + +COMPILE_ASSERT(sizeof(InvalidateFramebufferImmediate) == 12, + Sizeof_InvalidateFramebufferImmediate_is_not_12); +COMPILE_ASSERT(offsetof(InvalidateFramebufferImmediate, header) == 0, + OffsetOf_InvalidateFramebufferImmediate_header_not_0); +COMPILE_ASSERT(offsetof(InvalidateFramebufferImmediate, target) == 4, + OffsetOf_InvalidateFramebufferImmediate_target_not_4); +COMPILE_ASSERT(offsetof(InvalidateFramebufferImmediate, count) == 8, + OffsetOf_InvalidateFramebufferImmediate_count_not_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; +}; + +COMPILE_ASSERT(sizeof(InvalidateSubFramebufferImmediate) == 28, + Sizeof_InvalidateSubFramebufferImmediate_is_not_28); +COMPILE_ASSERT(offsetof(InvalidateSubFramebufferImmediate, header) == 0, + OffsetOf_InvalidateSubFramebufferImmediate_header_not_0); +COMPILE_ASSERT(offsetof(InvalidateSubFramebufferImmediate, target) == 4, + OffsetOf_InvalidateSubFramebufferImmediate_target_not_4); +COMPILE_ASSERT(offsetof(InvalidateSubFramebufferImmediate, count) == 8, + OffsetOf_InvalidateSubFramebufferImmediate_count_not_8); +COMPILE_ASSERT(offsetof(InvalidateSubFramebufferImmediate, x) == 12, + OffsetOf_InvalidateSubFramebufferImmediate_x_not_12); +COMPILE_ASSERT(offsetof(InvalidateSubFramebufferImmediate, y) == 16, + OffsetOf_InvalidateSubFramebufferImmediate_y_not_16); +COMPILE_ASSERT(offsetof(InvalidateSubFramebufferImmediate, width) == 20, + OffsetOf_InvalidateSubFramebufferImmediate_width_not_20); +COMPILE_ASSERT(offsetof(InvalidateSubFramebufferImmediate, height) == 24, + OffsetOf_InvalidateSubFramebufferImmediate_height_not_24); + struct IsBuffer { typedef IsBuffer ValueType; static const CommandId kCmdId = kIsBuffer; @@ -4426,6 +4551,37 @@ COMPILE_ASSERT(offsetof(PolygonOffset, factor) == 4, COMPILE_ASSERT(offsetof(PolygonOffset, units) == 8, OffsetOf_PolygonOffset_units_not_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; +}; + +COMPILE_ASSERT(sizeof(ReadBuffer) == 8, Sizeof_ReadBuffer_is_not_8); +COMPILE_ASSERT(offsetof(ReadBuffer, header) == 0, + OffsetOf_ReadBuffer_header_not_0); +COMPILE_ASSERT(offsetof(ReadBuffer, src) == 4, OffsetOf_ReadBuffer_src_not_4); + // ReadPixels has the result separated from the pixel buffer so that // it is easier to specify the result going to some specific place // that exactly fits the rectangle of pixels. diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index acc5e77..7473650 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -1218,6 +1218,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 = @@ -1354,6 +1407,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), diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index f1bb286..94aa86c 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -98,148 +98,151 @@ OP(GetVertexAttribiv) /* 339 */ \ OP(GetVertexAttribPointerv) /* 340 */ \ OP(Hint) /* 341 */ \ - OP(IsBuffer) /* 342 */ \ - OP(IsEnabled) /* 343 */ \ - OP(IsFramebuffer) /* 344 */ \ - OP(IsProgram) /* 345 */ \ - OP(IsRenderbuffer) /* 346 */ \ - OP(IsShader) /* 347 */ \ - OP(IsTexture) /* 348 */ \ - OP(LineWidth) /* 349 */ \ - OP(LinkProgram) /* 350 */ \ - OP(PixelStorei) /* 351 */ \ - OP(PolygonOffset) /* 352 */ \ - OP(ReadPixels) /* 353 */ \ - OP(ReleaseShaderCompiler) /* 354 */ \ - OP(RenderbufferStorage) /* 355 */ \ - OP(SampleCoverage) /* 356 */ \ - OP(Scissor) /* 357 */ \ - OP(ShaderBinary) /* 358 */ \ - OP(ShaderSourceBucket) /* 359 */ \ - OP(StencilFunc) /* 360 */ \ - OP(StencilFuncSeparate) /* 361 */ \ - OP(StencilMask) /* 362 */ \ - OP(StencilMaskSeparate) /* 363 */ \ - OP(StencilOp) /* 364 */ \ - OP(StencilOpSeparate) /* 365 */ \ - OP(TexImage2D) /* 366 */ \ - OP(TexParameterf) /* 367 */ \ - OP(TexParameterfvImmediate) /* 368 */ \ - OP(TexParameteri) /* 369 */ \ - OP(TexParameterivImmediate) /* 370 */ \ - OP(TexStorage3D) /* 371 */ \ - OP(TexSubImage2D) /* 372 */ \ - OP(Uniform1f) /* 373 */ \ - OP(Uniform1fvImmediate) /* 374 */ \ - OP(Uniform1i) /* 375 */ \ - OP(Uniform1ivImmediate) /* 376 */ \ - OP(Uniform1ui) /* 377 */ \ - OP(Uniform1uivImmediate) /* 378 */ \ - OP(Uniform2f) /* 379 */ \ - OP(Uniform2fvImmediate) /* 380 */ \ - OP(Uniform2i) /* 381 */ \ - OP(Uniform2ivImmediate) /* 382 */ \ - OP(Uniform2ui) /* 383 */ \ - OP(Uniform2uivImmediate) /* 384 */ \ - OP(Uniform3f) /* 385 */ \ - OP(Uniform3fvImmediate) /* 386 */ \ - OP(Uniform3i) /* 387 */ \ - OP(Uniform3ivImmediate) /* 388 */ \ - OP(Uniform3ui) /* 389 */ \ - OP(Uniform3uivImmediate) /* 390 */ \ - OP(Uniform4f) /* 391 */ \ - OP(Uniform4fvImmediate) /* 392 */ \ - OP(Uniform4i) /* 393 */ \ - OP(Uniform4ivImmediate) /* 394 */ \ - OP(Uniform4ui) /* 395 */ \ - OP(Uniform4uivImmediate) /* 396 */ \ - OP(UniformMatrix2fvImmediate) /* 397 */ \ - OP(UniformMatrix2x3fvImmediate) /* 398 */ \ - OP(UniformMatrix2x4fvImmediate) /* 399 */ \ - OP(UniformMatrix3fvImmediate) /* 400 */ \ - OP(UniformMatrix3x2fvImmediate) /* 401 */ \ - OP(UniformMatrix3x4fvImmediate) /* 402 */ \ - OP(UniformMatrix4fvImmediate) /* 403 */ \ - OP(UniformMatrix4x2fvImmediate) /* 404 */ \ - OP(UniformMatrix4x3fvImmediate) /* 405 */ \ - OP(UseProgram) /* 406 */ \ - OP(ValidateProgram) /* 407 */ \ - OP(VertexAttrib1f) /* 408 */ \ - OP(VertexAttrib1fvImmediate) /* 409 */ \ - OP(VertexAttrib2f) /* 410 */ \ - OP(VertexAttrib2fvImmediate) /* 411 */ \ - OP(VertexAttrib3f) /* 412 */ \ - OP(VertexAttrib3fvImmediate) /* 413 */ \ - OP(VertexAttrib4f) /* 414 */ \ - OP(VertexAttrib4fvImmediate) /* 415 */ \ - OP(VertexAttribI4i) /* 416 */ \ - OP(VertexAttribI4ivImmediate) /* 417 */ \ - OP(VertexAttribI4ui) /* 418 */ \ - OP(VertexAttribI4uivImmediate) /* 419 */ \ - OP(VertexAttribIPointer) /* 420 */ \ - OP(VertexAttribPointer) /* 421 */ \ - OP(Viewport) /* 422 */ \ - OP(BlitFramebufferCHROMIUM) /* 423 */ \ - OP(RenderbufferStorageMultisampleCHROMIUM) /* 424 */ \ - OP(RenderbufferStorageMultisampleEXT) /* 425 */ \ - OP(FramebufferTexture2DMultisampleEXT) /* 426 */ \ - OP(TexStorage2DEXT) /* 427 */ \ - OP(GenQueriesEXTImmediate) /* 428 */ \ - OP(DeleteQueriesEXTImmediate) /* 429 */ \ - OP(BeginQueryEXT) /* 430 */ \ - OP(EndQueryEXT) /* 431 */ \ - OP(InsertEventMarkerEXT) /* 432 */ \ - OP(PushGroupMarkerEXT) /* 433 */ \ - OP(PopGroupMarkerEXT) /* 434 */ \ - OP(GenVertexArraysOESImmediate) /* 435 */ \ - OP(DeleteVertexArraysOESImmediate) /* 436 */ \ - OP(IsVertexArrayOES) /* 437 */ \ - OP(BindVertexArrayOES) /* 438 */ \ - OP(SwapBuffers) /* 439 */ \ - OP(GetMaxValueInBufferCHROMIUM) /* 440 */ \ - OP(EnableFeatureCHROMIUM) /* 441 */ \ - OP(ResizeCHROMIUM) /* 442 */ \ - OP(GetRequestableExtensionsCHROMIUM) /* 443 */ \ - OP(RequestExtensionCHROMIUM) /* 444 */ \ - OP(GetProgramInfoCHROMIUM) /* 445 */ \ - OP(GetTranslatedShaderSourceANGLE) /* 446 */ \ - OP(PostSubBufferCHROMIUM) /* 447 */ \ - OP(TexImageIOSurface2DCHROMIUM) /* 448 */ \ - OP(CopyTextureCHROMIUM) /* 449 */ \ - OP(DrawArraysInstancedANGLE) /* 450 */ \ - OP(DrawElementsInstancedANGLE) /* 451 */ \ - OP(VertexAttribDivisorANGLE) /* 452 */ \ - OP(GenMailboxCHROMIUM) /* 453 */ \ - OP(ProduceTextureCHROMIUMImmediate) /* 454 */ \ - OP(ProduceTextureDirectCHROMIUMImmediate) /* 455 */ \ - OP(ConsumeTextureCHROMIUMImmediate) /* 456 */ \ - OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 457 */ \ - OP(BindUniformLocationCHROMIUMBucket) /* 458 */ \ - OP(GenValuebuffersCHROMIUMImmediate) /* 459 */ \ - OP(DeleteValuebuffersCHROMIUMImmediate) /* 460 */ \ - OP(IsValuebufferCHROMIUM) /* 461 */ \ - OP(BindValuebufferCHROMIUM) /* 462 */ \ - OP(SubscribeValueCHROMIUM) /* 463 */ \ - OP(PopulateSubscribedValuesCHROMIUM) /* 464 */ \ - OP(UniformValuebufferCHROMIUM) /* 465 */ \ - OP(BindTexImage2DCHROMIUM) /* 466 */ \ - OP(ReleaseTexImage2DCHROMIUM) /* 467 */ \ - OP(TraceBeginCHROMIUM) /* 468 */ \ - OP(TraceEndCHROMIUM) /* 469 */ \ - OP(AsyncTexSubImage2DCHROMIUM) /* 470 */ \ - OP(AsyncTexImage2DCHROMIUM) /* 471 */ \ - OP(WaitAsyncTexImage2DCHROMIUM) /* 472 */ \ - OP(WaitAllAsyncTexImage2DCHROMIUM) /* 473 */ \ - OP(DiscardFramebufferEXTImmediate) /* 474 */ \ - OP(LoseContextCHROMIUM) /* 475 */ \ - OP(InsertSyncPointCHROMIUM) /* 476 */ \ - OP(WaitSyncPointCHROMIUM) /* 477 */ \ - OP(DrawBuffersEXTImmediate) /* 478 */ \ - OP(DiscardBackbufferCHROMIUM) /* 479 */ \ - OP(ScheduleOverlayPlaneCHROMIUM) /* 480 */ \ - OP(MatrixLoadfCHROMIUMImmediate) /* 481 */ \ - OP(MatrixLoadIdentityCHROMIUM) /* 482 */ \ - OP(BlendBarrierKHR) /* 483 */ + OP(InvalidateFramebufferImmediate) /* 342 */ \ + OP(InvalidateSubFramebufferImmediate) /* 343 */ \ + OP(IsBuffer) /* 344 */ \ + OP(IsEnabled) /* 345 */ \ + OP(IsFramebuffer) /* 346 */ \ + OP(IsProgram) /* 347 */ \ + OP(IsRenderbuffer) /* 348 */ \ + OP(IsShader) /* 349 */ \ + OP(IsTexture) /* 350 */ \ + OP(LineWidth) /* 351 */ \ + OP(LinkProgram) /* 352 */ \ + OP(PixelStorei) /* 353 */ \ + OP(PolygonOffset) /* 354 */ \ + OP(ReadBuffer) /* 355 */ \ + OP(ReadPixels) /* 356 */ \ + OP(ReleaseShaderCompiler) /* 357 */ \ + OP(RenderbufferStorage) /* 358 */ \ + OP(SampleCoverage) /* 359 */ \ + OP(Scissor) /* 360 */ \ + OP(ShaderBinary) /* 361 */ \ + OP(ShaderSourceBucket) /* 362 */ \ + OP(StencilFunc) /* 363 */ \ + OP(StencilFuncSeparate) /* 364 */ \ + OP(StencilMask) /* 365 */ \ + OP(StencilMaskSeparate) /* 366 */ \ + OP(StencilOp) /* 367 */ \ + OP(StencilOpSeparate) /* 368 */ \ + OP(TexImage2D) /* 369 */ \ + OP(TexParameterf) /* 370 */ \ + OP(TexParameterfvImmediate) /* 371 */ \ + OP(TexParameteri) /* 372 */ \ + OP(TexParameterivImmediate) /* 373 */ \ + OP(TexStorage3D) /* 374 */ \ + OP(TexSubImage2D) /* 375 */ \ + OP(Uniform1f) /* 376 */ \ + OP(Uniform1fvImmediate) /* 377 */ \ + OP(Uniform1i) /* 378 */ \ + OP(Uniform1ivImmediate) /* 379 */ \ + OP(Uniform1ui) /* 380 */ \ + OP(Uniform1uivImmediate) /* 381 */ \ + OP(Uniform2f) /* 382 */ \ + OP(Uniform2fvImmediate) /* 383 */ \ + OP(Uniform2i) /* 384 */ \ + OP(Uniform2ivImmediate) /* 385 */ \ + OP(Uniform2ui) /* 386 */ \ + OP(Uniform2uivImmediate) /* 387 */ \ + OP(Uniform3f) /* 388 */ \ + OP(Uniform3fvImmediate) /* 389 */ \ + OP(Uniform3i) /* 390 */ \ + OP(Uniform3ivImmediate) /* 391 */ \ + OP(Uniform3ui) /* 392 */ \ + OP(Uniform3uivImmediate) /* 393 */ \ + OP(Uniform4f) /* 394 */ \ + OP(Uniform4fvImmediate) /* 395 */ \ + OP(Uniform4i) /* 396 */ \ + OP(Uniform4ivImmediate) /* 397 */ \ + OP(Uniform4ui) /* 398 */ \ + OP(Uniform4uivImmediate) /* 399 */ \ + OP(UniformMatrix2fvImmediate) /* 400 */ \ + OP(UniformMatrix2x3fvImmediate) /* 401 */ \ + OP(UniformMatrix2x4fvImmediate) /* 402 */ \ + OP(UniformMatrix3fvImmediate) /* 403 */ \ + OP(UniformMatrix3x2fvImmediate) /* 404 */ \ + OP(UniformMatrix3x4fvImmediate) /* 405 */ \ + OP(UniformMatrix4fvImmediate) /* 406 */ \ + OP(UniformMatrix4x2fvImmediate) /* 407 */ \ + OP(UniformMatrix4x3fvImmediate) /* 408 */ \ + OP(UseProgram) /* 409 */ \ + OP(ValidateProgram) /* 410 */ \ + OP(VertexAttrib1f) /* 411 */ \ + OP(VertexAttrib1fvImmediate) /* 412 */ \ + OP(VertexAttrib2f) /* 413 */ \ + OP(VertexAttrib2fvImmediate) /* 414 */ \ + OP(VertexAttrib3f) /* 415 */ \ + OP(VertexAttrib3fvImmediate) /* 416 */ \ + OP(VertexAttrib4f) /* 417 */ \ + OP(VertexAttrib4fvImmediate) /* 418 */ \ + OP(VertexAttribI4i) /* 419 */ \ + OP(VertexAttribI4ivImmediate) /* 420 */ \ + OP(VertexAttribI4ui) /* 421 */ \ + OP(VertexAttribI4uivImmediate) /* 422 */ \ + OP(VertexAttribIPointer) /* 423 */ \ + OP(VertexAttribPointer) /* 424 */ \ + OP(Viewport) /* 425 */ \ + OP(BlitFramebufferCHROMIUM) /* 426 */ \ + OP(RenderbufferStorageMultisampleCHROMIUM) /* 427 */ \ + OP(RenderbufferStorageMultisampleEXT) /* 428 */ \ + OP(FramebufferTexture2DMultisampleEXT) /* 429 */ \ + OP(TexStorage2DEXT) /* 430 */ \ + OP(GenQueriesEXTImmediate) /* 431 */ \ + OP(DeleteQueriesEXTImmediate) /* 432 */ \ + OP(BeginQueryEXT) /* 433 */ \ + OP(EndQueryEXT) /* 434 */ \ + OP(InsertEventMarkerEXT) /* 435 */ \ + OP(PushGroupMarkerEXT) /* 436 */ \ + OP(PopGroupMarkerEXT) /* 437 */ \ + OP(GenVertexArraysOESImmediate) /* 438 */ \ + OP(DeleteVertexArraysOESImmediate) /* 439 */ \ + OP(IsVertexArrayOES) /* 440 */ \ + OP(BindVertexArrayOES) /* 441 */ \ + OP(SwapBuffers) /* 442 */ \ + OP(GetMaxValueInBufferCHROMIUM) /* 443 */ \ + OP(EnableFeatureCHROMIUM) /* 444 */ \ + OP(ResizeCHROMIUM) /* 445 */ \ + OP(GetRequestableExtensionsCHROMIUM) /* 446 */ \ + OP(RequestExtensionCHROMIUM) /* 447 */ \ + OP(GetProgramInfoCHROMIUM) /* 448 */ \ + OP(GetTranslatedShaderSourceANGLE) /* 449 */ \ + OP(PostSubBufferCHROMIUM) /* 450 */ \ + OP(TexImageIOSurface2DCHROMIUM) /* 451 */ \ + OP(CopyTextureCHROMIUM) /* 452 */ \ + OP(DrawArraysInstancedANGLE) /* 453 */ \ + OP(DrawElementsInstancedANGLE) /* 454 */ \ + OP(VertexAttribDivisorANGLE) /* 455 */ \ + OP(GenMailboxCHROMIUM) /* 456 */ \ + OP(ProduceTextureCHROMIUMImmediate) /* 457 */ \ + OP(ProduceTextureDirectCHROMIUMImmediate) /* 458 */ \ + OP(ConsumeTextureCHROMIUMImmediate) /* 459 */ \ + OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 460 */ \ + OP(BindUniformLocationCHROMIUMBucket) /* 461 */ \ + OP(GenValuebuffersCHROMIUMImmediate) /* 462 */ \ + OP(DeleteValuebuffersCHROMIUMImmediate) /* 463 */ \ + OP(IsValuebufferCHROMIUM) /* 464 */ \ + OP(BindValuebufferCHROMIUM) /* 465 */ \ + OP(SubscribeValueCHROMIUM) /* 466 */ \ + OP(PopulateSubscribedValuesCHROMIUM) /* 467 */ \ + OP(UniformValuebufferCHROMIUM) /* 468 */ \ + OP(BindTexImage2DCHROMIUM) /* 469 */ \ + OP(ReleaseTexImage2DCHROMIUM) /* 470 */ \ + OP(TraceBeginCHROMIUM) /* 471 */ \ + OP(TraceEndCHROMIUM) /* 472 */ \ + OP(AsyncTexSubImage2DCHROMIUM) /* 473 */ \ + OP(AsyncTexImage2DCHROMIUM) /* 474 */ \ + OP(WaitAsyncTexImage2DCHROMIUM) /* 475 */ \ + OP(WaitAllAsyncTexImage2DCHROMIUM) /* 476 */ \ + OP(DiscardFramebufferEXTImmediate) /* 477 */ \ + OP(LoseContextCHROMIUM) /* 478 */ \ + OP(InsertSyncPointCHROMIUM) /* 479 */ \ + OP(WaitSyncPointCHROMIUM) /* 480 */ \ + OP(DrawBuffersEXTImmediate) /* 481 */ \ + OP(DiscardBackbufferCHROMIUM) /* 482 */ \ + OP(ScheduleOverlayPlaneCHROMIUM) /* 483 */ \ + OP(MatrixLoadfCHROMIUMImmediate) /* 484 */ \ + OP(MatrixLoadIdentityCHROMIUM) /* 485 */ \ + OP(BlendBarrierKHR) /* 486 */ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 9fec2e1..a15c791 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -139,7 +139,6 @@ 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), @@ -271,17 +270,10 @@ void FeatureInfo::InitializeFeatures() { 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)); AddExtensionString("GL_ANGLE_translated_shader_source"); AddExtensionString("GL_CHROMIUM_async_pixel_transfers"); @@ -386,7 +378,8 @@ 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)) { enable_depth_texture = true; feature_flags_.angle_depth_texture = extensions.Contains("GL_ANGLE_depth_texture"); @@ -404,7 +397,8 @@ 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) { AddExtensionString("GL_OES_packed_depth_stencil"); feature_flags_.packed_depth24_stencil8 = true; if (enable_depth_texture) { @@ -417,7 +411,8 @@ 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 || + 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; @@ -430,7 +425,8 @@ 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); @@ -442,7 +438,8 @@ void FeatureInfo::InitializeFeatures() { // 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 (((is_es3 || extensions.Contains("GL_OES_rgb8_rgba8")) && + 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); @@ -503,7 +500,8 @@ 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 || + 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; @@ -535,8 +533,9 @@ void FeatureInfo::InitializeFeatures() { // 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 ((is_es3 && extensions.Contains("GL_EXT_color_buffer_float")) || - feature_flags_.is_angle) { + 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; } } @@ -638,12 +637,13 @@ void FeatureInfo::InitializeFeatures() { // Check for multisample support if (!workarounds_.disable_multisampling) { 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; + 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; if (ext_has_multisample) { feature_flags_.chromium_framebuffer_multisample = true; validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT); @@ -670,14 +670,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; @@ -771,8 +772,10 @@ 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) { @@ -825,7 +828,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); @@ -836,7 +839,8 @@ 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))) { AddExtensionString("GL_EXT_draw_buffers"); feature_flags_.ext_draw_buffers = true; @@ -871,7 +875,8 @@ 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); @@ -906,13 +911,15 @@ 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 || + 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 || + extensions.Contains("GL_ARB_pixel_buffer_object") || extensions.Contains("GL_NV_pixel_buffer_object"); // We will use either glMapBuffer() or glMapBufferRange() for async readbacks. @@ -921,13 +928,15 @@ 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")) && + if ((gl_version_info_->is_es3 || + extensions.Contains("GL_EXT_discard_framebuffer")) && !workarounds_.disable_ext_discard_framebuffer) { // DiscardFramebufferEXT is automatically bound to InvalidateFramebuffer. AddExtensionString("GL_EXT_discard_framebuffer"); @@ -974,7 +983,8 @@ void FeatureInfo::InitializeFeatures() { } 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); @@ -982,7 +992,7 @@ void FeatureInfo::InitializeFeatures() { } } - if ((is_es3 || extensions.Contains("GL_EXT_texture_rg") || + if ((gl_version_info_->is_es3 || extensions.Contains("GL_EXT_texture_rg") || extensions.Contains("GL_ARB_texture_rg")) && IsGL_REDSupportedOnFBOs()) { feature_flags_.ext_texture_rg = true; diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index 816ab49..c4bf479 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/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; @@ -66,7 +67,6 @@ 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; @@ -122,6 +122,11 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { return workarounds_; } + const gfx::GLVersionInfo& gl_version_info() const { + CHECK(gl_version_info_.get()); + return *(gl_version_info_.get()); + } + private: friend class base::RefCounted<FeatureInfo>; friend class BufferManagerClientSideArraysTest; @@ -148,6 +153,8 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { // Flags for Workarounds. Workarounds workarounds_; + scoped_ptr<gfx::GLVersionInfo> gl_version_info_; + DISALLOW_COPY_AND_ASSIGN(FeatureInfo); }; diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index b314262..06f3d11 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc @@ -127,7 +127,6 @@ 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) @@ -345,7 +344,7 @@ TEST_F(FeatureInfoTest, InitializeNoExtensions) { TEST_F(FeatureInfoTest, InitializeWithANGLE) { SetupInitExpectationsWithGLVersion("", kGLRendererStringANGLE, ""); - EXPECT_TRUE(info_->feature_flags().is_angle); + EXPECT_TRUE(info_->gl_version_info().is_angle); } TEST_F(FeatureInfoTest, InitializeNPOTExtensionGLES) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 422168c..919d8d8 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -4494,7 +4494,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) { @@ -5495,7 +5501,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) { @@ -5519,7 +5525,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) { @@ -7865,8 +7871,8 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size, glGenBuffersARB(1, &buffer); glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); // For ANGLE client version 2, GL_STREAM_READ is not available. - const GLenum usage_hint = - features().is_angle ? GL_STATIC_DRAW : GL_STREAM_READ; + 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) { @@ -9703,7 +9709,7 @@ 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 { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index ebdb625..b84fc2a 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -1493,6 +1493,74 @@ 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; + } + if (width < 0) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glInvalidateSubFramebuffer", + "width < 0"); + return error::kNoError; + } + if (height < 0) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glInvalidateSubFramebuffer", + "height < 0"); + return error::kNoError; + } + 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 = @@ -1653,6 +1721,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) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h index f9b450e..014007a 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h @@ -1698,6 +1698,8 @@ TEST_P(GLES2DecoderTest1, HintInvalidArgs0_0) { EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } +// TODO(gman): InvalidateFramebufferImmediate +// TODO(gman): InvalidateSubFramebufferImmediate TEST_P(GLES2DecoderTest1, IsBufferValidArgs) { SpecializedSetup<cmds::IsBuffer, 0>(true); @@ -1875,14 +1877,4 @@ TEST_P(GLES2DecoderTest1, LinkProgramValidArgs) { } // 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 - #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h index b69197f..602be42 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h @@ -12,6 +12,28 @@ #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, 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) { @@ -1015,7 +1037,4 @@ TEST_P(GLES2DecoderTest2, PopGroupMarkerEXTValidArgs) { // TODO(gman): GetTranslatedShaderSourceANGLE // TODO(gman): PostSubBufferCHROMIUM // TODO(gman): TexImageIOSurface2DCHROMIUM -// TODO(gman): CopyTextureCHROMIUM -// TODO(gman): DrawArraysInstancedANGLE -// TODO(gman): DrawElementsInstancedANGLE #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h index 0ee2ba5..4509676 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h @@ -12,6 +12,9 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ +// TODO(gman): CopyTextureCHROMIUM +// TODO(gman): DrawArraysInstancedANGLE +// TODO(gman): DrawElementsInstancedANGLE // TODO(gman): VertexAttribDivisorANGLE // TODO(gman): GenMailboxCHROMIUM diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc index 78fa020..d230be78f 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc @@ -2120,7 +2120,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") != diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index 6fff4cb..14e3052 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py @@ -326,12 +326,8 @@ GL_FUNCTIONS = [ 'names': ['glDisableVertexAttribArray'], 'arguments': 'GLuint index', }, { 'return_type': 'void', - 'known_as': 'glDiscardFramebufferEXT', - 'versions': [{ 'name': 'glInvalidateFramebuffer', - 'gl_versions': ['es3'], - 'extensions': [] }, - { 'name': 'glDiscardFramebufferEXT', - 'gl_versions': ['es1', 'es2'] }], + 'versions': [{ 'name': 'glDiscardFramebufferEXT', + 'extensions': ['GL_EXT_discard_framebuffer'] }], 'arguments': 'GLenum target, GLsizei numAttachments, ' 'const GLenum* attachments' }, { 'return_type': 'void', @@ -698,6 +694,11 @@ GL_FUNCTIONS = [ 'names': ['glInsertEventMarkerEXT'], 'arguments': 'GLsizei length, const char* marker', }, { 'return_type': 'void', + 'versions': [{ 'name': 'glInvalidateFramebuffer', + 'gl_versions': ['gl4', 'es3'] }], # GL 4.3 or higher. + 'arguments': 'GLenum target, GLsizei numAttachments, ' + 'const GLenum* attachments' }, +{ 'return_type': 'void', 'versions': [{ 'name': 'glInvalidateSubFramebuffer', 'gl_versions': ['gl4', 'es3'] }], # GL 4.3 or higher. 'arguments': diff --git a/ui/gl/gl_version_info.h b/ui/gl/gl_version_info.h index 13b323f..21ca07a 100644 --- a/ui/gl/gl_version_info.h +++ b/ui/gl/gl_version_info.h @@ -7,10 +7,11 @@ #include <string> #include "base/basictypes.h" +#include "ui/gl/gl_export.h" namespace gfx { -struct GLVersionInfo { +struct GL_EXPORT GLVersionInfo { GLVersionInfo(const char* version_str, const char* renderer_str); // New flags, such as is_gl4_4 could be introduced as needed. @@ -27,7 +28,7 @@ struct GLVersionInfo { bool is_angle; -private: + private: DISALLOW_COPY_AND_ASSIGN(GLVersionInfo); }; |