diff options
Diffstat (limited to 'gpu')
18 files changed, 1504 insertions, 1009 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 1441fa3..59f1ba2 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -67,7 +67,7 @@ _CAPABILITY_FLAGS = [ {'name': 'polygon_offset_fill'}, {'name': 'sample_alpha_to_coverage'}, {'name': 'sample_coverage'}, - {'name': 'scissor_test'}, + {'name': 'scissor_test', 'state_flag': 'clear_state_dirty_'}, {'name': 'stencil_test', 'state_flag': 'clear_state_dirty_'}, ] @@ -1211,6 +1211,9 @@ _FUNCTION_INFO = { 'state': 'ClearDepthf', 'decoder_func': 'glClearDepth', 'gl_test_func': 'glClearDepth', + 'valid_args': { + '0': '0.5f' + }, }, 'ColorMask': { 'type': 'StateSet', @@ -1275,10 +1278,16 @@ _FUNCTION_INFO = { 'BlendEquation': { 'type': 'StateSetRGBAlpha', 'state': 'BlendEquation', + 'valid_args': { + '0': 'GL_FUNC_SUBTRACT' + }, }, 'BlendEquationSeparate': { 'type': 'StateSet', 'state': 'BlendEquation', + 'valid_args': { + '0': 'GL_FUNC_SUBTRACT' + }, }, 'BlendFunc': { 'type': 'StateSetRGBAlpha', @@ -1290,26 +1299,38 @@ _FUNCTION_INFO = { }, 'SampleCoverage': {'decoder_func': 'DoSampleCoverage'}, 'StencilFunc': { - 'type': 'StencilFrontBack', + 'type': 'StateSetFrontBack', 'state': 'StencilFunc', }, 'StencilFuncSeparate': { - 'type': 'StencilFrontBack', + 'type': 'StateSetFrontBackSeparate', 'state': 'StencilFunc', }, 'StencilOp': { 'type': 'StateSetFrontBack', 'state': 'StencilOp', + 'valid_args': { + '1': 'GL_INCR' + }, }, 'StencilOpSeparate': { 'type': 'StateSetFrontBackSeparate', 'state': 'StencilOp', + 'valid_args': { + '1': 'GL_INCR' + }, }, 'Hint': {'decoder_func': 'DoHint'}, 'CullFace': {'type': 'StateSet', 'state': 'CullFace'}, 'FrontFace': {'type': 'StateSet', 'state': 'FrontFace'}, 'DepthFunc': {'type': 'StateSet', 'state': 'DepthFunc'}, - 'LineWidth': {'type': 'StateSet', 'state': 'LineWidth'}, + 'LineWidth': { + 'type': 'StateSet', + 'state': 'LineWidth', + 'valid_args': { + '0': '0.5f' + }, + }, 'PolygonOffset': { 'type': 'StateSet', 'state': 'PolygonOffset', @@ -1362,6 +1383,7 @@ _FUNCTION_INFO = { 'Disable': { 'decoder_func': 'DoDisable', 'impl_func': False, + 'client_test': False, }, 'DisableVertexAttribArray': { 'decoder_func': 'DoDisableVertexAttribArray', @@ -1380,6 +1402,7 @@ _FUNCTION_INFO = { 'Enable': { 'decoder_func': 'DoEnable', 'impl_func': False, + 'client_test': False, }, 'EnableVertexAttribArray': { 'decoder_func': 'DoEnableVertexAttribArray', @@ -1936,7 +1959,11 @@ _FUNCTION_INFO = { 'client_test': False, 'pepper_interface': 'ChromiumMapSub', }, - 'UseProgram': {'decoder_func': 'DoUseProgram', 'unit_test': False}, + 'UseProgram': { + 'decoder_func': 'DoUseProgram', + 'impl_func': False, + 'unit_test': False, + }, 'ValidateProgram': {'decoder_func': 'DoValidateProgram'}, 'VertexAttrib1f': {'decoder_func': 'DoVertexAttrib1f'}, 'VertexAttrib1fv': { @@ -2850,13 +2877,18 @@ class StateSetHandler(TypeHandler): state = _STATES[state_name] states = state['states'] args = func.GetOriginalArgs() + code = [] + for ndx,item in enumerate(states): + code.append("state_.%s != %s" % (item['name'], args[ndx].name)) + file.Write(" if (%s) {\n" % " ||\n ".join(code)) for ndx,item in enumerate(states): - file.Write(" state_.%s = %s;\n" % (item['name'], args[ndx].name)) + file.Write(" state_.%s = %s;\n" % (item['name'], args[ndx].name)) if 'state_flag' in state: - file.Write(" %s = true;\n" % state['state_flag']) + file.Write(" %s = true;\n" % state['state_flag']) if not func.GetInfo("no_gl"): - file.Write(" %s(%s);\n" % + file.Write(" %s(%s);\n" % (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) + file.Write(" }\n") class StateSetRGBAlphaHandler(TypeHandler): @@ -2872,14 +2904,19 @@ class StateSetRGBAlphaHandler(TypeHandler): states = state['states'] args = func.GetOriginalArgs() num_args = len(args) - for ndx, item in enumerate(states): - file.Write(" state_.%s = %s;\n" % + code = [] + for ndx,item in enumerate(states): + code.append("state_.%s != %s" % (item['name'], args[ndx % num_args].name)) + file.Write(" if (%s) {\n" % " ||\n ".join(code)) + for ndx,item in enumerate(states): + file.Write(" state_.%s = %s;\n" % (item['name'], args[ndx % num_args].name)) if 'state_flag' in state: - file.Write(" %s = true;\n" % state['state_flag']) + file.Write(" %s = true;\n" % state['state_flag']) if not func.GetInfo("no_gl"): - file.Write(" %s(%s);\n" % + file.Write(" %s(%s);\n" % (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) + file.Write(" }\n") class StateSetFrontBackSeparateHandler(TypeHandler): @@ -2896,17 +2933,29 @@ class StateSetFrontBackSeparateHandler(TypeHandler): args = func.GetOriginalArgs() face = args[0].name num_args = len(args) + file.Write(" bool changed = false;\n") for group_ndx, group in enumerate(Grouper(num_args - 1, states)): file.Write(" if (%s == %s || %s == GL_FRONT_AND_BACK) {\n" % (face, ('GL_FRONT', 'GL_BACK')[group_ndx], face)) + code = [] for ndx, item in enumerate(group): - file.Write(" state_.%s = %s;\n" % (item['name'], args[ndx + 1].name)) + code.append("state_.%s != %s" % (item['name'], args[ndx + 1].name)) + file.Write(" changed |= %s;\n" % " ||\n ".join(code)) file.Write(" }\n") + file.Write(" if (changed) {\n") + for group_ndx, group in enumerate(Grouper(num_args - 1, states)): + file.Write(" if (%s == %s || %s == GL_FRONT_AND_BACK) {\n" % + (face, ('GL_FRONT', 'GL_BACK')[group_ndx], face)) + for ndx, item in enumerate(group): + file.Write(" state_.%s = %s;\n" % + (item['name'], args[ndx + 1].name)) + file.Write(" }\n") if 'state_flag' in state: - file.Write(" %s = true;\n" % state['state_flag']) + file.Write(" %s = true;\n" % state['state_flag']) if not func.GetInfo("no_gl"): - file.Write(" %s(%s);\n" % + file.Write(" %s(%s);\n" % (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) + file.Write(" }\n") class StateSetFrontBackHandler(TypeHandler): @@ -2921,16 +2970,22 @@ class StateSetFrontBackHandler(TypeHandler): state = _STATES[state_name] states = state['states'] args = func.GetOriginalArgs() - face = args[0].name num_args = len(args) + code = [] for group_ndx, group in enumerate(Grouper(num_args, states)): for ndx, item in enumerate(group): - file.Write(" state_.%s = %s;\n" % (item['name'], args[ndx].name)) + code.append("state_.%s != %s" % (item['name'], args[ndx].name)) + file.Write(" if (%s) {\n" % " ||\n ".join(code)) + for group_ndx, group in enumerate(Grouper(num_args, states)): + for ndx, item in enumerate(group): + file.Write(" state_.%s = %s;\n" % (item['name'], args[ndx].name)) if 'state_flag' in state: - file.Write(" %s = true;\n" % state['state_flag']) + file.Write(" %s = true;\n" % state['state_flag']) if not func.GetInfo("no_gl"): - file.Write(" %s(%s);\n" % + file.Write(" %s(%s);\n" % (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) + file.Write(" }\n") + class CustomHandler(TypeHandler): """Handler for commands that are auto-generated but require minor tweaks.""" @@ -3376,8 +3431,9 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { SetGLError(GL_INVALID_OPERATION, "%(name)s\", \"%(id)s reserved id"); return; } - Bind%(type)sHelper(%(arg_string)s); - helper_->%(name)s(%(arg_string)s); + if (Bind%(type)sHelper(%(arg_string)s)) { + helper_->%(name)s(%(arg_string)s); + } } """ @@ -3397,6 +3453,36 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { 'lc_type': name_arg.resource_type.lower(), }) + def WriteGLES2ImplementationUnitTest(self, func, file): + """Overrriden from TypeHandler.""" + code = """ +TEST_F(GLES2ImplementationTest, %(name)s) { + struct Cmds { + %(name)s cmd; + }; + Cmds expected; + expected.cmd.Init(%(cmd_args)s); + + gl_->%(name)s(%(args)s); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + ClearCommands(); + gl_->%(name)s(%(args)s); + EXPECT_TRUE(NoCommandsWritten()); +} +""" + cmd_arg_strings = [] + for count, arg in enumerate(func.GetCmdArgs()): + cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func, count, 0)) + count += 1 + gl_arg_strings = [] + for count, arg in enumerate(func.GetOriginalArgs()): + gl_arg_strings.append(arg.GetValidClientSideArg(func, count, 0)) + file.Write(code % { + 'name': func.name, + 'args': ", ".join(gl_arg_strings), + 'cmd_args': ", ".join(cmd_arg_strings), + }) + class GENnHandler(TypeHandler): """Handler for glGen___ type functions.""" @@ -6313,8 +6399,11 @@ class GLGenerator(object): def GetTypeHandler(self, name): """Gets a type info for the given type.""" - if name in self._type_handlers: - return self._type_handlers[name] + if len(name): + if name in self._type_handlers: + return self._type_handlers[name] + else: + raise KeyError("no such type handler: %s" % name) return self._empty_type_handler def GetFunctionInfo(self, name): @@ -6488,8 +6577,8 @@ class GLGenerator(object): file.Close() - def WriteContextStateHeader(self, filename): - """Writes the context state header.""" + def WriteServiceContextStateHeader(self, filename): + """Writes the service context state header.""" file = CHeaderWriter( filename, "// It is included by context_state.h\n") @@ -6507,8 +6596,64 @@ class GLGenerator(object): file.Close() - def WriteContextStateImpl(self, filename): - """Writes the context state implementation.""" + def WriteClientContextStateHeader(self, filename): + """Writes the client context state header.""" + file = CHeaderWriter( + filename, + "// It is included by client_context_state.h\n") + file.Write("struct EnableFlags {\n") + file.Write(" EnableFlags();\n") + for capability in _CAPABILITY_FLAGS: + file.Write(" bool %s;\n" % capability['name']) + file.Write("};\n\n") + + file.Close() + + def WriteContextStateGetters(self, file, class_name): + """Writes the state getters.""" + for gl_type in ["GLint", "GLfloat"]: + file.Write(""" +bool %s::GetStateAs%s( + GLenum pname, %s* params, GLsizei* num_written) const { + switch (pname) { +""" % (class_name, gl_type, gl_type)) + for state_name in _STATES.keys(): + state = _STATES[state_name] + if 'enum' in state: + file.Write(" case %s:\n" % state['enum']) + file.Write(" *num_written = %d;\n" % len(state['states'])) + file.Write(" if (params) {\n") + for ndx,item in enumerate(state['states']): + file.Write(" params[%d] = static_cast<%s>(%s);\n" % + (ndx, gl_type, item['name'])) + file.Write(" }\n") + file.Write(" return true;\n") + else: + for item in state['states']: + file.Write(" case %s:\n" % item['enum']) + file.Write(" *num_written = 1;\n") + file.Write(" if (params) {\n") + file.Write(" params[0] = static_cast<%s>(%s);\n" % + (gl_type, item['name'])) + file.Write(" }\n") + file.Write(" return true;\n") + for capability in _CAPABILITY_FLAGS: + file.Write(" case GL_%s:\n" % capability['name'].upper()) + file.Write(" *num_written = 1;\n") + file.Write(" if (params) {\n") + file.Write( + " params[0] = static_cast<%s>(enable_flags.%s);\n" % + (gl_type, capability['name'])) + file.Write(" }\n") + file.Write(" return true;\n") + file.Write(""" default: + return false; + } +} +""") + + def WriteServiceContextStateImpl(self, filename): + """Writes the context state service implementation.""" file = CHeaderWriter( filename, "// It is included by context_state.cc\n") @@ -6558,6 +6703,69 @@ void ContextState::InitState() const { file.Write(" gl%s(%s);\n" % (state['func'], ", ".join(args))) file.Write("}\n") + file.Write("""bool ContextState::GetEnabled(GLenum cap) const { + switch (cap) { +""") + for capability in _CAPABILITY_FLAGS: + file.Write(" case GL_%s:\n" % capability['name'].upper()) + file.Write(" return enable_flags.%s;\n" % capability['name']) + file.Write(""" default: + GPU_NOTREACHED(); + return false; + } +} +""") + + self.WriteContextStateGetters(file, "ContextState") + file.Close() + + def WriteClientContextStateImpl(self, filename): + """Writes the context state client side implementation.""" + file = CHeaderWriter( + filename, + "// It is included by client_context_state.cc\n") + code = [] + for capability in _CAPABILITY_FLAGS: + code.append("%s(%s)" % + (capability['name'], + ('false', 'true')['default' in capability])) + file.Write( + "ClientContextState::EnableFlags::EnableFlags()\n : %s {\n}\n" % + ",\n ".join(code)) + file.Write("\n") + + file.Write(""" +bool ClientContextState::SetCapabilityState( + GLenum cap, bool enabled, bool* changed) { + *changed = false; + switch (cap) { +""") + for capability in _CAPABILITY_FLAGS: + file.Write(" case GL_%s:\n" % capability['name'].upper()) + file.Write(""" if (enable_flags.%(name)s != enabled) { + *changed = true; + enable_flags.%(name)s = enabled; + } + return true; +""" % capability) + file.Write(""" default: + return false; + } +} +""") + file.Write("""bool ClientContextState::GetEnabled( + GLenum cap, bool* enabled) const { + switch (cap) { +""") + for capability in _CAPABILITY_FLAGS: + file.Write(" case GL_%s:\n" % capability['name'].upper()) + file.Write(" *enabled = enable_flags.%s;\n" % capability['name']) + file.Write(" return true;\n") + file.Write(""" default: + return false; + } +} +""") file.Close() def WriteServiceImplementation(self, filename): @@ -6594,59 +6802,6 @@ bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) { return false; } } - -bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) { - switch (cap) { -""") - for capability in _CAPABILITY_FLAGS: - file.Write(" case GL_%s:\n" % capability['name'].upper()) - file.Write(" return state_.enable_flags.%s;\n" % - capability['name']) - file.Write(""" default: - NOTREACHED(); - return false; - } -} -""") - for gl_type in ["GLint", "GLfloat"]: - file.Write(""" -bool GLES2DecoderImpl::GetStateAs%s( - GLenum pname, %s* params, GLsizei* num_written) { - switch (pname) { -""" % (gl_type, gl_type)) - for state_name in _STATES.keys(): - state = _STATES[state_name] - if 'enum' in state: - file.Write(" case %s:\n" % state['enum']) - file.Write(" *num_written = %d;\n" % len(state['states'])) - file.Write(" if (params) {\n") - for ndx,item in enumerate(state['states']): - file.Write(" params[%d] = static_cast<%s>(state_.%s);\n" % - (ndx, gl_type, item['name'])) - file.Write(" }\n") - file.Write(" return true;\n") - else: - for item in state['states']: - file.Write(" case %s:\n" % item['enum']) - file.Write(" *num_written = 1;\n") - file.Write(" if (params) {\n") - file.Write(" params[0] = static_cast<%s>(state_.%s);\n" % - (gl_type, item['name'])) - file.Write(" }\n") - file.Write(" return true;\n") - for capability in _CAPABILITY_FLAGS: - file.Write(" case GL_%s:\n" % capability['name'].upper()) - file.Write(" *num_written = 1;\n") - file.Write(" if (params) {\n") - file.Write(" params[0] = static_cast<%s>(" - "state_.enable_flags.%s);\n" % - (gl_type, capability['name'])) - file.Write(" }\n") - file.Write(" return true;\n") - file.Write(""" default: - return false; - } -} """) file.Close() @@ -7178,8 +7333,11 @@ def main(argv): gen.WriteGLES2CLibImplementation("client/gles2_c_lib_autogen.h") gen.WriteCmdHelperHeader("client/gles2_cmd_helper_autogen.h") gen.WriteServiceImplementation("service/gles2_cmd_decoder_autogen.h") - gen.WriteContextStateHeader("service/context_state_autogen.h") - gen.WriteContextStateImpl("service/context_state_impl_autogen.h") + gen.WriteServiceContextStateHeader("service/context_state_autogen.h") + gen.WriteServiceContextStateImpl("service/context_state_impl_autogen.h") + gen.WriteClientContextStateHeader("client/client_context_state_autogen.h") + gen.WriteClientContextStateImpl( + "client/client_context_state_impl_autogen.h") gen.WriteServiceUnitTests("service/gles2_cmd_decoder_unittest_%d_autogen.h") gen.WriteServiceUtilsHeader("service/gles2_cmd_validation_autogen.h") gen.WriteServiceUtilsImplementation( diff --git a/gpu/command_buffer/client/client_context_state.cc b/gpu/command_buffer/client/client_context_state.cc new file mode 100644 index 0000000..84a262e --- /dev/null +++ b/gpu/command_buffer/client/client_context_state.cc @@ -0,0 +1,25 @@ +// 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 "../client/client_context_state.h" +#include "../common/logging.h" + +namespace gpu { +namespace gles2 { + +ClientContextState::ClientContextState() { +} + +ClientContextState::~ClientContextState() { +} + +// 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. +#include "gpu/command_buffer/client/client_context_state_impl_autogen.h" + +} // namespace gles2 +} // namespace gpu + + diff --git a/gpu/command_buffer/client/client_context_state.h b/gpu/command_buffer/client/client_context_state.h new file mode 100644 index 0000000..f5a93a6 --- /dev/null +++ b/gpu/command_buffer/client/client_context_state.h @@ -0,0 +1,39 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file contains the ContextState class. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_H_ + +#include <GLES2/gl2.h> +#include <vector> +#include "gles2_impl_export.h" + +namespace gpu { +namespace gles2 { + +struct GLES2_IMPL_EXPORT ClientContextState { + ClientContextState(); + ~ClientContextState(); + + // Returns true if state was cached in which case 'enabled' will be set to the + // current state. + bool GetEnabled(GLenum cap, bool* enabled) const; + + // Sets the state of a capability. + // Returns true if the capability is one that is cached. + // 'changed' will be true if the state was different from 'enabled. + bool SetCapabilityState(GLenum cap, bool enabled, bool* changed); + + #include "gpu/command_buffer/client/client_context_state_autogen.h" + + EnableFlags enable_flags; +}; + +} // namespace gles2 +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_H_ + diff --git a/gpu/command_buffer/client/client_context_state_autogen.h b/gpu/command_buffer/client/client_context_state_autogen.h new file mode 100644 index 0000000..1714b2b --- /dev/null +++ b/gpu/command_buffer/client/client_context_state_autogen.h @@ -0,0 +1,27 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! + +// It is included by client_context_state.h +#ifndef GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_AUTOGEN_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_AUTOGEN_H_ + +struct EnableFlags { + EnableFlags(); + bool blend; + bool cull_face; + bool depth_test; + bool dither; + bool polygon_offset_fill; + bool sample_alpha_to_coverage; + bool sample_coverage; + bool scissor_test; + bool stencil_test; +}; + +#endif // GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_AUTOGEN_H_ + diff --git a/gpu/command_buffer/client/client_context_state_impl_autogen.h b/gpu/command_buffer/client/client_context_state_impl_autogen.h new file mode 100644 index 0000000..150816d --- /dev/null +++ b/gpu/command_buffer/client/client_context_state_impl_autogen.h @@ -0,0 +1,123 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! + +// It is included by client_context_state.cc +#ifndef GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_IMPL_AUTOGEN_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_IMPL_AUTOGEN_H_ + +ClientContextState::EnableFlags::EnableFlags() + : blend(false), + cull_face(false), + depth_test(false), + dither(true), + polygon_offset_fill(false), + sample_alpha_to_coverage(false), + sample_coverage(false), + scissor_test(false), + stencil_test(false) { +} + + +bool ClientContextState::SetCapabilityState( + GLenum cap, bool enabled, bool* changed) { + *changed = false; + switch (cap) { + case GL_BLEND: + if (enable_flags.blend != enabled) { + *changed = true; + enable_flags.blend = enabled; + } + return true; + case GL_CULL_FACE: + if (enable_flags.cull_face != enabled) { + *changed = true; + enable_flags.cull_face = enabled; + } + return true; + case GL_DEPTH_TEST: + if (enable_flags.depth_test != enabled) { + *changed = true; + enable_flags.depth_test = enabled; + } + return true; + case GL_DITHER: + if (enable_flags.dither != enabled) { + *changed = true; + enable_flags.dither = enabled; + } + return true; + case GL_POLYGON_OFFSET_FILL: + if (enable_flags.polygon_offset_fill != enabled) { + *changed = true; + enable_flags.polygon_offset_fill = enabled; + } + return true; + case GL_SAMPLE_ALPHA_TO_COVERAGE: + if (enable_flags.sample_alpha_to_coverage != enabled) { + *changed = true; + enable_flags.sample_alpha_to_coverage = enabled; + } + return true; + case GL_SAMPLE_COVERAGE: + if (enable_flags.sample_coverage != enabled) { + *changed = true; + enable_flags.sample_coverage = enabled; + } + return true; + case GL_SCISSOR_TEST: + if (enable_flags.scissor_test != enabled) { + *changed = true; + enable_flags.scissor_test = enabled; + } + return true; + case GL_STENCIL_TEST: + if (enable_flags.stencil_test != enabled) { + *changed = true; + enable_flags.stencil_test = enabled; + } + return true; + default: + return false; + } +} +bool ClientContextState::GetEnabled( + GLenum cap, bool* enabled) const { + switch (cap) { + case GL_BLEND: + *enabled = enable_flags.blend; + return true; + case GL_CULL_FACE: + *enabled = enable_flags.cull_face; + return true; + case GL_DEPTH_TEST: + *enabled = enable_flags.depth_test; + return true; + case GL_DITHER: + *enabled = enable_flags.dither; + return true; + case GL_POLYGON_OFFSET_FILL: + *enabled = enable_flags.polygon_offset_fill; + return true; + case GL_SAMPLE_ALPHA_TO_COVERAGE: + *enabled = enable_flags.sample_alpha_to_coverage; + return true; + case GL_SAMPLE_COVERAGE: + *enabled = enable_flags.sample_coverage; + return true; + case GL_SCISSOR_TEST: + *enabled = enable_flags.scissor_test; + return true; + case GL_STENCIL_TEST: + *enabled = enable_flags.stencil_test; + return true; + default: + return false; + } +} +#endif // GPU_COMMAND_BUFFER_CLIENT_CLIENT_CONTEXT_STATE_IMPL_AUTOGEN_H_ + diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 8960cff..8f67194 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -391,7 +391,7 @@ const size_t GLES2Implementation::kMaxSizeOfSimpleResult; const unsigned int GLES2Implementation::kStartingOffset; #endif -GLES2Implementation::GLCachedState::IntState::IntState() +GLES2Implementation::GLStaticState::IntState::IntState() : max_combined_texture_image_units(0), max_cube_map_texture_size(0), max_fragment_uniform_vectors(0), @@ -437,6 +437,7 @@ GLES2Implementation::GLES2Implementation( active_texture_unit_(0), bound_framebuffer_(0), bound_renderbuffer_(0), + current_program_(0), bound_array_buffer_id_(0), bound_element_array_buffer_id_(0), client_side_array_id_(0), @@ -503,16 +504,17 @@ bool GLES2Implementation::Initialize( GetMultipleIntegervCHROMIUM( pnames, arraysize(pnames), - &gl_state_.int_state.max_combined_texture_image_units, - sizeof(gl_state_.int_state)); + &static_state_.int_state.max_combined_texture_image_units, + sizeof(static_state_.int_state)); util_.set_num_compressed_texture_formats( - gl_state_.int_state.num_compressed_texture_formats); + static_state_.int_state.num_compressed_texture_formats); util_.set_num_shader_binary_formats( - gl_state_.int_state.num_shader_binary_formats); + static_state_.int_state.num_shader_binary_formats); texture_units_.reset( - new TextureUnit[gl_state_.int_state.max_combined_texture_image_units]); + new TextureUnit[ + static_state_.int_state.max_combined_texture_image_units]); query_tracker_.reset(new QueryTracker(mapped_memory_.get())); @@ -521,7 +523,7 @@ bool GLES2Implementation::Initialize( this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); client_side_buffer_helper_.reset(new ClientSideBufferHelper( - gl_state_.int_state.max_vertex_attribs, + static_state_.int_state.max_vertex_attribs, reserved_ids_[0], reserved_ids_[1])); #endif @@ -810,54 +812,24 @@ void GLES2Implementation::SetBucketAsString( SetBucketContents(bucket_id, str.c_str(), str.size() + 1); } -bool GLES2Implementation::SetCapabilityState(GLenum cap, bool enabled) { - switch (cap) { - case GL_DITHER: - gl_state_.enable_state.dither = enabled; - return true; - case GL_BLEND: - gl_state_.enable_state.blend = enabled; - return true; - case GL_CULL_FACE: - gl_state_.enable_state.cull_face = enabled; - return true; - case GL_DEPTH_TEST: - gl_state_.enable_state.depth_test = enabled; - return true; - case GL_POLYGON_OFFSET_FILL: - gl_state_.enable_state.polygon_offset_fill = enabled; - return true; - case GL_SAMPLE_ALPHA_TO_COVERAGE: - gl_state_.enable_state.sample_alpha_to_coverage = enabled; - return true; - case GL_SAMPLE_COVERAGE: - gl_state_.enable_state.sample_coverage = enabled; - return true; - case GL_SCISSOR_TEST: - gl_state_.enable_state.scissor_test = enabled; - return true; - case GL_STENCIL_TEST: - gl_state_.enable_state.stencil_test = enabled; - return true; - default: - return false; - } -} - void GLES2Implementation::Disable(GLenum cap) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDisable(" << GLES2Util::GetStringCapability(cap) << ")"); - SetCapabilityState(cap, false); - helper_->Disable(cap); + bool changed = false; + if (!state_.SetCapabilityState(cap, false, &changed) || changed) { + helper_->Disable(cap); + } } void GLES2Implementation::Enable(GLenum cap) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnable(" << GLES2Util::GetStringCapability(cap) << ")"); - SetCapabilityState(cap, true); - helper_->Enable(cap); + bool changed = false; + if (!state_.SetCapabilityState(cap, true, &changed) || changed) { + helper_->Enable(cap); + } } GLboolean GLES2Implementation::IsEnabled(GLenum cap) { @@ -865,47 +837,18 @@ GLboolean GLES2Implementation::IsEnabled(GLenum cap) { GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsEnabled(" << GLES2Util::GetStringCapability(cap) << ")"); bool state = false; - switch (cap) { - case GL_DITHER: - state = gl_state_.enable_state.dither; - break; - case GL_BLEND: - state = gl_state_.enable_state.blend; - break; - case GL_CULL_FACE: - state = gl_state_.enable_state.cull_face; - break; - case GL_DEPTH_TEST: - state = gl_state_.enable_state.depth_test; - break; - case GL_POLYGON_OFFSET_FILL: - state = gl_state_.enable_state.polygon_offset_fill; - break; - case GL_SAMPLE_ALPHA_TO_COVERAGE: - state = gl_state_.enable_state.sample_alpha_to_coverage; - break; - case GL_SAMPLE_COVERAGE: - state = gl_state_.enable_state.sample_coverage; - break; - case GL_SCISSOR_TEST: - state = gl_state_.enable_state.scissor_test; - break; - case GL_STENCIL_TEST: - state = gl_state_.enable_state.stencil_test; - break; - default: { - typedef IsEnabled::Result Result; - Result* result = GetResultAs<Result*>(); - if (!result) { - return GL_FALSE; - } - *result = 0; - helper_->IsEnabled(cap, GetResultShmId(), GetResultShmOffset()); - WaitForCmd(); - state = (*result) != 0; - break; + if (!state_.GetEnabled(cap, &state)) { + typedef IsEnabled::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return GL_FALSE; } + *result = 0; + helper_->IsEnabled(cap, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + state = (*result) != 0; } + GPU_CLIENT_LOG("returned " << state); return state; } @@ -913,40 +856,40 @@ GLboolean GLES2Implementation::IsEnabled(GLenum cap) { bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { switch (pname) { case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: - *params = gl_state_.int_state.max_combined_texture_image_units; + *params = static_state_.int_state.max_combined_texture_image_units; return true; case GL_MAX_CUBE_MAP_TEXTURE_SIZE: - *params = gl_state_.int_state.max_cube_map_texture_size; + *params = static_state_.int_state.max_cube_map_texture_size; return true; case GL_MAX_FRAGMENT_UNIFORM_VECTORS: - *params = gl_state_.int_state.max_fragment_uniform_vectors; + *params = static_state_.int_state.max_fragment_uniform_vectors; return true; case GL_MAX_RENDERBUFFER_SIZE: - *params = gl_state_.int_state.max_renderbuffer_size; + *params = static_state_.int_state.max_renderbuffer_size; return true; case GL_MAX_TEXTURE_IMAGE_UNITS: - *params = gl_state_.int_state.max_texture_image_units; + *params = static_state_.int_state.max_texture_image_units; return true; case GL_MAX_TEXTURE_SIZE: - *params = gl_state_.int_state.max_texture_size; + *params = static_state_.int_state.max_texture_size; return true; case GL_MAX_VARYING_VECTORS: - *params = gl_state_.int_state.max_varying_vectors; + *params = static_state_.int_state.max_varying_vectors; return true; case GL_MAX_VERTEX_ATTRIBS: - *params = gl_state_.int_state.max_vertex_attribs; + *params = static_state_.int_state.max_vertex_attribs; return true; case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: - *params = gl_state_.int_state.max_vertex_texture_image_units; + *params = static_state_.int_state.max_vertex_texture_image_units; return true; case GL_MAX_VERTEX_UNIFORM_VECTORS: - *params = gl_state_.int_state.max_vertex_uniform_vectors; + *params = static_state_.int_state.max_vertex_uniform_vectors; return true; case GL_NUM_COMPRESSED_TEXTURE_FORMATS: - *params = gl_state_.int_state.num_compressed_texture_formats; + *params = static_state_.int_state.num_compressed_texture_formats; return true; case GL_NUM_SHADER_BINARY_FORMATS: - *params = gl_state_.int_state.num_shader_binary_formats; + *params = static_state_.int_state.num_shader_binary_formats; return true; case GL_ARRAY_BUFFER_BINDING: if (share_group_->bind_generates_resource()) { @@ -1316,6 +1259,9 @@ bool GLES2Implementation::DeleteProgramHelper(GLuint program) { "glDeleteProgram", "id not created by this context."); return false; } + if (program == current_program_) { + current_program_ = 0; + } return true; } @@ -1401,6 +1347,15 @@ GLint GLES2Implementation::GetUniformLocation( return loc; } +void GLES2Implementation::UseProgram(GLuint program) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUseProgram(" << program << ")"); + if (current_program_ != program) { + current_program_ = program; + helper_->UseProgram(program); + } +} + bool GLES2Implementation::GetProgramivHelper( GLuint program, GLenum pname, GLint* params) { bool got_value = share_group_->program_info_manager()->GetProgramiv( @@ -2390,7 +2345,7 @@ void GLES2Implementation::ActiveTexture(GLenum texture) { << GLES2Util::GetStringEnum(texture) << ")"); GLuint texture_index = texture - GL_TEXTURE0; if (texture_index >= static_cast<GLuint>( - gl_state_.int_state.max_combined_texture_image_units)) { + static_state_.int_state.max_combined_texture_image_units)) { SetGLErrorInvalidEnum( "glActiveTexture", texture, "texture"); return; @@ -2407,77 +2362,111 @@ void GLES2Implementation::ActiveTexture(GLenum texture) { // the old model but possibly not true in the new model if another context has // deleted the resource. -void GLES2Implementation::BindBufferHelper( +bool GLES2Implementation::BindBufferHelper( GLenum target, GLuint buffer) { // TODO(gman): See note #1 above. + bool changed = false; switch (target) { case GL_ARRAY_BUFFER: - bound_array_buffer_id_ = buffer; + if (bound_array_buffer_id_ != buffer) { + bound_array_buffer_id_ = buffer; + changed = true; + } break; case GL_ELEMENT_ARRAY_BUFFER: - bound_element_array_buffer_id_ = buffer; + if (bound_element_array_buffer_id_ != buffer) { + bound_element_array_buffer_id_ = buffer; + changed = true; + } break; default: + 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); + return changed; } -void GLES2Implementation::BindFramebufferHelper( +bool GLES2Implementation::BindFramebufferHelper( GLenum target, GLuint framebuffer) { // TODO(gman): See note #1 above. + bool changed = false; switch (target) { case GL_FRAMEBUFFER: - bound_framebuffer_ = framebuffer; + if (bound_framebuffer_ != framebuffer) { + bound_framebuffer_ = framebuffer; + changed = true; + } break; default: + 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::kFramebuffers)->MarkAsUsedForBind(framebuffer); + return changed; } -void GLES2Implementation::BindRenderbufferHelper( +bool GLES2Implementation::BindRenderbufferHelper( GLenum target, GLuint renderbuffer) { // TODO(gman): See note #1 above. + bool changed = false; switch (target) { case GL_RENDERBUFFER: - bound_renderbuffer_ = renderbuffer; + if (bound_renderbuffer_ != renderbuffer) { + bound_renderbuffer_ = renderbuffer; + changed = true; + } break; default: + 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; } -void GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) { +bool GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) { // TODO(gman): See note #1 above. + bool changed = false; TextureUnit& unit = texture_units_[active_texture_unit_]; switch (target) { case GL_TEXTURE_2D: - unit.bound_texture_2d = texture; + if (unit.bound_texture_2d != texture) { + unit.bound_texture_2d = texture; + changed = true; + } break; case GL_TEXTURE_CUBE_MAP: - unit.bound_texture_cube_map = texture; + if (unit.bound_texture_cube_map != texture) { + unit.bound_texture_cube_map = texture; + changed = true; + } break; default: + 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; } -void GLES2Implementation::BindVertexArrayHelper(GLuint array) { +bool GLES2Implementation::BindVertexArrayHelper(GLuint array) { // TODO(gman): See note #1 above. - bound_vertex_array_id_ = array; - + bool changed = false; + if (bound_vertex_array_id_ != array) { + bound_vertex_array_id_ = array; + changed = true; + } GetIdHandler(id_namespaces::kVertexArrays)->MarkAsUsedForBind(array); + return changed; } #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) @@ -2573,7 +2562,7 @@ void GLES2Implementation::DeleteTexturesHelper( } for (GLsizei ii = 0; ii < n; ++ii) { for (GLint tt = 0; - tt < gl_state_.int_state.max_combined_texture_image_units; + tt < static_state_.int_state.max_combined_texture_image_units; ++tt) { TextureUnit& unit = texture_units_[tt]; if (textures[ii] == unit.bound_texture_2d) { diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index 47fb3b0..1ba9acd 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -18,6 +18,7 @@ #include "../common/gles2_cmd_utils.h" #include "../common/scoped_ptr.h" #include "../client/ref_counted.h" +#include "../client/client_context_state.h" #include "../client/gles2_cmd_helper.h" #include "../client/gles2_interface.h" #include "../client/query_tracker.h" @@ -108,8 +109,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { virtual void OnErrorMessage(const char* msg, int id) = 0; }; - // Stores client side cached GL state. - struct GLCachedState { + // Stores GL state that never changes. + struct GLStaticState { struct GLES2_IMPL_EXPORT IntState { IntState(); GLint max_combined_texture_image_units; @@ -125,32 +126,7 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { GLint num_compressed_texture_formats; GLint num_shader_binary_formats; }; - struct EnableState { - EnableState() - : blend(false), - cull_face(false), - depth_test(false), - dither(false), - polygon_offset_fill(false), - sample_alpha_to_coverage(false), - sample_coverage(false), - scissor_test(false), - stencil_test(false) { - } - - bool blend; - bool cull_face; - bool depth_test; - bool dither; - bool polygon_offset_fill; - bool sample_alpha_to_coverage; - bool sample_coverage; - bool scissor_test; - bool stencil_test; - }; - IntState int_state; - EnableState enable_state; }; // The maxiumum result size from simple GL get commands. @@ -406,11 +382,11 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { bool IsTextureReservedId(GLuint id) { return false; } bool IsVertexArrayReservedId(GLuint id) { return false; } - void BindBufferHelper(GLenum target, GLuint texture); - void BindFramebufferHelper(GLenum target, GLuint texture); - void BindRenderbufferHelper(GLenum target, GLuint texture); - void BindTextureHelper(GLenum target, GLuint texture); - void BindVertexArrayHelper(GLuint array); + 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 BindVertexArrayHelper(GLuint array); void DeleteBuffersHelper(GLsizei n, const GLuint* buffers); void DeleteFramebuffersHelper(GLsizei n, const GLuint* framebuffers); @@ -497,7 +473,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { ExtensionStatus angle_pack_reverse_row_order_status; - GLCachedState gl_state_; + GLStaticState static_state_; + ClientContextState state_; // pack alignment as last set by glPixelStorei GLint pack_alignment_; @@ -528,6 +505,9 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { GLuint bound_framebuffer_; GLuint bound_renderbuffer_; + // The program in use by glUseProgram + GLuint current_program_; + // The currently bound array buffer. GLuint bound_array_buffer_id_; diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 2ffd65c..a2b9227 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h @@ -24,8 +24,9 @@ void GLES2Implementation::BindBuffer(GLenum target, GLuint buffer) { SetGLError(GL_INVALID_OPERATION, "BindBuffer", "buffer reserved id"); return; } - BindBufferHelper(target, buffer); - helper_->BindBuffer(target, buffer); + if (BindBufferHelper(target, buffer)) { + helper_->BindBuffer(target, buffer); + } } void GLES2Implementation::BindFramebuffer(GLenum target, GLuint framebuffer) { @@ -36,8 +37,9 @@ void GLES2Implementation::BindFramebuffer(GLenum target, GLuint framebuffer) { GL_INVALID_OPERATION, "BindFramebuffer", "framebuffer reserved id"); return; } - BindFramebufferHelper(target, framebuffer); - helper_->BindFramebuffer(target, framebuffer); + if (BindFramebufferHelper(target, framebuffer)) { + helper_->BindFramebuffer(target, framebuffer); + } } void GLES2Implementation::BindRenderbuffer( @@ -49,8 +51,9 @@ void GLES2Implementation::BindRenderbuffer( GL_INVALID_OPERATION, "BindRenderbuffer", "renderbuffer reserved id"); return; } - BindRenderbufferHelper(target, renderbuffer); - helper_->BindRenderbuffer(target, renderbuffer); + if (BindRenderbufferHelper(target, renderbuffer)) { + helper_->BindRenderbuffer(target, renderbuffer); + } } void GLES2Implementation::BindTexture(GLenum target, GLuint texture) { @@ -60,8 +63,9 @@ void GLES2Implementation::BindTexture(GLenum target, GLuint texture) { SetGLError(GL_INVALID_OPERATION, "BindTexture", "texture reserved id"); return; } - BindTextureHelper(target, texture); - helper_->BindTexture(target, texture); + if (BindTextureHelper(target, texture)) { + helper_->BindTexture(target, texture); + } } void GLES2Implementation::BlendColor( @@ -1192,12 +1196,6 @@ void GLES2Implementation::UniformMatrix4fv( helper_->UniformMatrix4fvImmediate(location, count, transpose, value); } -void GLES2Implementation::UseProgram(GLuint program) { - GPU_CLIENT_SINGLE_THREAD_CHECK(); - GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUseProgram(" << program << ")"); - helper_->UseProgram(program); -} - void GLES2Implementation::ValidateProgram(GLuint program) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glValidateProgram(" << program << ")"); // NOLINT @@ -1426,8 +1424,9 @@ void GLES2Implementation::BindVertexArrayOES(GLuint array) { GL_INVALID_OPERATION, "BindVertexArrayOES", "array reserved id"); return; } - BindVertexArrayHelper(array); - helper_->BindVertexArrayOES(array); + if (BindVertexArrayHelper(array)) { + helper_->BindVertexArrayOES(array); + } } void GLES2Implementation::GetTranslatedShaderSourceANGLE( diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 8844fb4..d203648 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -363,8 +363,8 @@ class GLES2ImplementationTest : public testing::Test { helper_.reset(new GLES2CmdHelper(command_buffer())); helper_->Initialize(kCommandBufferSizeBytes); - GLES2Implementation::GLCachedState state; - GLES2Implementation::GLCachedState::IntState& int_state = state.int_state; + GLES2Implementation::GLStaticState state; + GLES2Implementation::GLStaticState::IntState& int_state = state.int_state; int_state.max_combined_texture_image_units = kMaxCombinedTextureImageUnits; int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize; int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors; @@ -2555,11 +2555,13 @@ TEST_F(GLES2ImplementationTest, CapabilitiesAreCached) { GLenum state = kStates[ii]; expected.enable_cmd.Init(state); GLboolean result = gl_->IsEnabled(state); - EXPECT_FALSE(result); + EXPECT_EQ(static_cast<GLboolean>(ii == 0), result); EXPECT_TRUE(NoCommandsWritten()); const void* commands = GetPut(); - gl_->Enable(state); - EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected))); + if (!result) { + gl_->Enable(state); + EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected))); + } ClearCommands(); result = gl_->IsEnabled(state); EXPECT_TRUE(result); @@ -2768,6 +2770,37 @@ TEST_F(GLES2ImplementationTest, VertexArrays) { } #endif +TEST_F(GLES2ImplementationTest, Disable) { + struct Cmds { + Disable cmd; + }; + Cmds expected; + expected.cmd.Init(GL_DITHER); // Note: DITHER defaults to enabled. + + gl_->Disable(GL_DITHER); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + // Check it's cached and not called again. + ClearCommands(); + gl_->Disable(GL_DITHER); + EXPECT_TRUE(NoCommandsWritten()); +} + +TEST_F(GLES2ImplementationTest, Enable) { + struct Cmds { + Enable cmd; + }; + Cmds expected; + expected.cmd.Init(GL_BLEND); // Note: BLEND defaults to disabled. + + gl_->Enable(GL_BLEND); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + // Check it's cached and not called again. + ClearCommands(); + gl_->Enable(GL_BLEND); + EXPECT_TRUE(NoCommandsWritten()); +} + + #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h" } // namespace gles2 diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 890df13..304b357 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -33,6 +33,9 @@ TEST_F(GLES2ImplementationTest, BindBuffer) { gl_->BindBuffer(GL_ARRAY_BUFFER, 2); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + ClearCommands(); + gl_->BindBuffer(GL_ARRAY_BUFFER, 2); + EXPECT_TRUE(NoCommandsWritten()); } TEST_F(GLES2ImplementationTest, BindFramebuffer) { @@ -44,6 +47,9 @@ TEST_F(GLES2ImplementationTest, BindFramebuffer) { gl_->BindFramebuffer(GL_FRAMEBUFFER, 2); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + ClearCommands(); + gl_->BindFramebuffer(GL_FRAMEBUFFER, 2); + EXPECT_TRUE(NoCommandsWritten()); } TEST_F(GLES2ImplementationTest, BindRenderbuffer) { @@ -55,6 +61,9 @@ TEST_F(GLES2ImplementationTest, BindRenderbuffer) { gl_->BindRenderbuffer(GL_RENDERBUFFER, 2); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + ClearCommands(); + gl_->BindRenderbuffer(GL_RENDERBUFFER, 2); + EXPECT_TRUE(NoCommandsWritten()); } TEST_F(GLES2ImplementationTest, BindTexture) { @@ -66,6 +75,9 @@ TEST_F(GLES2ImplementationTest, BindTexture) { gl_->BindTexture(GL_TEXTURE_2D, 2); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + ClearCommands(); + gl_->BindTexture(GL_TEXTURE_2D, 2); + EXPECT_TRUE(NoCommandsWritten()); } TEST_F(GLES2ImplementationTest, BlendColor) { @@ -84,9 +96,9 @@ TEST_F(GLES2ImplementationTest, BlendEquation) { BlendEquation cmd; }; Cmds expected; - expected.cmd.Init(GL_FUNC_ADD); + expected.cmd.Init(GL_FUNC_SUBTRACT); - gl_->BlendEquation(GL_FUNC_ADD); + gl_->BlendEquation(GL_FUNC_SUBTRACT); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } @@ -95,9 +107,9 @@ TEST_F(GLES2ImplementationTest, BlendEquationSeparate) { BlendEquationSeparate cmd; }; Cmds expected; - expected.cmd.Init(GL_FUNC_ADD, GL_FUNC_ADD); + expected.cmd.Init(GL_FUNC_SUBTRACT, GL_FUNC_ADD); - gl_->BlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); + gl_->BlendEquationSeparate(GL_FUNC_SUBTRACT, GL_FUNC_ADD); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } @@ -366,17 +378,6 @@ TEST_F(GLES2ImplementationTest, DetachShader) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -TEST_F(GLES2ImplementationTest, Disable) { - struct Cmds { - Disable cmd; - }; - Cmds expected; - expected.cmd.Init(GL_BLEND); - - gl_->Disable(GL_BLEND); - EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); -} - TEST_F(GLES2ImplementationTest, DisableVertexAttribArray) { struct Cmds { DisableVertexAttribArray cmd; @@ -399,17 +400,6 @@ TEST_F(GLES2ImplementationTest, DrawArrays) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -TEST_F(GLES2ImplementationTest, Enable) { - struct Cmds { - Enable cmd; - }; - Cmds expected; - expected.cmd.Init(GL_BLEND); - - gl_->Enable(GL_BLEND); - EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); -} - TEST_F(GLES2ImplementationTest, EnableVertexAttribArray) { struct Cmds { EnableVertexAttribArray cmd; @@ -1050,9 +1040,9 @@ TEST_F(GLES2ImplementationTest, StencilOp) { StencilOp cmd; }; Cmds expected; - expected.cmd.Init(GL_KEEP, GL_KEEP, GL_KEEP); + expected.cmd.Init(GL_KEEP, GL_INCR, GL_KEEP); - gl_->StencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + gl_->StencilOp(GL_KEEP, GL_INCR, GL_KEEP); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } @@ -1061,9 +1051,9 @@ TEST_F(GLES2ImplementationTest, StencilOpSeparate) { StencilOpSeparate cmd; }; Cmds expected; - expected.cmd.Init(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP); + expected.cmd.Init(GL_FRONT, GL_INCR, GL_KEEP, GL_KEEP); - gl_->StencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP); + gl_->StencilOpSeparate(GL_FRONT, GL_INCR, GL_KEEP, GL_KEEP); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } @@ -1667,6 +1657,9 @@ TEST_F(GLES2ImplementationTest, BindVertexArrayOES) { gl_->BindVertexArrayOES(1); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + ClearCommands(); + gl_->BindVertexArrayOES(1); + EXPECT_TRUE(NoCommandsWritten()); } // TODO: Implement unit test for GenSharedIdsCHROMIUM // TODO: Implement unit test for DeleteSharedIdsCHROMIUM diff --git a/gpu/command_buffer/service/context_state.h b/gpu/command_buffer/service/context_state.h index b011ab2..a9fc5d0 100644 --- a/gpu/command_buffer/service/context_state.h +++ b/gpu/command_buffer/service/context_state.h @@ -88,6 +88,13 @@ struct GPU_EXPORT ContextState { void InitCapabilities() const; void InitState() const; + // Helper for getting cached state. + bool GetStateAsGLint( + GLenum pname, GLint* params, GLsizei* num_written) const; + bool GetStateAsGLfloat( + GLenum pname, GLfloat* params, GLsizei* num_written) const; + bool GetEnabled(GLenum cap) const; + #include "gpu/command_buffer/service/context_state_autogen.h" EnableFlags enable_flags; diff --git a/gpu/command_buffer/service/context_state_impl_autogen.h b/gpu/command_buffer/service/context_state_impl_autogen.h index c33cb7f..5342435 100644 --- a/gpu/command_buffer/service/context_state_impl_autogen.h +++ b/gpu/command_buffer/service/context_state_impl_autogen.h @@ -126,5 +126,631 @@ void ContextState::InitState() const { stencil_back_z_pass_op); glViewport(viewport_x, viewport_y, viewport_width, viewport_height); } +bool ContextState::GetEnabled(GLenum cap) const { + switch (cap) { + case GL_BLEND: + return enable_flags.blend; + case GL_CULL_FACE: + return enable_flags.cull_face; + case GL_DEPTH_TEST: + return enable_flags.depth_test; + case GL_DITHER: + return enable_flags.dither; + case GL_POLYGON_OFFSET_FILL: + return enable_flags.polygon_offset_fill; + case GL_SAMPLE_ALPHA_TO_COVERAGE: + return enable_flags.sample_alpha_to_coverage; + case GL_SAMPLE_COVERAGE: + return enable_flags.sample_coverage; + case GL_SCISSOR_TEST: + return enable_flags.scissor_test; + case GL_STENCIL_TEST: + return enable_flags.stencil_test; + default: + GPU_NOTREACHED(); + return false; + } +} + +bool ContextState::GetStateAsGLint( + GLenum pname, GLint* params, GLsizei* num_written) const { + switch (pname) { + case GL_VIEWPORT: + *num_written = 4; + if (params) { + params[0] = static_cast<GLint>(viewport_x); + params[1] = static_cast<GLint>(viewport_y); + params[2] = static_cast<GLint>(viewport_width); + params[3] = static_cast<GLint>(viewport_height); + } + return true; + case GL_BLEND_SRC_RGB: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(blend_source_rgb); + } + return true; + case GL_BLEND_DST_RGB: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(blend_dest_rgb); + } + return true; + case GL_BLEND_SRC_ALPHA: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(blend_source_alpha); + } + return true; + case GL_BLEND_DST_ALPHA: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(blend_dest_alpha); + } + return true; + case GL_LINE_WIDTH: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(line_width); + } + return true; + case GL_BLEND_COLOR: + *num_written = 4; + if (params) { + params[0] = static_cast<GLint>(blend_color_red); + params[1] = static_cast<GLint>(blend_color_green); + params[2] = static_cast<GLint>(blend_color_blue); + params[3] = static_cast<GLint>(blend_color_alpha); + } + return true; + case GL_STENCIL_CLEAR_VALUE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_clear); + } + return true; + case GL_COLOR_WRITEMASK: + *num_written = 4; + if (params) { + params[0] = static_cast<GLint>(color_mask_red); + params[1] = static_cast<GLint>(color_mask_green); + params[2] = static_cast<GLint>(color_mask_blue); + params[3] = static_cast<GLint>(color_mask_alpha); + } + return true; + case GL_COLOR_CLEAR_VALUE: + *num_written = 4; + if (params) { + params[0] = static_cast<GLint>(color_clear_red); + params[1] = static_cast<GLint>(color_clear_green); + params[2] = static_cast<GLint>(color_clear_blue); + params[3] = static_cast<GLint>(color_clear_alpha); + } + return true; + case GL_DEPTH_RANGE: + *num_written = 2; + if (params) { + params[0] = static_cast<GLint>(z_near); + params[1] = static_cast<GLint>(z_far); + } + return true; + case GL_DEPTH_CLEAR_VALUE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(depth_clear); + } + return true; + case GL_STENCIL_FAIL: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_front_fail_op); + } + return true; + case GL_STENCIL_PASS_DEPTH_FAIL: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_front_z_fail_op); + } + return true; + case GL_STENCIL_PASS_DEPTH_PASS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_front_z_pass_op); + } + return true; + case GL_STENCIL_BACK_FAIL: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_back_fail_op); + } + return true; + case GL_STENCIL_BACK_PASS_DEPTH_FAIL: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_back_z_fail_op); + } + return true; + case GL_STENCIL_BACK_PASS_DEPTH_PASS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_back_z_pass_op); + } + return true; + case GL_SCISSOR_BOX: + *num_written = 4; + if (params) { + params[0] = static_cast<GLint>(scissor_x); + params[1] = static_cast<GLint>(scissor_y); + params[2] = static_cast<GLint>(scissor_width); + params[3] = static_cast<GLint>(scissor_height); + } + return true; + case GL_FRONT_FACE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(front_face); + } + return true; + case GL_SAMPLE_COVERAGE_VALUE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(sample_coverage_value); + } + return true; + case GL_SAMPLE_COVERAGE_INVERT: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(sample_coverage_invert); + } + return true; + case GL_POLYGON_OFFSET_FACTOR: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(polygon_offset_factor); + } + return true; + case GL_POLYGON_OFFSET_UNITS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(polygon_offset_units); + } + return true; + case GL_CULL_FACE_MODE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(cull_mode); + } + return true; + case GL_DEPTH_FUNC: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(depth_func); + } + return true; + case GL_STENCIL_FUNC: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_front_func); + } + return true; + case GL_STENCIL_REF: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_front_ref); + } + return true; + case GL_STENCIL_VALUE_MASK: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_front_mask); + } + return true; + case GL_STENCIL_BACK_FUNC: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_back_func); + } + return true; + case GL_STENCIL_BACK_REF: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_back_ref); + } + return true; + case GL_STENCIL_BACK_VALUE_MASK: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_back_mask); + } + return true; + case GL_DEPTH_WRITEMASK: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(depth_mask); + } + return true; + case GL_BLEND_EQUATION_RGB: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(blend_equation_rgb); + } + return true; + case GL_BLEND_EQUATION_ALPHA: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(blend_equation_alpha); + } + return true; + case GL_STENCIL_WRITEMASK: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_front_writemask); + } + return true; + case GL_STENCIL_BACK_WRITEMASK: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_back_writemask); + } + return true; + case GL_BLEND: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(enable_flags.blend); + } + return true; + case GL_CULL_FACE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(enable_flags.cull_face); + } + return true; + case GL_DEPTH_TEST: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(enable_flags.depth_test); + } + return true; + case GL_DITHER: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(enable_flags.dither); + } + return true; + case GL_POLYGON_OFFSET_FILL: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(enable_flags.polygon_offset_fill); + } + return true; + case GL_SAMPLE_ALPHA_TO_COVERAGE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(enable_flags.sample_alpha_to_coverage); + } + return true; + case GL_SAMPLE_COVERAGE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(enable_flags.sample_coverage); + } + return true; + case GL_SCISSOR_TEST: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(enable_flags.scissor_test); + } + return true; + case GL_STENCIL_TEST: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(enable_flags.stencil_test); + } + return true; + default: + return false; + } +} + +bool ContextState::GetStateAsGLfloat( + GLenum pname, GLfloat* params, GLsizei* num_written) const { + switch (pname) { + case GL_VIEWPORT: + *num_written = 4; + if (params) { + params[0] = static_cast<GLfloat>(viewport_x); + params[1] = static_cast<GLfloat>(viewport_y); + params[2] = static_cast<GLfloat>(viewport_width); + params[3] = static_cast<GLfloat>(viewport_height); + } + return true; + case GL_BLEND_SRC_RGB: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(blend_source_rgb); + } + return true; + case GL_BLEND_DST_RGB: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(blend_dest_rgb); + } + return true; + case GL_BLEND_SRC_ALPHA: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(blend_source_alpha); + } + return true; + case GL_BLEND_DST_ALPHA: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(blend_dest_alpha); + } + return true; + case GL_LINE_WIDTH: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(line_width); + } + return true; + case GL_BLEND_COLOR: + *num_written = 4; + if (params) { + params[0] = static_cast<GLfloat>(blend_color_red); + params[1] = static_cast<GLfloat>(blend_color_green); + params[2] = static_cast<GLfloat>(blend_color_blue); + params[3] = static_cast<GLfloat>(blend_color_alpha); + } + return true; + case GL_STENCIL_CLEAR_VALUE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_clear); + } + return true; + case GL_COLOR_WRITEMASK: + *num_written = 4; + if (params) { + params[0] = static_cast<GLfloat>(color_mask_red); + params[1] = static_cast<GLfloat>(color_mask_green); + params[2] = static_cast<GLfloat>(color_mask_blue); + params[3] = static_cast<GLfloat>(color_mask_alpha); + } + return true; + case GL_COLOR_CLEAR_VALUE: + *num_written = 4; + if (params) { + params[0] = static_cast<GLfloat>(color_clear_red); + params[1] = static_cast<GLfloat>(color_clear_green); + params[2] = static_cast<GLfloat>(color_clear_blue); + params[3] = static_cast<GLfloat>(color_clear_alpha); + } + return true; + case GL_DEPTH_RANGE: + *num_written = 2; + if (params) { + params[0] = static_cast<GLfloat>(z_near); + params[1] = static_cast<GLfloat>(z_far); + } + return true; + case GL_DEPTH_CLEAR_VALUE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(depth_clear); + } + return true; + case GL_STENCIL_FAIL: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_front_fail_op); + } + return true; + case GL_STENCIL_PASS_DEPTH_FAIL: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_front_z_fail_op); + } + return true; + case GL_STENCIL_PASS_DEPTH_PASS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_front_z_pass_op); + } + return true; + case GL_STENCIL_BACK_FAIL: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_back_fail_op); + } + return true; + case GL_STENCIL_BACK_PASS_DEPTH_FAIL: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_back_z_fail_op); + } + return true; + case GL_STENCIL_BACK_PASS_DEPTH_PASS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_back_z_pass_op); + } + return true; + case GL_SCISSOR_BOX: + *num_written = 4; + if (params) { + params[0] = static_cast<GLfloat>(scissor_x); + params[1] = static_cast<GLfloat>(scissor_y); + params[2] = static_cast<GLfloat>(scissor_width); + params[3] = static_cast<GLfloat>(scissor_height); + } + return true; + case GL_FRONT_FACE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(front_face); + } + return true; + case GL_SAMPLE_COVERAGE_VALUE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(sample_coverage_value); + } + return true; + case GL_SAMPLE_COVERAGE_INVERT: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(sample_coverage_invert); + } + return true; + case GL_POLYGON_OFFSET_FACTOR: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(polygon_offset_factor); + } + return true; + case GL_POLYGON_OFFSET_UNITS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(polygon_offset_units); + } + return true; + case GL_CULL_FACE_MODE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(cull_mode); + } + return true; + case GL_DEPTH_FUNC: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(depth_func); + } + return true; + case GL_STENCIL_FUNC: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_front_func); + } + return true; + case GL_STENCIL_REF: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_front_ref); + } + return true; + case GL_STENCIL_VALUE_MASK: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_front_mask); + } + return true; + case GL_STENCIL_BACK_FUNC: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_back_func); + } + return true; + case GL_STENCIL_BACK_REF: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_back_ref); + } + return true; + case GL_STENCIL_BACK_VALUE_MASK: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_back_mask); + } + return true; + case GL_DEPTH_WRITEMASK: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(depth_mask); + } + return true; + case GL_BLEND_EQUATION_RGB: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(blend_equation_rgb); + } + return true; + case GL_BLEND_EQUATION_ALPHA: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(blend_equation_alpha); + } + return true; + case GL_STENCIL_WRITEMASK: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_front_writemask); + } + return true; + case GL_STENCIL_BACK_WRITEMASK: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_back_writemask); + } + return true; + case GL_BLEND: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(enable_flags.blend); + } + return true; + case GL_CULL_FACE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(enable_flags.cull_face); + } + return true; + case GL_DEPTH_TEST: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(enable_flags.depth_test); + } + return true; + case GL_DITHER: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(enable_flags.dither); + } + return true; + case GL_POLYGON_OFFSET_FILL: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(enable_flags.polygon_offset_fill); + } + return true; + case GL_SAMPLE_ALPHA_TO_COVERAGE: + *num_written = 1; + if (params) { + params[0] = + static_cast<GLfloat>(enable_flags.sample_alpha_to_coverage); + } + return true; + case GL_SAMPLE_COVERAGE: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(enable_flags.sample_coverage); + } + return true; + case GL_SCISSOR_TEST: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(enable_flags.scissor_test); + } + return true; + case GL_STENCIL_TEST: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(enable_flags.stencil_test); + } + return true; + default: + return false; + } +} #endif // GPU_COMMAND_BUFFER_SERVICE_CONTEXT_STATE_IMPL_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 772d6d4..535918d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -982,9 +982,6 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written); - // Same as GetHelper except for auto-generated state. - bool GetStateAsGLint(GLenum pname, GLint* params, GLsizei* num_written); - bool GetStateAsGLfloat(GLenum pname, GLfloat* params, GLsizei* num_written); // Wrapper for glCreateProgram bool CreateProgramHelper(GLuint client_id); @@ -3880,7 +3877,7 @@ bool GLES2DecoderImpl::GetHelper( bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet( GLenum pname, GLsizei* num_values) { - if (GetStateAsGLint(pname, NULL, num_values)) { + if (state_.GetStateAsGLint(pname, NULL, num_values)) { return true; } return GetHelper(pname, NULL, num_values); @@ -3891,7 +3888,7 @@ void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) { GLsizei num_written = 0; if (GetNumValuesReturnedForGLGet(pname, &num_written)) { scoped_array<GLint> values(new GLint[num_written]); - if (!GetStateAsGLint(pname, values.get(), &num_written)) { + if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) { GetHelper(pname, values.get(), &num_written); } for (GLsizei ii = 0; ii < num_written; ++ii) { @@ -3905,7 +3902,7 @@ void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) { void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) { DCHECK(params); GLsizei num_written = 0; - if (!GetStateAsGLfloat(pname, params, &num_written)) { + if (!state_.GetStateAsGLfloat(pname, params, &num_written)) { if (GetHelper(pname, NULL, &num_written)) { scoped_array<GLint> values(new GLint[num_written]); GetHelper(pname, values.get(), &num_written); @@ -3921,7 +3918,7 @@ void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) { void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) { DCHECK(params); GLsizei num_written; - if (!GetStateAsGLint(pname, params, &num_written) && + if (!state_.GetStateAsGLint(pname, params, &num_written) && !GetHelper(pname, params, &num_written)) { glGetIntegerv(pname, params); } @@ -5857,6 +5854,10 @@ error::Error GLES2DecoderImpl::HandleGetShaderInfoLog( return error::kNoError; } +bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) { + return state_.GetEnabled(cap); +} + bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) { const BufferManager::BufferInfo* buffer = GetBufferInfo(client_id); return buffer && buffer->IsValid() && !buffer->IsDeleted(); @@ -8422,7 +8423,7 @@ error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM( GLint* start = results; for (GLuint ii = 0; ii < count; ++ii) { GLsizei num_written = 0; - if (!GetStateAsGLint(enums[ii], results, &num_written) && + if (!state_.GetStateAsGLint(enums[ii], results, &num_written) && !GetHelper(enums[ii], results, &num_written)) { glGetIntegerv(enums[ii], results); } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 9512a79..4a8d2a7 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -79,11 +79,16 @@ error::Error GLES2DecoderImpl::HandleBlendColor( GLclampf green = static_cast<GLclampf>(c.green); GLclampf blue = static_cast<GLclampf>(c.blue); GLclampf alpha = static_cast<GLclampf>(c.alpha); - state_.blend_color_red = red; - state_.blend_color_green = green; - state_.blend_color_blue = blue; - state_.blend_color_alpha = alpha; - glBlendColor(red, green, blue, alpha); + if (state_.blend_color_red != red || + state_.blend_color_green != green || + state_.blend_color_blue != blue || + state_.blend_color_alpha != alpha) { + state_.blend_color_red = red; + state_.blend_color_green = green; + state_.blend_color_blue = blue; + state_.blend_color_alpha = alpha; + glBlendColor(red, green, blue, alpha); + } return error::kNoError; } @@ -94,9 +99,12 @@ error::Error GLES2DecoderImpl::HandleBlendEquation( SetGLErrorInvalidEnum("glBlendEquation", mode, "mode"); return error::kNoError; } - state_.blend_equation_rgb = mode; - state_.blend_equation_alpha = mode; - glBlendEquation(mode); + if (state_.blend_equation_rgb != mode || + state_.blend_equation_alpha != mode) { + state_.blend_equation_rgb = mode; + state_.blend_equation_alpha = mode; + glBlendEquation(mode); + } return error::kNoError; } @@ -112,9 +120,12 @@ error::Error GLES2DecoderImpl::HandleBlendEquationSeparate( SetGLErrorInvalidEnum("glBlendEquationSeparate", modeAlpha, "modeAlpha"); return error::kNoError; } - state_.blend_equation_rgb = modeRGB; - state_.blend_equation_alpha = modeAlpha; - glBlendEquationSeparate(modeRGB, modeAlpha); + if (state_.blend_equation_rgb != modeRGB || + state_.blend_equation_alpha != modeAlpha) { + state_.blend_equation_rgb = modeRGB; + state_.blend_equation_alpha = modeAlpha; + glBlendEquationSeparate(modeRGB, modeAlpha); + } return error::kNoError; } @@ -130,11 +141,16 @@ error::Error GLES2DecoderImpl::HandleBlendFunc( SetGLErrorInvalidEnum("glBlendFunc", dfactor, "dfactor"); return error::kNoError; } - state_.blend_source_rgb = sfactor; - state_.blend_dest_rgb = dfactor; - state_.blend_source_alpha = sfactor; - state_.blend_dest_alpha = dfactor; - glBlendFunc(sfactor, dfactor); + if (state_.blend_source_rgb != sfactor || + state_.blend_dest_rgb != dfactor || + state_.blend_source_alpha != sfactor || + state_.blend_dest_alpha != dfactor) { + state_.blend_source_rgb = sfactor; + state_.blend_dest_rgb = dfactor; + state_.blend_source_alpha = sfactor; + state_.blend_dest_alpha = dfactor; + glBlendFunc(sfactor, dfactor); + } return error::kNoError; } @@ -160,11 +176,16 @@ error::Error GLES2DecoderImpl::HandleBlendFuncSeparate( SetGLErrorInvalidEnum("glBlendFuncSeparate", dstAlpha, "dstAlpha"); return error::kNoError; } - state_.blend_source_rgb = srcRGB; - state_.blend_dest_rgb = dstRGB; - state_.blend_source_alpha = srcAlpha; - state_.blend_dest_alpha = dstAlpha; - glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); + if (state_.blend_source_rgb != srcRGB || + state_.blend_dest_rgb != dstRGB || + state_.blend_source_alpha != srcAlpha || + state_.blend_dest_alpha != dstAlpha) { + state_.blend_source_rgb = srcRGB; + state_.blend_dest_rgb = dstRGB; + state_.blend_source_alpha = srcAlpha; + state_.blend_dest_alpha = dstAlpha; + glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); + } return error::kNoError; } @@ -237,27 +258,36 @@ error::Error GLES2DecoderImpl::HandleClearColor( GLclampf green = static_cast<GLclampf>(c.green); GLclampf blue = static_cast<GLclampf>(c.blue); GLclampf alpha = static_cast<GLclampf>(c.alpha); - state_.color_clear_red = red; - state_.color_clear_green = green; - state_.color_clear_blue = blue; - state_.color_clear_alpha = alpha; - glClearColor(red, green, blue, alpha); + if (state_.color_clear_red != red || + state_.color_clear_green != green || + state_.color_clear_blue != blue || + state_.color_clear_alpha != alpha) { + state_.color_clear_red = red; + state_.color_clear_green = green; + state_.color_clear_blue = blue; + state_.color_clear_alpha = alpha; + glClearColor(red, green, blue, alpha); + } return error::kNoError; } error::Error GLES2DecoderImpl::HandleClearDepthf( uint32 immediate_data_size, const gles2::ClearDepthf& c) { GLclampf depth = static_cast<GLclampf>(c.depth); - state_.depth_clear = depth; - glClearDepth(depth); + if (state_.depth_clear != depth) { + state_.depth_clear = depth; + glClearDepth(depth); + } return error::kNoError; } error::Error GLES2DecoderImpl::HandleClearStencil( uint32 immediate_data_size, const gles2::ClearStencil& c) { GLint s = static_cast<GLint>(c.s); - state_.stencil_clear = s; - glClearStencil(s); + if (state_.stencil_clear != s) { + state_.stencil_clear = s; + glClearStencil(s); + } return error::kNoError; } @@ -267,11 +297,16 @@ error::Error GLES2DecoderImpl::HandleColorMask( GLboolean green = static_cast<GLboolean>(c.green); GLboolean blue = static_cast<GLboolean>(c.blue); GLboolean alpha = static_cast<GLboolean>(c.alpha); - state_.color_mask_red = red; - state_.color_mask_green = green; - state_.color_mask_blue = blue; - state_.color_mask_alpha = alpha; - clear_state_dirty_ = true; + if (state_.color_mask_red != red || + state_.color_mask_green != green || + state_.color_mask_blue != blue || + state_.color_mask_alpha != alpha) { + state_.color_mask_red = red; + state_.color_mask_green = green; + state_.color_mask_blue = blue; + state_.color_mask_alpha = alpha; + clear_state_dirty_ = true; + } return error::kNoError; } @@ -457,8 +492,10 @@ error::Error GLES2DecoderImpl::HandleCullFace( SetGLErrorInvalidEnum("glCullFace", mode, "mode"); return error::kNoError; } - state_.cull_mode = mode; - glCullFace(mode); + if (state_.cull_mode != mode) { + state_.cull_mode = mode; + glCullFace(mode); + } return error::kNoError; } @@ -597,16 +634,20 @@ error::Error GLES2DecoderImpl::HandleDepthFunc( SetGLErrorInvalidEnum("glDepthFunc", func, "func"); return error::kNoError; } - state_.depth_func = func; - glDepthFunc(func); + if (state_.depth_func != func) { + state_.depth_func = func; + glDepthFunc(func); + } return error::kNoError; } error::Error GLES2DecoderImpl::HandleDepthMask( uint32 immediate_data_size, const gles2::DepthMask& c) { GLboolean flag = static_cast<GLboolean>(c.flag); - state_.depth_mask = flag; - clear_state_dirty_ = true; + if (state_.depth_mask != flag) { + state_.depth_mask = flag; + clear_state_dirty_ = true; + } return error::kNoError; } @@ -734,8 +775,10 @@ error::Error GLES2DecoderImpl::HandleFrontFace( SetGLErrorInvalidEnum("glFrontFace", mode, "mode"); return error::kNoError; } - state_.front_face = mode; - glFrontFace(mode); + if (state_.front_face != mode) { + state_.front_face = mode; + glFrontFace(mode); + } return error::kNoError; } @@ -1430,8 +1473,10 @@ error::Error GLES2DecoderImpl::HandleIsTexture( error::Error GLES2DecoderImpl::HandleLineWidth( uint32 immediate_data_size, const gles2::LineWidth& c) { GLfloat width = static_cast<GLfloat>(c.width); - state_.line_width = width; - glLineWidth(width); + if (state_.line_width != width) { + state_.line_width = width; + glLineWidth(width); + } return error::kNoError; } @@ -1446,9 +1491,12 @@ error::Error GLES2DecoderImpl::HandlePolygonOffset( uint32 immediate_data_size, const gles2::PolygonOffset& c) { GLfloat factor = static_cast<GLfloat>(c.factor); GLfloat units = static_cast<GLfloat>(c.units); - state_.polygon_offset_factor = factor; - state_.polygon_offset_units = units; - glPolygonOffset(factor, units); + if (state_.polygon_offset_factor != factor || + state_.polygon_offset_units != units) { + state_.polygon_offset_factor = factor; + state_.polygon_offset_units = units; + glPolygonOffset(factor, units); + } return error::kNoError; } @@ -1507,11 +1555,16 @@ error::Error GLES2DecoderImpl::HandleScissor( SetGLError(GL_INVALID_VALUE, "glScissor", "height < 0"); return error::kNoError; } - state_.scissor_x = x; - state_.scissor_y = y; - state_.scissor_width = width; - state_.scissor_height = height; - glScissor(x, y, width, height); + if (state_.scissor_x != x || + state_.scissor_y != y || + state_.scissor_width != width || + state_.scissor_height != height) { + state_.scissor_x = x; + state_.scissor_y = y; + state_.scissor_width = width; + state_.scissor_height = height; + glScissor(x, y, width, height); + } return error::kNoError; } @@ -1524,7 +1577,20 @@ error::Error GLES2DecoderImpl::HandleStencilFunc( SetGLErrorInvalidEnum("glStencilFunc", func, "func"); return error::kNoError; } - glStencilFunc(func, ref, mask); + if (state_.stencil_front_func != func || + state_.stencil_front_ref != ref || + state_.stencil_front_mask != mask || + state_.stencil_back_func != func || + state_.stencil_back_ref != ref || + state_.stencil_back_mask != mask) { + state_.stencil_front_func = func; + state_.stencil_front_ref = ref; + state_.stencil_front_mask = mask; + state_.stencil_back_func = func; + state_.stencil_back_ref = ref; + state_.stencil_back_mask = mask; + glStencilFunc(func, ref, mask); + } return error::kNoError; } @@ -1542,16 +1608,42 @@ error::Error GLES2DecoderImpl::HandleStencilFuncSeparate( SetGLErrorInvalidEnum("glStencilFuncSeparate", func, "func"); return error::kNoError; } - glStencilFuncSeparate(face, func, ref, mask); + bool changed = false; + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + changed |= state_.stencil_front_func != func || + state_.stencil_front_ref != ref || + state_.stencil_front_mask != mask; + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + changed |= state_.stencil_back_func != func || + state_.stencil_back_ref != ref || + state_.stencil_back_mask != mask; + } + if (changed) { + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + state_.stencil_front_func = func; + state_.stencil_front_ref = ref; + state_.stencil_front_mask = mask; + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + state_.stencil_back_func = func; + state_.stencil_back_ref = ref; + state_.stencil_back_mask = mask; + } + glStencilFuncSeparate(face, func, ref, mask); + } return error::kNoError; } error::Error GLES2DecoderImpl::HandleStencilMask( uint32 immediate_data_size, const gles2::StencilMask& c) { GLuint mask = static_cast<GLuint>(c.mask); - state_.stencil_front_writemask = mask; - state_.stencil_back_writemask = mask; - clear_state_dirty_ = true; + if (state_.stencil_front_writemask != mask || + state_.stencil_back_writemask != mask) { + state_.stencil_front_writemask = mask; + state_.stencil_back_writemask = mask; + clear_state_dirty_ = true; + } return error::kNoError; } @@ -1563,13 +1655,22 @@ error::Error GLES2DecoderImpl::HandleStencilMaskSeparate( SetGLErrorInvalidEnum("glStencilMaskSeparate", face, "face"); return error::kNoError; } + bool changed = false; if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { - state_.stencil_front_writemask = mask; + changed |= state_.stencil_front_writemask != mask; } if (face == GL_BACK || face == GL_FRONT_AND_BACK) { - state_.stencil_back_writemask = mask; + changed |= state_.stencil_back_writemask != mask; + } + if (changed) { + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + state_.stencil_front_writemask = mask; + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + state_.stencil_back_writemask = mask; + } + clear_state_dirty_ = true; } - clear_state_dirty_ = true; return error::kNoError; } @@ -1590,13 +1691,20 @@ error::Error GLES2DecoderImpl::HandleStencilOp( SetGLErrorInvalidEnum("glStencilOp", zpass, "zpass"); return error::kNoError; } - state_.stencil_front_fail_op = fail; - state_.stencil_front_z_fail_op = zfail; - state_.stencil_front_z_pass_op = zpass; - state_.stencil_back_fail_op = fail; - state_.stencil_back_z_fail_op = zfail; - state_.stencil_back_z_pass_op = zpass; - glStencilOp(fail, zfail, zpass); + if (state_.stencil_front_fail_op != fail || + state_.stencil_front_z_fail_op != zfail || + state_.stencil_front_z_pass_op != zpass || + state_.stencil_back_fail_op != fail || + state_.stencil_back_z_fail_op != zfail || + state_.stencil_back_z_pass_op != zpass) { + state_.stencil_front_fail_op = fail; + state_.stencil_front_z_fail_op = zfail; + state_.stencil_front_z_pass_op = zpass; + state_.stencil_back_fail_op = fail; + state_.stencil_back_z_fail_op = zfail; + state_.stencil_back_z_pass_op = zpass; + glStencilOp(fail, zfail, zpass); + } return error::kNoError; } @@ -1622,17 +1730,30 @@ error::Error GLES2DecoderImpl::HandleStencilOpSeparate( SetGLErrorInvalidEnum("glStencilOpSeparate", zpass, "zpass"); return error::kNoError; } + bool changed = false; if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { - state_.stencil_front_fail_op = fail; - state_.stencil_front_z_fail_op = zfail; - state_.stencil_front_z_pass_op = zpass; + changed |= state_.stencil_front_fail_op != fail || + state_.stencil_front_z_fail_op != zfail || + state_.stencil_front_z_pass_op != zpass; } if (face == GL_BACK || face == GL_FRONT_AND_BACK) { - state_.stencil_back_fail_op = fail; - state_.stencil_back_z_fail_op = zfail; - state_.stencil_back_z_pass_op = zpass; + changed |= state_.stencil_back_fail_op != fail || + state_.stencil_back_z_fail_op != zfail || + state_.stencil_back_z_pass_op != zpass; + } + if (changed) { + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + state_.stencil_front_fail_op = fail; + state_.stencil_front_z_fail_op = zfail; + state_.stencil_front_z_pass_op = zpass; + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + state_.stencil_back_fail_op = fail; + state_.stencil_back_z_fail_op = zfail; + state_.stencil_back_z_pass_op = zpass; + } + glStencilOpSeparate(face, fail, zfail, zpass); } - glStencilOpSeparate(face, fail, zfail, zpass); return error::kNoError; } @@ -3000,8 +3121,11 @@ bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) { state_.enable_flags.sample_coverage = enabled; return true; case GL_SCISSOR_TEST: - state_.enable_flags.scissor_test = enabled; - return true; + if (state_.enable_flags.scissor_test != enabled) { + state_.enable_flags.scissor_test = enabled; + clear_state_dirty_ = true; + } + return false; case GL_STENCIL_TEST: if (state_.enable_flags.stencil_test != enabled) { state_.enable_flags.stencil_test = enabled; @@ -3013,635 +3137,5 @@ bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) { return false; } } - -bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) { - switch (cap) { - case GL_BLEND: - return state_.enable_flags.blend; - case GL_CULL_FACE: - return state_.enable_flags.cull_face; - case GL_DEPTH_TEST: - return state_.enable_flags.depth_test; - case GL_DITHER: - return state_.enable_flags.dither; - case GL_POLYGON_OFFSET_FILL: - return state_.enable_flags.polygon_offset_fill; - case GL_SAMPLE_ALPHA_TO_COVERAGE: - return state_.enable_flags.sample_alpha_to_coverage; - case GL_SAMPLE_COVERAGE: - return state_.enable_flags.sample_coverage; - case GL_SCISSOR_TEST: - return state_.enable_flags.scissor_test; - case GL_STENCIL_TEST: - return state_.enable_flags.stencil_test; - default: - NOTREACHED(); - return false; - } -} - -bool GLES2DecoderImpl::GetStateAsGLint( - GLenum pname, GLint* params, GLsizei* num_written) { - switch (pname) { - case GL_VIEWPORT: - *num_written = 4; - if (params) { - params[0] = static_cast<GLint>(state_.viewport_x); - params[1] = static_cast<GLint>(state_.viewport_y); - params[2] = static_cast<GLint>(state_.viewport_width); - params[3] = static_cast<GLint>(state_.viewport_height); - } - return true; - case GL_BLEND_SRC_RGB: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.blend_source_rgb); - } - return true; - case GL_BLEND_DST_RGB: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.blend_dest_rgb); - } - return true; - case GL_BLEND_SRC_ALPHA: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.blend_source_alpha); - } - return true; - case GL_BLEND_DST_ALPHA: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.blend_dest_alpha); - } - return true; - case GL_LINE_WIDTH: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.line_width); - } - return true; - case GL_BLEND_COLOR: - *num_written = 4; - if (params) { - params[0] = static_cast<GLint>(state_.blend_color_red); - params[1] = static_cast<GLint>(state_.blend_color_green); - params[2] = static_cast<GLint>(state_.blend_color_blue); - params[3] = static_cast<GLint>(state_.blend_color_alpha); - } - return true; - case GL_STENCIL_CLEAR_VALUE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_clear); - } - return true; - case GL_COLOR_WRITEMASK: - *num_written = 4; - if (params) { - params[0] = static_cast<GLint>(state_.color_mask_red); - params[1] = static_cast<GLint>(state_.color_mask_green); - params[2] = static_cast<GLint>(state_.color_mask_blue); - params[3] = static_cast<GLint>(state_.color_mask_alpha); - } - return true; - case GL_COLOR_CLEAR_VALUE: - *num_written = 4; - if (params) { - params[0] = static_cast<GLint>(state_.color_clear_red); - params[1] = static_cast<GLint>(state_.color_clear_green); - params[2] = static_cast<GLint>(state_.color_clear_blue); - params[3] = static_cast<GLint>(state_.color_clear_alpha); - } - return true; - case GL_DEPTH_RANGE: - *num_written = 2; - if (params) { - params[0] = static_cast<GLint>(state_.z_near); - params[1] = static_cast<GLint>(state_.z_far); - } - return true; - case GL_DEPTH_CLEAR_VALUE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.depth_clear); - } - return true; - case GL_STENCIL_FAIL: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_front_fail_op); - } - return true; - case GL_STENCIL_PASS_DEPTH_FAIL: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_front_z_fail_op); - } - return true; - case GL_STENCIL_PASS_DEPTH_PASS: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_front_z_pass_op); - } - return true; - case GL_STENCIL_BACK_FAIL: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_back_fail_op); - } - return true; - case GL_STENCIL_BACK_PASS_DEPTH_FAIL: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_back_z_fail_op); - } - return true; - case GL_STENCIL_BACK_PASS_DEPTH_PASS: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_back_z_pass_op); - } - return true; - case GL_SCISSOR_BOX: - *num_written = 4; - if (params) { - params[0] = static_cast<GLint>(state_.scissor_x); - params[1] = static_cast<GLint>(state_.scissor_y); - params[2] = static_cast<GLint>(state_.scissor_width); - params[3] = static_cast<GLint>(state_.scissor_height); - } - return true; - case GL_FRONT_FACE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.front_face); - } - return true; - case GL_SAMPLE_COVERAGE_VALUE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.sample_coverage_value); - } - return true; - case GL_SAMPLE_COVERAGE_INVERT: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.sample_coverage_invert); - } - return true; - case GL_POLYGON_OFFSET_FACTOR: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.polygon_offset_factor); - } - return true; - case GL_POLYGON_OFFSET_UNITS: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.polygon_offset_units); - } - return true; - case GL_CULL_FACE_MODE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.cull_mode); - } - return true; - case GL_DEPTH_FUNC: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.depth_func); - } - return true; - case GL_STENCIL_FUNC: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_front_func); - } - return true; - case GL_STENCIL_REF: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_front_ref); - } - return true; - case GL_STENCIL_VALUE_MASK: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_front_mask); - } - return true; - case GL_STENCIL_BACK_FUNC: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_back_func); - } - return true; - case GL_STENCIL_BACK_REF: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_back_ref); - } - return true; - case GL_STENCIL_BACK_VALUE_MASK: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_back_mask); - } - return true; - case GL_DEPTH_WRITEMASK: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.depth_mask); - } - return true; - case GL_BLEND_EQUATION_RGB: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.blend_equation_rgb); - } - return true; - case GL_BLEND_EQUATION_ALPHA: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.blend_equation_alpha); - } - return true; - case GL_STENCIL_WRITEMASK: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_front_writemask); - } - return true; - case GL_STENCIL_BACK_WRITEMASK: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.stencil_back_writemask); - } - return true; - case GL_BLEND: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.enable_flags.blend); - } - return true; - case GL_CULL_FACE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.enable_flags.cull_face); - } - return true; - case GL_DEPTH_TEST: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.enable_flags.depth_test); - } - return true; - case GL_DITHER: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.enable_flags.dither); - } - return true; - case GL_POLYGON_OFFSET_FILL: - *num_written = 1; - if (params) { - params[0] = - static_cast<GLint>(state_.enable_flags.polygon_offset_fill); - } - return true; - case GL_SAMPLE_ALPHA_TO_COVERAGE: - *num_written = 1; - if (params) { - params[0] = - static_cast<GLint>(state_.enable_flags.sample_alpha_to_coverage); - } - return true; - case GL_SAMPLE_COVERAGE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.enable_flags.sample_coverage); - } - return true; - case GL_SCISSOR_TEST: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.enable_flags.scissor_test); - } - return true; - case GL_STENCIL_TEST: - *num_written = 1; - if (params) { - params[0] = static_cast<GLint>(state_.enable_flags.stencil_test); - } - return true; - default: - return false; - } -} - -bool GLES2DecoderImpl::GetStateAsGLfloat( - GLenum pname, GLfloat* params, GLsizei* num_written) { - switch (pname) { - case GL_VIEWPORT: - *num_written = 4; - if (params) { - params[0] = static_cast<GLfloat>(state_.viewport_x); - params[1] = static_cast<GLfloat>(state_.viewport_y); - params[2] = static_cast<GLfloat>(state_.viewport_width); - params[3] = static_cast<GLfloat>(state_.viewport_height); - } - return true; - case GL_BLEND_SRC_RGB: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.blend_source_rgb); - } - return true; - case GL_BLEND_DST_RGB: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.blend_dest_rgb); - } - return true; - case GL_BLEND_SRC_ALPHA: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.blend_source_alpha); - } - return true; - case GL_BLEND_DST_ALPHA: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.blend_dest_alpha); - } - return true; - case GL_LINE_WIDTH: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.line_width); - } - return true; - case GL_BLEND_COLOR: - *num_written = 4; - if (params) { - params[0] = static_cast<GLfloat>(state_.blend_color_red); - params[1] = static_cast<GLfloat>(state_.blend_color_green); - params[2] = static_cast<GLfloat>(state_.blend_color_blue); - params[3] = static_cast<GLfloat>(state_.blend_color_alpha); - } - return true; - case GL_STENCIL_CLEAR_VALUE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_clear); - } - return true; - case GL_COLOR_WRITEMASK: - *num_written = 4; - if (params) { - params[0] = static_cast<GLfloat>(state_.color_mask_red); - params[1] = static_cast<GLfloat>(state_.color_mask_green); - params[2] = static_cast<GLfloat>(state_.color_mask_blue); - params[3] = static_cast<GLfloat>(state_.color_mask_alpha); - } - return true; - case GL_COLOR_CLEAR_VALUE: - *num_written = 4; - if (params) { - params[0] = static_cast<GLfloat>(state_.color_clear_red); - params[1] = static_cast<GLfloat>(state_.color_clear_green); - params[2] = static_cast<GLfloat>(state_.color_clear_blue); - params[3] = static_cast<GLfloat>(state_.color_clear_alpha); - } - return true; - case GL_DEPTH_RANGE: - *num_written = 2; - if (params) { - params[0] = static_cast<GLfloat>(state_.z_near); - params[1] = static_cast<GLfloat>(state_.z_far); - } - return true; - case GL_DEPTH_CLEAR_VALUE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.depth_clear); - } - return true; - case GL_STENCIL_FAIL: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_front_fail_op); - } - return true; - case GL_STENCIL_PASS_DEPTH_FAIL: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_front_z_fail_op); - } - return true; - case GL_STENCIL_PASS_DEPTH_PASS: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_front_z_pass_op); - } - return true; - case GL_STENCIL_BACK_FAIL: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_back_fail_op); - } - return true; - case GL_STENCIL_BACK_PASS_DEPTH_FAIL: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_back_z_fail_op); - } - return true; - case GL_STENCIL_BACK_PASS_DEPTH_PASS: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_back_z_pass_op); - } - return true; - case GL_SCISSOR_BOX: - *num_written = 4; - if (params) { - params[0] = static_cast<GLfloat>(state_.scissor_x); - params[1] = static_cast<GLfloat>(state_.scissor_y); - params[2] = static_cast<GLfloat>(state_.scissor_width); - params[3] = static_cast<GLfloat>(state_.scissor_height); - } - return true; - case GL_FRONT_FACE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.front_face); - } - return true; - case GL_SAMPLE_COVERAGE_VALUE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.sample_coverage_value); - } - return true; - case GL_SAMPLE_COVERAGE_INVERT: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.sample_coverage_invert); - } - return true; - case GL_POLYGON_OFFSET_FACTOR: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.polygon_offset_factor); - } - return true; - case GL_POLYGON_OFFSET_UNITS: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.polygon_offset_units); - } - return true; - case GL_CULL_FACE_MODE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.cull_mode); - } - return true; - case GL_DEPTH_FUNC: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.depth_func); - } - return true; - case GL_STENCIL_FUNC: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_front_func); - } - return true; - case GL_STENCIL_REF: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_front_ref); - } - return true; - case GL_STENCIL_VALUE_MASK: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_front_mask); - } - return true; - case GL_STENCIL_BACK_FUNC: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_back_func); - } - return true; - case GL_STENCIL_BACK_REF: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_back_ref); - } - return true; - case GL_STENCIL_BACK_VALUE_MASK: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_back_mask); - } - return true; - case GL_DEPTH_WRITEMASK: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.depth_mask); - } - return true; - case GL_BLEND_EQUATION_RGB: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.blend_equation_rgb); - } - return true; - case GL_BLEND_EQUATION_ALPHA: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.blend_equation_alpha); - } - return true; - case GL_STENCIL_WRITEMASK: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_front_writemask); - } - return true; - case GL_STENCIL_BACK_WRITEMASK: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.stencil_back_writemask); - } - return true; - case GL_BLEND: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.enable_flags.blend); - } - return true; - case GL_CULL_FACE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.enable_flags.cull_face); - } - return true; - case GL_DEPTH_TEST: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.enable_flags.depth_test); - } - return true; - case GL_DITHER: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.enable_flags.dither); - } - return true; - case GL_POLYGON_OFFSET_FILL: - *num_written = 1; - if (params) { - params[0] = - static_cast<GLfloat>(state_.enable_flags.polygon_offset_fill); - } - return true; - case GL_SAMPLE_ALPHA_TO_COVERAGE: - *num_written = 1; - if (params) { - params[0] = - static_cast<GLfloat>(state_.enable_flags.sample_alpha_to_coverage); - } - return true; - case GL_SAMPLE_COVERAGE: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.enable_flags.sample_coverage); - } - return true; - case GL_SCISSOR_TEST: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.enable_flags.scissor_test); - } - return true; - case GL_STENCIL_TEST: - *num_written = 1; - if (params) { - params[0] = static_cast<GLfloat>(state_.enable_flags.stencil_test); - } - return true; - default: - return false; - } -} #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index b698bf9..cee68f4 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -3293,9 +3293,6 @@ TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearColor) { EXPECT_CALL(*gl_, ClearColor(0.1f, 0.2f, 0.3f, 0.4f)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, Enable(GL_SCISSOR_TEST)) - .Times(1) - .RetiresOnSaturation(); EXPECT_CALL(*gl_, GetError()) .WillOnce(Return(GL_NO_ERROR)) .RetiresOnSaturation(); 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 8e2a919..7e817667 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 @@ -175,10 +175,10 @@ TEST_F(GLES2DecoderTest1, BlendColorValidArgs) { } TEST_F(GLES2DecoderTest1, BlendEquationValidArgs) { - EXPECT_CALL(*gl_, BlendEquation(GL_FUNC_ADD)); + EXPECT_CALL(*gl_, BlendEquation(GL_FUNC_SUBTRACT)); SpecializedSetup<BlendEquation, 0>(true); BlendEquation cmd; - cmd.Init(GL_FUNC_ADD); + cmd.Init(GL_FUNC_SUBTRACT); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -202,10 +202,10 @@ TEST_F(GLES2DecoderTest1, BlendEquationInvalidArgs0_1) { } TEST_F(GLES2DecoderTest1, BlendEquationSeparateValidArgs) { - EXPECT_CALL(*gl_, BlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD)); + EXPECT_CALL(*gl_, BlendEquationSeparate(GL_FUNC_SUBTRACT, GL_FUNC_ADD)); SpecializedSetup<BlendEquationSeparate, 0>(true); BlendEquationSeparate cmd; - cmd.Init(GL_FUNC_ADD, GL_FUNC_ADD); + cmd.Init(GL_FUNC_SUBTRACT, GL_FUNC_ADD); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -232,7 +232,7 @@ TEST_F(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs1_0) { EXPECT_CALL(*gl_, BlendEquationSeparate(_, _)).Times(0); SpecializedSetup<BlendEquationSeparate, 0>(false); BlendEquationSeparate cmd; - cmd.Init(GL_FUNC_ADD, GL_MIN); + cmd.Init(GL_FUNC_SUBTRACT, GL_MIN); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -241,7 +241,7 @@ TEST_F(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs1_1) { EXPECT_CALL(*gl_, BlendEquationSeparate(_, _)).Times(0); SpecializedSetup<BlendEquationSeparate, 0>(false); BlendEquationSeparate cmd; - cmd.Init(GL_FUNC_ADD, GL_MAX); + cmd.Init(GL_FUNC_SUBTRACT, GL_MAX); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -321,10 +321,10 @@ TEST_F(GLES2DecoderTest1, ClearColorValidArgs) { } TEST_F(GLES2DecoderTest1, ClearDepthfValidArgs) { - EXPECT_CALL(*gl_, ClearDepth(1)); + EXPECT_CALL(*gl_, ClearDepth(0.5f)); SpecializedSetup<ClearDepthf, 0>(true); ClearDepthf cmd; - cmd.Init(1); + cmd.Init(0.5f); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } 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 173f515..4be5c97 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 @@ -215,10 +215,10 @@ TEST_F(GLES2DecoderTest2, IsTextureInvalidArgsBadSharedMemoryId) { } TEST_F(GLES2DecoderTest2, LineWidthValidArgs) { - EXPECT_CALL(*gl_, LineWidth(1)); + EXPECT_CALL(*gl_, LineWidth(0.5f)); SpecializedSetup<LineWidth, 0>(true); LineWidth cmd; - cmd.Init(1); + cmd.Init(0.5f); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -359,19 +359,19 @@ TEST_F(GLES2DecoderTest2, StencilMaskSeparateValidArgs) { } TEST_F(GLES2DecoderTest2, StencilOpValidArgs) { - EXPECT_CALL(*gl_, StencilOp(GL_KEEP, GL_KEEP, GL_KEEP)); + EXPECT_CALL(*gl_, StencilOp(GL_KEEP, GL_INCR, GL_KEEP)); SpecializedSetup<StencilOp, 0>(true); StencilOp cmd; - cmd.Init(GL_KEEP, GL_KEEP, GL_KEEP); + cmd.Init(GL_KEEP, GL_INCR, GL_KEEP); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } TEST_F(GLES2DecoderTest2, StencilOpSeparateValidArgs) { - EXPECT_CALL(*gl_, StencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP)); + EXPECT_CALL(*gl_, StencilOpSeparate(GL_FRONT, GL_INCR, GL_KEEP, GL_KEEP)); SpecializedSetup<StencilOpSeparate, 0>(true); StencilOpSeparate cmd; - cmd.Init(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP); + cmd.Init(GL_FRONT, GL_INCR, GL_KEEP, GL_KEEP); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } diff --git a/gpu/gpu_common.gypi b/gpu/gpu_common.gypi index 24c7e4d..f6dd581 100644 --- a/gpu/gpu_common.gypi +++ b/gpu/gpu_common.gypi @@ -19,6 +19,10 @@ # with without support for client side arrays and once with for pepper and # the OpenGL ES 2.0 compliant for the conformance tests. 'gles2_implementation_source_files': [ + 'command_buffer/client/client_context_state.h', + 'command_buffer/client/client_context_state.cc', + 'command_buffer/client/client_context_state_autogen.h', + 'command_buffer/client/client_context_state_impl_autogen.h', 'command_buffer/client/gles2_impl_export.h', 'command_buffer/client/gles2_implementation_autogen.h', 'command_buffer/client/gles2_implementation.cc', |