diff options
author | Andras Becsi <andras.becsi@digia.com> | 2014-03-18 13:16:26 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-03-20 15:55:39 +0100 |
commit | 3f0f86b0caed75241fa71c95a5d73bc0164348c5 (patch) | |
tree | 92b9fb00f2e9e90b0be2262093876d4f43b6cd13 /chromium/gpu/command_buffer | |
parent | e90d7c4b152c56919d963987e2503f9909a666d2 (diff) | |
download | qtwebengine-chromium-3f0f86b0caed75241fa71c95a5d73bc0164348c5.tar.gz |
Update to new stable branch 1750
This also includes an updated ninja and chromium dependencies
needed on Windows.
Change-Id: Icd597d80ed3fa4425933c9f1334c3c2e31291c42
Reviewed-by: Zoltan Arvai <zarvai@inf.u-szeged.hu>
Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
Diffstat (limited to 'chromium/gpu/command_buffer')
120 files changed, 3655 insertions, 3360 deletions
diff --git a/chromium/gpu/command_buffer/OWNERS b/chromium/gpu/command_buffer/OWNERS index 7ef33ed2f58..bb8ea76f760 100644 --- a/chromium/gpu/command_buffer/OWNERS +++ b/chromium/gpu/command_buffer/OWNERS @@ -1,5 +1,4 @@ piman@chromium.org -apatrick@chromium.org jbauman@chromium.org bajones@chromium.org -zmo@chromium.org
\ No newline at end of file +zmo@chromium.org diff --git a/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py b/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py index f4c7e5b7367..0f2e49a31f1 100755 --- a/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -1212,6 +1212,10 @@ _PEPPER_INTERFACES = [ # valid_args: A dictionary of argument indices to args to use in unit tests # when they can not be automatically determined. # pepper_interface: The pepper interface that is used for this extension +# pepper_args: A string representing the argument list (what would appear in +# C/C++ between the parentheses for the function declaration) +# that the Pepper API expects for this function. Use this only if +# the stable Pepper API differs from the GLES2 argument list. # invalid_test: False if no invalid test needed. # shadowed: True = the value is shadowed so no glGetXXX call will be made. # first_element_only: For PUT types, True if only the first element of an @@ -1226,7 +1230,12 @@ _FUNCTION_INFO = { 'client_test': False, }, 'AttachShader': {'decoder_func': 'DoAttachShader'}, - 'BindAttribLocation': {'type': 'GLchar', 'bucket': True, 'needs_size': True}, + 'BindAttribLocation': { + 'type': 'GLchar', + 'bucket': True, + 'needs_size': True, + 'immediate': False, + }, 'BindBuffer': { 'type': 'Bind', 'decoder_func': 'DoBindBuffer', @@ -1251,8 +1260,8 @@ _FUNCTION_INFO = { # TODO(gman): remove this once client side caching works. 'client_test': False, }, - 'BlitFramebufferEXT': { - 'decoder_func': 'DoBlitFramebufferEXT', + 'BlitFramebufferCHROMIUM': { + 'decoder_func': 'DoBlitFramebufferCHROMIUM', 'unit_test': False, 'extension': True, 'pepper_interface': 'FramebufferBlit', @@ -1261,13 +1270,14 @@ _FUNCTION_INFO = { }, 'BufferData': { 'type': 'Manual', - 'immediate': True, + 'immediate': False, 'client_test': False, }, 'BufferSubData': { 'type': 'Data', 'client_test': False, 'decoder_func': 'DoBufferSubData', + 'immediate': False, }, 'CheckFramebufferStatus': { 'type': 'Is', @@ -1326,13 +1336,14 @@ _FUNCTION_INFO = { 'CompileShader': {'decoder_func': 'DoCompileShader', 'unit_test': False}, 'CompressedTexImage2D': { 'type': 'Manual', - 'immediate': True, + 'immediate': False, 'bucket': True, }, 'CompressedTexSubImage2D': { 'type': 'Data', 'bucket': True, 'decoder_func': 'DoCompressedTexSubImage2D', + 'immediate': False, }, 'CopyTexImage2D': { 'decoder_func': 'DoCopyTexImage2D', @@ -1355,7 +1366,7 @@ _FUNCTION_INFO = { }, 'DestroyImageCHROMIUM': { 'type': 'Manual', - 'immediate': True, + 'immediate': False, 'client_test': False, 'gen_cmd': False, 'extension': True, @@ -1555,11 +1566,9 @@ _FUNCTION_INFO = { 'resource_types': 'Buffers', }, 'GenMailboxCHROMIUM': { - 'type': 'Manual', - 'cmd_args': 'GLuint bucket_id', - 'result': ['SizedResult<GLint>'], - 'client_test': False, - 'unit_test': False, + 'type': 'HandWritten', + 'immediate': False, + 'impl_func': False, 'extension': True, 'chromium': True, }, @@ -1621,12 +1630,13 @@ _FUNCTION_INFO = { }, 'GetAttribLocation': { 'type': 'HandWritten', - 'immediate': True, + 'immediate': False, 'bucket': True, 'needs_size': True, 'cmd_args': 'GLidProgram program, const char* name, NonImmediate GLint* location', 'result': ['GLint'], + 'error_return': -1, # http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml }, 'GetBooleanv': { 'type': 'GETn', @@ -1772,12 +1782,13 @@ _FUNCTION_INFO = { }, 'GetUniformLocation': { 'type': 'HandWritten', - 'immediate': True, + 'immediate': False, 'bucket': True, 'needs_size': True, 'cmd_args': 'GLidProgram program, const char* name, NonImmediate GLint* location', 'result': ['GLint'], + 'error_return': -1, # http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformLocation.xml }, 'GetVertexAttribfv': { 'type': 'GETn', @@ -1890,13 +1901,24 @@ _FUNCTION_INFO = { 'gl_test_func': 'glRenderbufferStorageEXT', 'expectation': False, }, + 'RenderbufferStorageMultisampleCHROMIUM': { + 'cmd_comment': + '// GL_CHROMIUM_framebuffer_multisample\n', + 'decoder_func': 'DoRenderbufferStorageMultisampleCHROMIUM', + 'gl_test_func': 'glRenderbufferStorageMultisampleCHROMIUM', + 'expectation': False, + 'unit_test': False, + 'extension': True, + 'pepper_interface': 'FramebufferMultisample', + }, 'RenderbufferStorageMultisampleEXT': { - 'decoder_func': 'DoRenderbufferStorageMultisample', + 'cmd_comment': + '// GL_EXT_multisampled_render_to_texture\n', + 'decoder_func': 'DoRenderbufferStorageMultisampleEXT', 'gl_test_func': 'glRenderbufferStorageMultisampleEXT', 'expectation': False, 'unit_test': False, 'extension': True, - 'pepper_interface': 'FramebufferMultisample', }, 'ReadPixels': { 'cmd_comment': @@ -1935,12 +1957,14 @@ _FUNCTION_INFO = { }, 'ShaderSource': { 'type': 'Manual', - 'immediate': True, + 'immediate': False, 'bucket': True, 'needs_size': True, 'client_test': False, 'cmd_args': 'GLuint shader, const char* data', + 'pepper_args': + 'GLuint shader, GLsizei count, const char** str, const GLint* length', }, 'StencilMask': { 'type': 'StateSetFrontBack', @@ -1963,7 +1987,7 @@ _FUNCTION_INFO = { }, 'TexImage2D': { 'type': 'Manual', - 'immediate': True, + 'immediate': False, 'client_test': False, }, 'TexParameterf': { @@ -1999,7 +2023,7 @@ _FUNCTION_INFO = { }, 'TexSubImage2D': { 'type': 'Manual', - 'immediate': True, + 'immediate': False, 'client_test': False, 'cmd_args': 'GLenumTextureTarget target, GLint level, ' 'GLint xoffset, GLint yoffset, ' @@ -2305,28 +2329,34 @@ _FUNCTION_INFO = { }, 'BindUniformLocationCHROMIUM': { 'type': 'GLchar', + 'extension': True, 'bucket': True, 'needs_size': True, 'gl_test_func': 'DoBindUniformLocationCHROMIUM', + 'immediate': False, }, 'InsertEventMarkerEXT': { 'type': 'GLcharN', 'decoder_func': 'DoInsertEventMarkerEXT', 'expectation': False, + 'extension': True, }, 'PushGroupMarkerEXT': { 'type': 'GLcharN', 'decoder_func': 'DoPushGroupMarkerEXT', 'expectation': False, + 'extension': True, }, 'PopGroupMarkerEXT': { 'decoder_func': 'DoPopGroupMarkerEXT', 'expectation': False, + 'extension': True, 'impl_func': False, }, 'GenVertexArraysOES': { 'type': 'GENn', + 'extension': True, 'gl_test_func': 'glGenVertexArraysOES', 'resource_type': 'VertexArray', 'resource_types': 'VertexArrays', @@ -2334,6 +2364,7 @@ _FUNCTION_INFO = { }, 'BindVertexArrayOES': { 'type': 'Bind', + 'extension': True, 'gl_test_func': 'glBindVertexArrayOES', 'decoder_func': 'DoBindVertexArrayOES', 'gen_func': 'GenVertexArraysOES', @@ -2342,6 +2373,7 @@ _FUNCTION_INFO = { }, 'DeleteVertexArraysOES': { 'type': 'DELn', + 'extension': True, 'gl_test_func': 'glDeleteVertexArraysOES', 'resource_type': 'VertexArray', 'resource_types': 'VertexArrays', @@ -2349,6 +2381,7 @@ _FUNCTION_INFO = { }, 'IsVertexArrayOES': { 'type': 'Is', + 'extension': True, 'gl_test_func': 'glIsVertexArrayOES', 'decoder_func': 'DoIsVertexArrayOES', 'expectation': False, @@ -2448,6 +2481,12 @@ _FUNCTION_INFO = { 'extension': True, 'chromium': True, }, + 'DiscardBackbufferCHROMIUM': { + 'type': 'Custom', + 'impl_func': True, + 'extension': True, + 'chromium': True, + }, } @@ -2837,17 +2876,18 @@ COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d, def WriteHandlerDeferReadWrite(self, func, file): """Writes the code to handle deferring reads or writes.""" - defer_reads = func.GetInfo('defer_reads') defer_draws = func.GetInfo('defer_draws') - conditions = [] + defer_reads = func.GetInfo('defer_reads') + if defer_draws or defer_reads: + file.Write(" error::Error error;\n") if defer_draws: - conditions.append('ShouldDeferDraws()'); + file.Write(" error = WillAccessBoundFramebufferForDraw();\n") + file.Write(" if (error != error::kNoError)\n") + file.Write(" return error;\n") if defer_reads: - conditions.append('ShouldDeferReads()'); - if not conditions: - return - file.Write(" if (%s)\n" % ' || '.join(conditions)) - file.Write(" return error::kDeferCommandUntilLater;\n") + file.Write(" error = WillAccessBoundFramebufferForRead();\n") + file.Write(" if (error != error::kNoError)\n") + file.Write(" return error;\n") def WriteValidUnitTest(self, func, file, test, extra = {}): """Writes a valid unit test.""" @@ -3583,10 +3623,7 @@ class ManualHandler(CustomHandler): def WriteImmediateCmdGetTotalSize(self, func, file): """Overrriden from TypeHandler.""" # TODO(gman): Move this data to _FUNCTION_INFO? - if func.name == 'ShaderSourceImmediate': - file.Write(" uint32 total_size = ComputeSize(_data_size);\n") - else: - CustomHandler.WriteImmediateCmdGetTotalSize(self, func, file) + CustomHandler.WriteImmediateCmdGetTotalSize(self, func, file) class DataHandler(TypeHandler): @@ -3629,39 +3666,10 @@ class DataHandler(TypeHandler): def WriteImmediateCmdGetTotalSize(self, func, file): """Overrriden from TypeHandler.""" - # TODO(gman): Move this data to _FUNCTION_INFO? - if func.name == 'BufferDataImmediate': - file.Write(" uint32 total_size = ComputeSize(_size);\n") - elif func.name == 'BufferSubDataImmediate': - file.Write(" uint32 total_size = ComputeSize(_size);\n") - elif func.name == 'CompressedTexImage2DImmediate': - file.Write(" uint32 total_size = ComputeSize(_imageSize);\n") - elif func.name == 'CompressedTexSubImage2DImmediate': - file.Write(" uint32 total_size = ComputeSize(_imageSize);\n") - elif func.name == 'TexImage2DImmediate': - file.Write( - " uint32 total_size = 0; // TODO(gman): get correct size\n") - elif func.name == 'TexSubImage2DImmediate': - file.Write( - " uint32 total_size = 0; // TODO(gman): get correct size\n") + pass def WriteImmediateCmdSizeTest(self, func, file): """Overrriden from TypeHandler.""" - # TODO(gman): Move this data to _FUNCTION_INFO? - if func.name == 'BufferDataImmediate': - file.Write(" uint32 total_size = cmd.ComputeSize(cmd.size);\n") - elif func.name == 'BufferSubDataImmediate': - file.Write(" uint32 total_size = cmd.ComputeSize(cmd.size);\n") - elif func.name == 'CompressedTexImage2DImmediate': - file.Write(" uint32 total_size = cmd.ComputeSize(cmd.imageSize);\n") - elif func.name == 'CompressedTexSubImage2DImmediate': - file.Write(" uint32 total_size = cmd.ComputeSize(cmd.imageSize);\n") - elif func.name == 'TexImage2DImmediate': - file.Write( - " uint32 total_size = 0; // TODO(gman): get correct size\n") - elif func.name == 'TexSubImage2DImmediate': - file.Write( - " uint32 total_size = 0; // TODO(gman): get correct size\n") file.Write(" EXPECT_EQ(sizeof(cmd), total_size);\n") def WriteImmediateCmdInit(self, func, file): @@ -4361,7 +4369,7 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs) { """ % func.GetOriginalArgs()[1].name) file.Write(""" GPU_CLIENT_DCHECK_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { - GPU_DCHECK(%s[i] != 0); + DCHECK(%s[i] != 0); } }); """ % func.GetOriginalArgs()[1].name) @@ -6394,7 +6402,7 @@ class Function(object): """Gets the last original argument to this function.""" return self.original_args[len(self.original_args) - 1] - def __GetArgList(self, arg_string, add_comma): + def __MaybePrependComma(self, arg_string, add_comma): """Adds a comma if arg_string is not empty and add_comma is true.""" comma = "" if add_comma and len(arg_string): @@ -6402,46 +6410,53 @@ class Function(object): return "%s%s" % (comma, arg_string) def MakeTypedOriginalArgString(self, prefix, add_comma = False): - """Gets a list of arguments as they arg in GL.""" + """Gets a list of arguments as they are in GL.""" args = self.GetOriginalArgs() arg_string = ", ".join( ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args]) - return self.__GetArgList(arg_string, add_comma) + return self.__MaybePrependComma(arg_string, add_comma) def MakeOriginalArgString(self, prefix, add_comma = False, separator = ", "): """Gets the list of arguments as they are in GL.""" args = self.GetOriginalArgs() arg_string = separator.join( ["%s%s" % (prefix, arg.name) for arg in args]) - return self.__GetArgList(arg_string, add_comma) + return self.__MaybePrependComma(arg_string, add_comma) + + def MakeTypedPepperArgString(self, prefix): + """Gets a list of arguments as they need to be for Pepper.""" + if self.GetInfo("pepper_args"): + return self.GetInfo("pepper_args") + else: + return self.MakeTypedOriginalArgString(prefix, False) def MakeTypedCmdArgString(self, prefix, add_comma = False): """Gets a typed list of arguments as they need to be for command buffers.""" args = self.GetCmdArgs() arg_string = ", ".join( ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args]) - return self.__GetArgList(arg_string, add_comma) + return self.__MaybePrependComma(arg_string, add_comma) def MakeCmdArgString(self, prefix, add_comma = False): """Gets the list of arguments as they need to be for command buffers.""" args = self.GetCmdArgs() arg_string = ", ".join( ["%s%s" % (prefix, arg.name) for arg in args]) - return self.__GetArgList(arg_string, add_comma) + return self.__MaybePrependComma(arg_string, add_comma) def MakeTypedInitString(self, prefix, add_comma = False): """Gets a typed list of arguments as they need to be for cmd Init/Set.""" args = self.GetInitArgs() arg_string = ", ".join( ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args]) - return self.__GetArgList(arg_string, add_comma) + return self.__MaybePrependComma(arg_string, add_comma) def MakeInitString(self, prefix, add_comma = False): """Gets the list of arguments as they need to be for cmd Init/Set.""" args = self.GetInitArgs() arg_string = ", ".join( ["%s%s" % (prefix, arg.name) for arg in args]) - return self.__GetArgList(arg_string, add_comma) + return self.__MaybePrependComma(arg_string, add_comma) def MakeLogArgString(self): """Makes a string of the arguments for the LOG macros""" @@ -7167,7 +7182,7 @@ void ContextState::InitState() const { file.Write(" case GL_%s:\n" % capability['name'].upper()) file.Write(" return enable_flags.%s;\n" % capability['name']) file.Write(""" default: - GPU_NOTREACHED(); + NOTREACHED(); return false; } } @@ -7593,7 +7608,7 @@ const size_t GLES2Util::enum_to_string_table_len_ = if not func.InPepperInterface(interface): continue - original_arg = func.MakeTypedOriginalArgString("") + original_arg = func.MakeTypedPepperArgString("") context_arg = "PP_Resource context" if len(original_arg): arg = context_arg + ", " + original_arg @@ -7621,31 +7636,49 @@ const size_t GLES2Util::enum_to_string_table_len_ = file.Write("namespace ppapi {\n\n") file.Write("namespace {\n\n") - file.Write("gpu::gles2::GLES2Implementation*" - " GetGLES(PP_Resource context) {\n") - file.Write(" thunk::EnterResource<thunk::PPB_Graphics3D_API>" - " enter_g3d(context, false);\n") - file.Write(" DCHECK(enter_g3d.succeeded());\n") - file.Write(" return static_cast<PPB_Graphics3D_Shared*>" - "(enter_g3d.object())->gles2_impl();\n") - file.Write("}\n\n") + file.Write("typedef thunk::EnterResource<thunk::PPB_Graphics3D_API>" + " Enter3D;\n\n") + + file.Write("gpu::gles2::GLES2Implementation* ToGles2Impl(Enter3D*" + " enter) {\n") + file.Write(" DCHECK(enter);\n") + file.Write(" DCHECK(enter->succeeded());\n") + file.Write(" return static_cast<PPB_Graphics3D_Shared*>(enter->object())->" + "gles2_impl();\n"); + file.Write("}\n\n"); for func in self.original_functions: if not func.InAnyPepperExtension(): continue - original_arg = func.MakeTypedOriginalArgString("") + original_arg = func.MakeTypedPepperArgString("") context_arg = "PP_Resource context_id" if len(original_arg): arg = context_arg + ", " + original_arg else: arg = context_arg file.Write("%s %s(%s) {\n" % (func.return_type, func.name, arg)) + file.Write(" Enter3D enter(context_id, true);\n") + file.Write(" if (enter.succeeded()) {\n") return_str = "" if func.return_type == "void" else "return " - file.Write(" %sGetGLES(context_id)->%s(%s);\n" % + file.Write(" %sToGles2Impl(&enter)->%s(%s);\n" % (return_str, func.original_name, func.MakeOriginalArgString(""))) + file.Write(" }") + if func.return_type == "void": + file.Write("\n") + else: + file.Write(" else {\n") + error_return = "0" + if func.GetInfo("error_return"): + error_return = func.GetInfo("error_return") + elif func.return_type == "GLboolean": + error_return = "GL_FALSE" + elif "*" in func.return_type: + error_return = "NULL" + file.Write(" return %s;\n" % error_return) + file.Write(" }\n") file.Write("}\n\n") file.Write("} // namespace\n") diff --git a/chromium/gpu/command_buffer/client/atomicops.cc b/chromium/gpu/command_buffer/client/atomicops.cc deleted file mode 100644 index c4d5cb1117c..00000000000 --- a/chromium/gpu/command_buffer/client/atomicops.cc +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gpu/command_buffer/client/atomicops.h" -#include "gpu/command_buffer/common/logging.h" - -#if !defined(__native_client__) -#include "base/atomicops.h" -#include "base/synchronization/lock.h" -#else -#include <pthread.h> -#endif - -namespace gpu { - -void MemoryBarrier() { -#if defined(__native_client__) - __sync_synchronize(); -#else - base::subtle::MemoryBarrier(); -#endif -} - -#if defined(__native_client__) - -class LockImpl { - public: - LockImpl() - : acquired_(false) { - pthread_mutex_init(&mutex_, NULL); - } - - ~LockImpl() { - pthread_mutex_destroy(&mutex_); - } - - void Acquire() { - pthread_mutex_lock(&mutex_); - acquired_ = true; - } - - void Release() { - GPU_DCHECK(acquired_); - acquired_ = false; - pthread_mutex_unlock(&mutex_); - } - - bool Try() { - bool acquired = pthread_mutex_trylock(&mutex_) == 0; - if (acquired) { - acquired_ = true; - } - return acquired; - } - - void AssertAcquired() const { - GPU_DCHECK(acquired_); - } - - private: - bool acquired_; - pthread_mutex_t mutex_; - - DISALLOW_COPY_AND_ASSIGN(LockImpl); -}; - -#else // !__native_client__ - -class LockImpl : public base::Lock { -}; - -#endif // !__native_client__ - -Lock::Lock() - : lock_(new LockImpl()) { -} - -Lock::~Lock() { -} - -void Lock::Acquire() { - lock_->Acquire(); -} - -void Lock::Release() { - lock_->Release(); -} - -bool Lock::Try() { - return lock_->Try(); -} - -void Lock::AssertAcquired() const { - return lock_->AssertAcquired(); -} - -} // namespace gpu - diff --git a/chromium/gpu/command_buffer/client/atomicops.h b/chromium/gpu/command_buffer/client/atomicops.h deleted file mode 100644 index 9e1628e0ad6..00000000000 --- a/chromium/gpu/command_buffer/client/atomicops.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_ATOMICOPS_H_ -#define GPU_COMMAND_BUFFER_CLIENT_ATOMICOPS_H_ - -#include "base/memory/scoped_ptr.h" -#include "gpu/command_buffer/common/types.h" -#include "gpu/gpu_export.h" - -namespace gpu { - -GPU_EXPORT void MemoryBarrier(); - -class LockImpl; -class GPU_EXPORT Lock { - public: - Lock(); - ~Lock(); - void Acquire(); - void Release(); - bool Try(); - void AssertAcquired() const; - - private: - scoped_ptr<LockImpl> lock_; - - DISALLOW_COPY_AND_ASSIGN(Lock); -}; - -// A helper class that acquires the given Lock while the AutoLock is in scope. -class GPU_EXPORT AutoLock { - public: - explicit AutoLock(Lock& lock) : lock_(lock) { - lock_.Acquire(); - } - - ~AutoLock() { - lock_.AssertAcquired(); - lock_.Release(); - } - - private: - Lock& lock_; - DISALLOW_COPY_AND_ASSIGN(AutoLock); -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_CLIENT_ATOMICOPS_H_ diff --git a/chromium/gpu/command_buffer/client/buffer_tracker.cc b/chromium/gpu/command_buffer/client/buffer_tracker.cc index f5ead5af08c..18cedb975d0 100644 --- a/chromium/gpu/command_buffer/client/buffer_tracker.cc +++ b/chromium/gpu/command_buffer/client/buffer_tracker.cc @@ -4,7 +4,6 @@ #include "gpu/command_buffer/client/buffer_tracker.h" -#include "gpu/command_buffer/client/atomicops.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" #include "gpu/command_buffer/client/mapped_memory.h" @@ -23,8 +22,8 @@ BufferTracker::~BufferTracker() { BufferTracker::Buffer* BufferTracker::CreateBuffer( GLuint id, GLsizeiptr size) { - GPU_DCHECK_NE(0u, id); - GPU_DCHECK_LE(0, size); + DCHECK_NE(0u, id); + DCHECK_LE(0, size); int32 shm_id = -1; uint32 shm_offset = 0; void* address = NULL; @@ -34,7 +33,7 @@ BufferTracker::Buffer* BufferTracker::CreateBuffer( Buffer* buffer = new Buffer(id, size, shm_id, shm_offset, address); std::pair<BufferMap::iterator, bool> result = buffers_.insert(std::make_pair(id, buffer)); - GPU_DCHECK(result.second); + DCHECK(result.second); return buffer; } diff --git a/chromium/gpu/command_buffer/client/buffer_tracker.h b/chromium/gpu/command_buffer/client/buffer_tracker.h index e61c50188af..3e50364317d 100644 --- a/chromium/gpu/command_buffer/client/buffer_tracker.h +++ b/chromium/gpu/command_buffer/client/buffer_tracker.h @@ -8,8 +8,8 @@ #include <GLES2/gl2.h> #include <queue> +#include "base/containers/hash_tables.h" #include "gles2_impl_export.h" -#include "gpu/command_buffer/client/hash_tables.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" namespace gpu { @@ -99,7 +99,7 @@ class GLES2_IMPL_EXPORT BufferTracker { void FreePendingToken(Buffer*, int32 token); private: - typedef gpu::hash_map<GLuint, Buffer*> BufferMap; + typedef base::hash_map<GLuint, Buffer*> BufferMap; MappedMemoryManager* mapped_memory_; BufferMap buffers_; diff --git a/chromium/gpu/command_buffer/client/client_context_state.cc b/chromium/gpu/command_buffer/client/client_context_state.cc index ecb33b6fa5b..9f4fbad3c61 100644 --- a/chromium/gpu/command_buffer/client/client_context_state.cc +++ b/chromium/gpu/command_buffer/client/client_context_state.cc @@ -3,7 +3,8 @@ // found in the LICENSE file. #include "gpu/command_buffer/client/client_context_state.h" -#include "gpu/command_buffer/common/logging.h" + +#include "base/logging.h" namespace gpu { namespace gles2 { diff --git a/chromium/gpu/command_buffer/client/client_test_helper.cc b/chromium/gpu/command_buffer/client/client_test_helper.cc index 31a91b20d6c..db191ce5eba 100644 --- a/chromium/gpu/command_buffer/client/client_test_helper.cc +++ b/chromium/gpu/command_buffer/client/client_test_helper.cc @@ -76,16 +76,16 @@ Buffer MockCommandBufferBase::CreateTransferBuffer(size_t size, int32* id) { } void MockCommandBufferBase::DestroyTransferBufferHelper(int32 id) { - GPU_DCHECK_GE(id, kTransferBufferBaseId); - GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); + DCHECK_GE(id, kTransferBufferBaseId); + DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); id -= kTransferBufferBaseId; transfer_buffers_[id].reset(); transfer_buffer_buffers_[id] = Buffer(); } Buffer MockCommandBufferBase::GetTransferBuffer(int32 id) { - GPU_DCHECK_GE(id, kTransferBufferBaseId); - GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); + DCHECK_GE(id, kTransferBufferBaseId); + DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); return transfer_buffer_buffers_[id - kTransferBufferBaseId]; } @@ -94,26 +94,21 @@ void MockCommandBufferBase::FlushHelper(int32 put_offset) { } void MockCommandBufferBase::SetToken(int32 token) { - GPU_NOTREACHED(); + NOTREACHED(); state_.token = token; } void MockCommandBufferBase::SetParseError(error::Error error) { - GPU_NOTREACHED(); + NOTREACHED(); state_.error = error; } void MockCommandBufferBase::SetContextLostReason( error::ContextLostReason reason) { - GPU_NOTREACHED(); + NOTREACHED(); state_.context_lost_reason = reason; } -uint32 MockCommandBufferBase::InsertSyncPoint() { - GPU_NOTREACHED(); - return 0; -} - // GCC requires these declarations, but MSVC requires they not be present #ifndef _MSC_VER const int32 MockCommandBufferBase::kTransferBufferBaseId; diff --git a/chromium/gpu/command_buffer/client/client_test_helper.h b/chromium/gpu/command_buffer/client/client_test_helper.h index e9d6c365fae..e071f5a7482 100644 --- a/chromium/gpu/command_buffer/client/client_test_helper.h +++ b/chromium/gpu/command_buffer/client/client_test_helper.h @@ -7,11 +7,12 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_CLIENT_TEST_HELPER_H_ #define GPU_COMMAND_BUFFER_CLIENT_CLIENT_TEST_HELPER_H_ +#include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/common/cmd_buffer_common.h" #include "gpu/command_buffer/common/command_buffer.h" -#include "gpu/command_buffer/common/compiler_specific.h" #include "gpu/command_buffer/common/gpu_control.h" +#include "gpu/command_buffer/common/gpu_memory_allocation.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -39,7 +40,6 @@ class MockCommandBufferBase : public CommandBuffer { virtual void SetToken(int32 token) OVERRIDE; virtual void SetParseError(error::Error error) OVERRIDE; virtual void SetContextLostReason(error::ContextLostReason reason) OVERRIDE; - virtual uint32 InsertSyncPoint() OVERRIDE; // Get's the Id of the next transfer buffer that will be returned // by CreateTransferBuffer. This is useful for testing expected ids. @@ -87,12 +87,24 @@ class MockClientGpuControl : public GpuControl { MockClientGpuControl(); virtual ~MockClientGpuControl(); + MOCK_METHOD0(GetCapabilities, Capabilities()); MOCK_METHOD4(CreateGpuMemoryBuffer, gfx::GpuMemoryBuffer*(size_t width, size_t height, unsigned internalformat, int32* id)); MOCK_METHOD1(DestroyGpuMemoryBuffer, void(int32 id)); + MOCK_METHOD2(GenerateMailboxNames, bool(unsigned num, + std::vector<gpu::Mailbox>* names)); + MOCK_METHOD0(InsertSyncPoint, uint32()); + MOCK_METHOD2(SignalSyncPoint, void(uint32 id, + const base::Closure& callback)); + MOCK_METHOD1(Echo, void(const base::Closure& callback)); + + MOCK_METHOD2(SignalQuery, void(uint32 query, const base::Closure& callback)); + MOCK_METHOD1(SetSurfaceVisible, void(bool visible)); + MOCK_METHOD1(SendManagedMemoryStats, + void(const ManagedMemoryStats& stats)); private: DISALLOW_COPY_AND_ASSIGN(MockClientGpuControl); diff --git a/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc b/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc index b83934ff5a7..11219ede664 100644 --- a/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc +++ b/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc @@ -5,15 +5,18 @@ // This file contains the implementation of the command buffer helper class. #include "gpu/command_buffer/client/cmd_buffer_helper.h" + +#include "base/logging.h" #include "gpu/command_buffer/common/command_buffer.h" #include "gpu/command_buffer/common/trace_event.h" namespace gpu { -namespace { const int kCommandsPerFlushCheck = 100; + +#if !defined(OS_ANDROID) const double kFlushDelay = 1.0 / (5.0 * 60.0); -} +#endif CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer) : command_buffer_(command_buffer), @@ -86,7 +89,7 @@ void CommandBufferHelper::FreeResources() { } void CommandBufferHelper::FreeRingBuffer() { - GPU_CHECK((put_ == get_offset()) || + CHECK((put_ == get_offset()) || error::IsError(command_buffer_->GetLastState().error)); FreeResources(); } @@ -129,7 +132,7 @@ bool CommandBufferHelper::Finish() { if (put_ == get_offset()) { return true; } - GPU_DCHECK(HaveRingBuffer()); + DCHECK(HaveRingBuffer()); do { // Do not loop forever if the flush fails, meaning the command buffer reader // has shutdown. @@ -149,7 +152,7 @@ int32 CommandBufferHelper::InsertToken() { if (!usable()) { return token_; } - GPU_DCHECK(HaveRingBuffer()); + DCHECK(HaveRingBuffer()); // Increment token as 31-bit integer. Negative values are used to signal an // error. token_ = (token_ + 1) & 0x7FFFFFFF; @@ -160,7 +163,7 @@ int32 CommandBufferHelper::InsertToken() { TRACE_EVENT0("gpu", "CommandBufferHelper::InsertToken(wrapped)"); // we wrapped Finish(); - GPU_DCHECK_EQ(token_, last_token_read()); + DCHECK_EQ(token_, last_token_read()); } } return token_; @@ -178,7 +181,7 @@ void CommandBufferHelper::WaitForToken(int32 token) { if (token > token_) return; // we wrapped while (last_token_read() < token) { if (get_offset() == put_) { - GPU_LOG(FATAL) << "Empty command buffer while waiting on a token."; + LOG(FATAL) << "Empty command buffer while waiting on a token."; return; } // Do not loop forever if the flush fails, meaning the command buffer reader @@ -198,14 +201,14 @@ void CommandBufferHelper::WaitForAvailableEntries(int32 count) { if (!usable()) { return; } - GPU_DCHECK(HaveRingBuffer()); - GPU_DCHECK(count < total_entry_count_); + DCHECK(HaveRingBuffer()); + DCHECK(count < total_entry_count_); if (put_ + count > total_entry_count_) { // There's not enough room between the current put and the end of the // buffer, so we need to wrap. We will add noops all the way to the end, // but we need to make sure get wraps first, actually that get is 1 or // more (since put will wrap to 0 after we add the noops). - GPU_DCHECK_LE(1, put_); + DCHECK_LE(1, put_); if (get_offset() > put_ || get_offset() == 0) { TRACE_EVENT0("gpu", "CommandBufferHelper::WaitForAvailableEntries"); while (get_offset() > put_ || get_offset() == 0) { @@ -261,12 +264,12 @@ CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) { if (!usable()) { return NULL; } - GPU_DCHECK(HaveRingBuffer()); + DCHECK(HaveRingBuffer()); ++commands_issued_; WaitForAvailableEntries(entries); CommandBufferEntry* space = &entries_[put_]; put_ += entries; - GPU_DCHECK_LE(put_, total_entry_count_); + DCHECK_LE(put_, total_entry_count_); if (put_ == total_entry_count_) { put_ = 0; } diff --git a/chromium/gpu/command_buffer/client/cmd_buffer_helper.h b/chromium/gpu/command_buffer/client/cmd_buffer_helper.h index e2639b3a264..a50dc7bfe4e 100644 --- a/chromium/gpu/command_buffer/client/cmd_buffer_helper.h +++ b/chromium/gpu/command_buffer/client/cmd_buffer_helper.h @@ -13,7 +13,6 @@ #include "gpu/command_buffer/common/cmd_buffer_common.h" #include "gpu/command_buffer/common/command_buffer.h" #include "gpu/command_buffer/common/constants.h" -#include "gpu/command_buffer/common/logging.h" #include "gpu/gpu_export.h" namespace gpu { diff --git a/chromium/gpu/command_buffer/client/context_support.h b/chromium/gpu/command_buffer/client/context_support.h new file mode 100644 index 00000000000..6a8972081ca --- /dev/null +++ b/chromium/gpu/command_buffer/client/context_support.h @@ -0,0 +1,43 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_CONTEXT_SUPPORT_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CONTEXT_SUPPORT_H_ + +#include "base/callback.h" +#include "ui/gfx/rect.h" + +namespace gpu { +struct ManagedMemoryStats; + +class ContextSupport { + public: + // Runs |callback| when a sync point is reached. + virtual void SignalSyncPoint(uint32 sync_point, + const base::Closure& callback) = 0; + + // Runs |callback| when a query created via glCreateQueryEXT() has cleared + // passed the glEndQueryEXT() point. + virtual void SignalQuery(uint32 query, const base::Closure& callback) = 0; + + // For onscreen contexts, indicates that the surface visibility has changed. + // Clients aren't expected to draw to an invisible surface. + virtual void SetSurfaceVisible(bool visible) = 0; + + virtual void SendManagedMemoryStats(const ManagedMemoryStats& stats) = 0; + + virtual void Swap() = 0; + virtual void PartialSwapBuffers(gfx::Rect sub_buffer) = 0; + + virtual void SetSwapBuffersCompleteCallback( + const base::Closure& callback) = 0; + + protected: + ContextSupport() {} + virtual ~ContextSupport() {} +}; + +} + +#endif // GPU_COMMAND_BUFFER_CLIENT_CONTEXT_SUPPORT_H_ diff --git a/chromium/gpu/command_buffer/client/fenced_allocator.cc b/chromium/gpu/command_buffer/client/fenced_allocator.cc index 02e891f665d..0e90bf385b4 100644 --- a/chromium/gpu/command_buffer/client/fenced_allocator.cc +++ b/chromium/gpu/command_buffer/client/fenced_allocator.cc @@ -49,8 +49,8 @@ FencedAllocator::~FencedAllocator() { } } // These checks are not valid if the service has crashed or lost the context. - // GPU_DCHECK_EQ(blocks_.size(), 1u); - // GPU_DCHECK_EQ(blocks_[0].state, FREE); + // DCHECK_EQ(blocks_.size(), 1u); + // DCHECK_EQ(blocks_[0].state, FREE); } // Looks for a non-allocated block that is big enough. Search in the FREE @@ -92,7 +92,7 @@ FencedAllocator::Offset FencedAllocator::Alloc(unsigned int size) { // necessary. void FencedAllocator::Free(FencedAllocator::Offset offset) { BlockIndex index = GetBlockByOffset(offset); - GPU_DCHECK_NE(blocks_[index].state, FREE); + DCHECK_NE(blocks_[index].state, FREE); Block &block = blocks_[index]; if (block.state == IN_USE) @@ -136,7 +136,7 @@ unsigned int FencedAllocator::GetLargestFreeOrPendingSize() { max_size = std::max(max_size, current_size); current_size = 0; } else { - GPU_DCHECK(block.state == FREE || block.state == FREE_PENDING_TOKEN); + DCHECK(block.state == FREE || block.state == FREE_PENDING_TOKEN); current_size += block.size; } } @@ -195,7 +195,7 @@ FencedAllocator::BlockIndex FencedAllocator::CollapseFreeBlock( FencedAllocator::BlockIndex FencedAllocator::WaitForTokenAndFreeBlock( BlockIndex index) { Block &block = blocks_[index]; - GPU_DCHECK_EQ(block.state, FREE_PENDING_TOKEN); + DCHECK_EQ(block.state, FREE_PENDING_TOKEN); helper_->WaitForToken(block.token); block.state = FREE; return CollapseFreeBlock(index); @@ -220,8 +220,8 @@ void FencedAllocator::FreeUnused() { FencedAllocator::Offset FencedAllocator::AllocInBlock(BlockIndex index, unsigned int size) { Block &block = blocks_[index]; - GPU_DCHECK_GE(block.size, size); - GPU_DCHECK_EQ(block.state, FREE); + DCHECK_GE(block.size, size); + DCHECK_EQ(block.state, FREE); Offset offset = block.offset; bytes_in_use_ += size; if (block.size == size) { @@ -241,7 +241,7 @@ FencedAllocator::BlockIndex FencedAllocator::GetBlockByOffset(Offset offset) { Block templ = { IN_USE, offset, 0, kUnusedToken }; Container::iterator it = std::lower_bound(blocks_.begin(), blocks_.end(), templ, OffsetCmp()); - GPU_DCHECK(it != blocks_.end() && it->offset == offset); + DCHECK(it != blocks_.end() && it->offset == offset); return it-blocks_.begin(); } diff --git a/chromium/gpu/command_buffer/client/fenced_allocator.h b/chromium/gpu/command_buffer/client/fenced_allocator.h index 71e6178e832..bb5c55170ab 100644 --- a/chromium/gpu/command_buffer/client/fenced_allocator.h +++ b/chromium/gpu/command_buffer/client/fenced_allocator.h @@ -9,7 +9,7 @@ #include <vector> -#include "gpu/command_buffer/common/logging.h" +#include "base/logging.h" #include "gpu/command_buffer/common/types.h" #include "gpu/gpu_export.h" @@ -187,7 +187,7 @@ class FencedAllocatorWrapper { // Parameters: // pointer: the pointer to the memory block to free. void Free(void *pointer) { - GPU_DCHECK(pointer); + DCHECK(pointer); allocator_.Free(GetOffset(pointer)); } @@ -198,7 +198,7 @@ class FencedAllocatorWrapper { // pointer: the pointer to the memory block to free. // token: the token value to wait for before re-using the memory. void FreePendingToken(void *pointer, int32 token) { - GPU_DCHECK(pointer); + DCHECK(pointer); allocator_.FreePendingToken(GetOffset(pointer), token); } diff --git a/chromium/gpu/command_buffer/client/gl_in_process_context.cc b/chromium/gpu/command_buffer/client/gl_in_process_context.cc index cf0c8a79ec6..1bd4c625457 100644 --- a/chromium/gpu/command_buffer/client/gl_in_process_context.cc +++ b/chromium/gpu/command_buffer/client/gl_in_process_context.cc @@ -62,10 +62,6 @@ class GLInProcessContextImpl // GLInProcessContext implementation: virtual void SetContextLostCallback(const base::Closure& callback) OVERRIDE; - virtual void SignalSyncPoint(unsigned sync_point, - const base::Closure& callback) OVERRIDE; - virtual void SignalQuery(unsigned query, const base::Closure& callback) - OVERRIDE; virtual gles2::GLES2Implementation* GetImplementation() OVERRIDE; #if defined(OS_ANDROID) @@ -75,8 +71,6 @@ class GLInProcessContextImpl private: void Destroy(); - void PollQueryCallbacks(); - void CallQueryCallback(size_t index); void OnContextLost(); void OnSignalSyncPoint(const base::Closure& callback); @@ -85,9 +79,6 @@ class GLInProcessContextImpl scoped_ptr<gles2::GLES2Implementation> gles2_implementation_; scoped_ptr<InProcessCommandBuffer> command_buffer_; - typedef std::pair<unsigned, base::Closure> QueryCallback; - std::vector<QueryCallback> query_callbacks_; - unsigned int share_group_id_; bool context_lost_; base::Closure context_lost_callback_; @@ -100,11 +91,6 @@ base::LazyInstance<base::Lock> g_all_shared_contexts_lock = base::LazyInstance<std::set<GLInProcessContextImpl*> > g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER; -size_t SharedContextCount() { - base::AutoLock lock(g_all_shared_contexts_lock.Get()); - return g_all_shared_contexts.Get().size(); -} - GLInProcessContextImpl::GLInProcessContextImpl() : share_group_id_(0), context_lost_(false) {} @@ -116,14 +102,6 @@ GLInProcessContextImpl::~GLInProcessContextImpl() { Destroy(); } -void GLInProcessContextImpl::SignalSyncPoint(unsigned sync_point, - const base::Closure& callback) { - DCHECK(!callback.is_null()); - base::Closure wrapped_callback = base::Bind( - &GLInProcessContextImpl::OnSignalSyncPoint, AsWeakPtr(), callback); - command_buffer_->SignalSyncPoint(sync_point, wrapped_callback); -} - gles2::GLES2Implementation* GLInProcessContextImpl::GetImplementation() { return gles2_implementation_.get(); } @@ -140,12 +118,6 @@ void GLInProcessContextImpl::OnContextLost() { } } -void GLInProcessContextImpl::OnSignalSyncPoint(const base::Closure& callback) { - // TODO: Should it always trigger callbacks? - if (!context_lost_) - callback.Run(); -} - bool GLInProcessContextImpl::Initialize( scoped_refptr<gfx::GLSurface> surface, bool is_offscreen, @@ -156,6 +128,9 @@ bool GLInProcessContextImpl::Initialize( gfx::GpuPreference gpu_preference) { DCHECK(size.width() >= 0 && size.height() >= 0); + // Changes to these values should also be copied to + // gpu/command_buffer/client/gl_in_process_context.cc and to + // content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h const int32 ALPHA_SIZE = 0x3021; const int32 BLUE_SIZE = 0x3022; const int32 GREEN_SIZE = 0x3023; @@ -166,6 +141,9 @@ bool GLInProcessContextImpl::Initialize( const int32 SAMPLE_BUFFERS = 0x3032; const int32 NONE = 0x3038; + // Chromium-specific attributes + const int32 FAIL_IF_MAJOR_PERF_CAVEAT = 0x10002; + std::vector<int32> attrib_vector; if (attribs.alpha_size >= 0) { attrib_vector.push_back(ALPHA_SIZE); @@ -199,6 +177,10 @@ bool GLInProcessContextImpl::Initialize( attrib_vector.push_back(SAMPLE_BUFFERS); attrib_vector.push_back(attribs.sample_buffers); } + if (attribs.fail_if_major_perf_caveat > 0) { + attrib_vector.push_back(FAIL_IF_MAJOR_PERF_CAVEAT); + attrib_vector.push_back(attribs.fail_if_major_perf_caveat); + } attrib_vector.push_back(NONE); base::Closure wrapped_callback = @@ -235,14 +217,14 @@ bool GLInProcessContextImpl::Initialize( gpu_preference, wrapped_callback, share_group_id_)) { - LOG(INFO) << "Failed to initialize InProcessCommmandBuffer"; + LOG(ERROR) << "Failed to initialize InProcessCommmandBuffer"; return false; } // Create the GLES2 helper, which writes the command buffer protocol. gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get())); if (!gles2_helper_->Initialize(kCommandBufferSize)) { - LOG(INFO) << "Failed to initialize GLES2CmdHelper"; + LOG(ERROR) << "Failed to initialize GLES2CmdHelper"; Destroy(); return false; } @@ -250,12 +232,16 @@ bool GLInProcessContextImpl::Initialize( // Create a transfer buffer. transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get())); + bool bind_generates_resources = false; + bool free_everything_when_invisible = false; + // Create the object exposing the OpenGL API. gles2_implementation_.reset(new gles2::GLES2Implementation( gles2_helper_.get(), share_group, transfer_buffer_.get(), - false, + bind_generates_resources, + free_everything_when_invisible, command_buffer_.get())); if (share_resources) { @@ -275,10 +261,6 @@ bool GLInProcessContextImpl::Initialize( } void GLInProcessContextImpl::Destroy() { - while (!query_callbacks_.empty()) { - CallQueryCallback(0); - } - if (gles2_implementation_) { // First flush the context to ensure that any pending frees of resources // are completed. Otherwise, if this context is part of a share group, @@ -295,50 +277,6 @@ void GLInProcessContextImpl::Destroy() { command_buffer_.reset(); } -void GLInProcessContextImpl::CallQueryCallback(size_t index) { - DCHECK_LT(index, query_callbacks_.size()); - QueryCallback query_callback = query_callbacks_[index]; - query_callbacks_[index] = query_callbacks_.back(); - query_callbacks_.pop_back(); - query_callback.second.Run(); -} - -// TODO(sievers): Move this to the service side -void GLInProcessContextImpl::PollQueryCallbacks() { - for (size_t i = 0; i < query_callbacks_.size();) { - unsigned query = query_callbacks_[i].first; - GLuint param = 0; - gles2::GLES2Implementation* gl = GetImplementation(); - if (gl->IsQueryEXT(query)) { - gl->GetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, ¶m); - } else { - param = 1; - } - if (param) { - CallQueryCallback(i); - } else { - i++; - } - } - if (!query_callbacks_.empty()) { - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - base::Bind(&GLInProcessContextImpl::PollQueryCallbacks, - this->AsWeakPtr()), - base::TimeDelta::FromMilliseconds(5)); - } -} - -void GLInProcessContextImpl::SignalQuery( - unsigned query, - const base::Closure& callback) { - query_callbacks_.push_back(std::make_pair(query, callback)); - // If size > 1, there is already a poll callback pending. - if (query_callbacks_.size() == 1) { - PollQueryCallbacks(); - } -} - #if defined(OS_ANDROID) scoped_refptr<gfx::SurfaceTexture> GLInProcessContextImpl::GetSurfaceTexture(uint32 stream_id) { diff --git a/chromium/gpu/command_buffer/client/gl_in_process_context.h b/chromium/gpu/command_buffer/client/gl_in_process_context.h index 1be0d9da92b..6d96f131554 100644 --- a/chromium/gpu/command_buffer/client/gl_in_process_context.h +++ b/chromium/gpu/command_buffer/client/gl_in_process_context.h @@ -40,6 +40,7 @@ struct GLES2_IMPL_EXPORT GLInProcessContextAttribs { int32 stencil_size; int32 samples; int32 sample_buffers; + int32 fail_if_major_perf_caveat; }; class GLES2_IMPL_EXPORT GLInProcessContext { @@ -69,11 +70,6 @@ class GLES2_IMPL_EXPORT GLInProcessContext { virtual void SetContextLostCallback(const base::Closure& callback) = 0; - virtual void SignalSyncPoint(unsigned sync_point, - const base::Closure& callback) = 0; - - virtual void SignalQuery(unsigned query, const base::Closure& callback) = 0; - // Allows direct access to the GLES2 implementation so a GLInProcessContext // can be used without making it current. virtual gles2::GLES2Implementation* GetImplementation() = 0; diff --git a/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h b/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h index cc9a5cf49be..f2eb83746e7 100644 --- a/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -509,12 +509,18 @@ void GLES2VertexAttribPointer( void GLES2Viewport(GLint x, GLint y, GLsizei width, GLsizei height) { gles2::GetGLContext()->Viewport(x, y, width, height); } -void GLES2BlitFramebufferEXT( +void GLES2BlitFramebufferCHROMIUM( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - gles2::GetGLContext()->BlitFramebufferEXT( + gles2::GetGLContext()->BlitFramebufferCHROMIUM( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } +void GLES2RenderbufferStorageMultisampleCHROMIUM( + GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height) { + gles2::GetGLContext()->RenderbufferStorageMultisampleCHROMIUM( + target, samples, internalformat, width, height); +} void GLES2RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { @@ -758,6 +764,9 @@ void GLES2WaitSyncPointCHROMIUM(GLuint sync_point) { void GLES2DrawBuffersEXT(GLsizei count, const GLenum* bufs) { gles2::GetGLContext()->DrawBuffersEXT(count, bufs); } +void GLES2DiscardBackbufferCHROMIUM() { + gles2::GetGLContext()->DiscardBackbufferCHROMIUM(); +} namespace gles2 { @@ -989,8 +998,9 @@ extern const NameToFunc g_gles2_function_table[] = { { "glVertexAttribPointer", reinterpret_cast<GLES2FunctionPointer>( glVertexAttribPointer), }, { "glViewport", reinterpret_cast<GLES2FunctionPointer>(glViewport), }, - { "glBlitFramebufferEXT", reinterpret_cast<GLES2FunctionPointer>( - glBlitFramebufferEXT), }, + { "glBlitFramebufferCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( + glBlitFramebufferCHROMIUM), }, + { "glRenderbufferStorageMultisampleCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(glRenderbufferStorageMultisampleCHROMIUM), }, // NOLINT { "glRenderbufferStorageMultisampleEXT", reinterpret_cast<GLES2FunctionPointer>(glRenderbufferStorageMultisampleEXT), }, // NOLINT { "glFramebufferTexture2DMultisampleEXT", reinterpret_cast<GLES2FunctionPointer>(glFramebufferTexture2DMultisampleEXT), }, // NOLINT { "glTexStorage2DEXT", reinterpret_cast<GLES2FunctionPointer>( @@ -1114,6 +1124,8 @@ extern const NameToFunc g_gles2_function_table[] = { glWaitSyncPointCHROMIUM), }, { "glDrawBuffersEXT", reinterpret_cast<GLES2FunctionPointer>( glDrawBuffersEXT), }, + { "glDiscardBackbufferCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( + glDiscardBackbufferCHROMIUM), }, { NULL, NULL, }, }; diff --git a/chromium/gpu/command_buffer/client/gles2_cmd_helper.h b/chromium/gpu/command_buffer/client/gles2_cmd_helper.h index 7361a9b3e0d..72fae315b34 100644 --- a/chromium/gpu/command_buffer/client/gles2_cmd_helper.h +++ b/chromium/gpu/command_buffer/client/gles2_cmd_helper.h @@ -38,19 +38,6 @@ class GPU_EXPORT GLES2CmdHelper : public CommandBufferHelper { } } - void GetAttribLocationImmediate( - GLuint program, const char* name, - uint32 location_shm_id, uint32 location_shm_offset) { - const uint32 size = gles2::cmds::GetAttribLocationImmediate::ComputeSize( - name); - gles2::cmds::GetAttribLocationImmediate* c = - GetImmediateCmdSpaceTotalSize<gles2::cmds::GetAttribLocationImmediate>( - size); - if (c) { - c->Init(program, name, location_shm_id, location_shm_offset); - } - } - void GetAttribLocationBucket( GLuint program, uint32 name_bucket_id, uint32 location_shm_id, uint32 location_shm_offset) { @@ -73,19 +60,6 @@ class GPU_EXPORT GLES2CmdHelper : public CommandBufferHelper { } } - void GetUniformLocationImmediate( - GLuint program, const char* name, - uint32 location_shm_id, uint32 location_shm_offset) { - const uint32 size = gles2::cmds::GetUniformLocationImmediate::ComputeSize( - name); - gles2::cmds::GetUniformLocationImmediate* c = - GetImmediateCmdSpaceTotalSize<gles2::cmds::GetUniformLocationImmediate>( - size); - if (c) { - c->Init(program, name, location_shm_id, location_shm_offset); - } - } - void GetUniformLocationBucket( GLuint program, uint32 name_bucket_id, uint32 location_shm_id, uint32 location_shm_offset) { @@ -96,11 +70,6 @@ class GPU_EXPORT GLES2CmdHelper : public CommandBufferHelper { } } - GLuint InsertSyncPointCHROMIUM() { - CommandBufferHelper::Flush(); - return command_buffer()->InsertSyncPoint(); - } - private: DISALLOW_COPY_AND_ASSIGN(GLES2CmdHelper); }; diff --git a/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 8d2fd7d5ef4..76a9f4a1267 100644 --- a/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -33,17 +33,6 @@ } } - void BindAttribLocationImmediate( - GLuint program, GLuint index, const char* name) { - const uint32 data_size = strlen(name); - gles2::cmds::BindAttribLocationImmediate* c = - GetImmediateCmdSpace<gles2::cmds::BindAttribLocationImmediate>( - data_size); - if (c) { - c->Init(program, index, name, data_size); - } - } - void BindAttribLocationBucket( GLuint program, GLuint index, uint32 name_bucket_id) { gles2::cmds::BindAttribLocationBucket* c = @@ -131,15 +120,6 @@ } } - void BufferDataImmediate(GLenum target, GLsizeiptr size, GLenum usage) { - const uint32 s = 0; // TODO(gman): compute correct size - gles2::cmds::BufferDataImmediate* c = - GetImmediateCmdSpaceTotalSize<gles2::cmds::BufferDataImmediate>(s); - if (c) { - c->Init(target, size, usage); - } - } - void BufferSubData( GLenum target, GLintptr offset, GLsizeiptr size, uint32 data_shm_id, uint32 data_shm_offset) { @@ -149,16 +129,6 @@ } } - void BufferSubDataImmediate( - GLenum target, GLintptr offset, GLsizeiptr size) { - const uint32 s = 0; // TODO(gman): compute correct size - gles2::cmds::BufferSubDataImmediate* c = - GetImmediateCmdSpaceTotalSize<gles2::cmds::BufferSubDataImmediate>(s); - if (c) { - c->Init(target, offset, size); - } - } - void CheckFramebufferStatus( GLenum target, uint32 result_shm_id, uint32 result_shm_offset) { gles2::cmds::CheckFramebufferStatus* c = @@ -225,17 +195,6 @@ } } - void CompressedTexImage2DImmediate( - GLenum target, GLint level, GLenum internalformat, GLsizei width, - GLsizei height, GLint border, GLsizei imageSize) { - const uint32 s = 0; // TODO(gman): compute correct size - gles2::cmds::CompressedTexImage2DImmediate* c = - GetImmediateCmdSpaceTotalSize<gles2::cmds::CompressedTexImage2DImmediate>(s); // NOLINT - if (c) { - c->Init(target, level, internalformat, width, height, border, imageSize); - } - } - void CompressedTexImage2DBucket( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLuint bucket_id) { @@ -259,18 +218,6 @@ } } - void CompressedTexSubImage2DImmediate( - GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, - GLsizei height, GLenum format, GLsizei imageSize) { - const uint32 s = 0; // TODO(gman): compute correct size - gles2::cmds::CompressedTexSubImage2DImmediate* c = - GetImmediateCmdSpaceTotalSize<gles2::cmds::CompressedTexSubImage2DImmediate>(s); // NOLINT - if (c) { - c->Init( - target, level, xoffset, yoffset, width, height, format, imageSize); - } - } - void CompressedTexSubImage2DBucket( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLuint bucket_id) { @@ -985,15 +932,6 @@ } } - void ShaderSourceImmediate(GLuint shader, uint32 data_size) { - const uint32 s = 0; // TODO(gman): compute correct size - gles2::cmds::ShaderSourceImmediate* c = - GetImmediateCmdSpaceTotalSize<gles2::cmds::ShaderSourceImmediate>(s); - if (c) { - c->Init(shader, data_size); - } - } - void ShaderSourceBucket(GLuint shader, uint32 data_bucket_id) { gles2::cmds::ShaderSourceBucket* c = GetCmdSpace<gles2::cmds::ShaderSourceBucket>(); @@ -1060,18 +998,6 @@ } } - void TexImage2DImmediate( - GLenum target, GLint level, GLint internalformat, GLsizei width, - GLsizei height, GLint border, GLenum format, GLenum type) { - const uint32 s = 0; // TODO(gman): compute correct size - gles2::cmds::TexImage2DImmediate* c = - GetImmediateCmdSpaceTotalSize<gles2::cmds::TexImage2DImmediate>(s); - if (c) { - c->Init( - target, level, internalformat, width, height, border, format, type); - } - } - void TexParameterf(GLenum target, GLenum pname, GLfloat param) { gles2::cmds::TexParameterf* c = GetCmdSpace<gles2::cmds::TexParameterf>(); if (c) { @@ -1140,19 +1066,6 @@ } } - void TexSubImage2DImmediate( - GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, - GLsizei height, GLenum format, GLenum type, GLboolean internal) { - const uint32 s = 0; // TODO(gman): compute correct size - gles2::cmds::TexSubImage2DImmediate* c = - GetImmediateCmdSpaceTotalSize<gles2::cmds::TexSubImage2DImmediate>(s); - if (c) { - c->Init( - target, level, xoffset, yoffset, width, height, format, type, - internal); - } - } - void Uniform1f(GLint location, GLfloat x) { gles2::cmds::Uniform1f* c = GetCmdSpace<gles2::cmds::Uniform1f>(); if (c) { @@ -1555,11 +1468,11 @@ } } - void BlitFramebufferEXT( + void BlitFramebufferCHROMIUM( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - gles2::cmds::BlitFramebufferEXT* c = - GetCmdSpace<gles2::cmds::BlitFramebufferEXT>(); + gles2::cmds::BlitFramebufferCHROMIUM* c = + GetCmdSpace<gles2::cmds::BlitFramebufferCHROMIUM>(); if (c) { c->Init( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, @@ -1567,6 +1480,16 @@ } } + void RenderbufferStorageMultisampleCHROMIUM( + GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height) { + gles2::cmds::RenderbufferStorageMultisampleCHROMIUM* c = + GetCmdSpace<gles2::cmds::RenderbufferStorageMultisampleCHROMIUM>(); + if (c) { + c->Init(target, samples, internalformat, width, height); + } + } + void RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { @@ -1911,14 +1834,6 @@ } } - void GenMailboxCHROMIUM(GLuint bucket_id) { - gles2::cmds::GenMailboxCHROMIUM* c = - GetCmdSpace<gles2::cmds::GenMailboxCHROMIUM>(); - if (c) { - c->Init(bucket_id); - } - } - void ProduceTextureCHROMIUM( GLenum target, uint32 mailbox_shm_id, uint32 mailbox_shm_offset) { gles2::cmds::ProduceTextureCHROMIUM* c = @@ -1967,17 +1882,6 @@ } } - void BindUniformLocationCHROMIUMImmediate( - GLuint program, GLint location, const char* name) { - const uint32 data_size = strlen(name); - gles2::cmds::BindUniformLocationCHROMIUMImmediate* c = - GetImmediateCmdSpace<gles2::cmds::BindUniformLocationCHROMIUMImmediate>( - data_size); - if (c) { - c->Init(program, location, name, data_size); - } - } - void BindUniformLocationCHROMIUMBucket( GLuint program, GLint location, uint32 name_bucket_id) { gles2::cmds::BindUniformLocationCHROMIUMBucket* c = @@ -2110,5 +2014,13 @@ } } + void DiscardBackbufferCHROMIUM() { + gles2::cmds::DiscardBackbufferCHROMIUM* c = + GetCmdSpace<gles2::cmds::DiscardBackbufferCHROMIUM>(); + if (c) { + c->Init(); + } + } + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_implementation.cc b/chromium/gpu/command_buffer/client/gles2_implementation.cc index 0bee1ed5c4d..b0efc3769da 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation.cc +++ b/chromium/gpu/command_buffer/client/gles2_implementation.cc @@ -22,6 +22,7 @@ #include "gpu/command_buffer/client/transfer_buffer.h" #include "gpu/command_buffer/client/vertex_array_object_manager.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/common/gpu_control.h" #include "gpu/command_buffer/common/trace_event.h" #include "ui/gfx/gpu_memory_buffer.h" @@ -71,13 +72,13 @@ GLES2Implementation::GLStaticState::IntState::IntState() GLES2Implementation::SingleThreadChecker::SingleThreadChecker( GLES2Implementation* gles2_implementation) : gles2_implementation_(gles2_implementation) { - GPU_CHECK_EQ(0, gles2_implementation_->use_count_); + CHECK_EQ(0, gles2_implementation_->use_count_); ++gles2_implementation_->use_count_; } GLES2Implementation::SingleThreadChecker::~SingleThreadChecker() { --gles2_implementation_->use_count_; - GPU_CHECK_EQ(0, gles2_implementation_->use_count_); + CHECK_EQ(0, gles2_implementation_->use_count_); } GLES2Implementation::GLES2Implementation( @@ -85,6 +86,7 @@ GLES2Implementation::GLES2Implementation( ShareGroup* share_group, TransferBufferInterface* transfer_buffer, bool bind_generates_resource, + bool free_everything_when_invisible, GpuControl* gpu_control) : helper_(helper), transfer_buffer_(transfer_buffer), @@ -110,9 +112,14 @@ GLES2Implementation::GLES2Implementation( use_count_(0), current_query_(NULL), error_message_callback_(NULL), - gpu_control_(gpu_control) { - GPU_DCHECK(helper); - GPU_DCHECK(transfer_buffer); + gpu_control_(gpu_control), + surface_visible_(true), + free_everything_when_invisible_(free_everything_when_invisible), + capabilities_(gpu_control->GetCapabilities()), + weak_ptr_factory_(this) { + DCHECK(helper); + DCHECK(transfer_buffer); + DCHECK(gpu_control); char temp[128]; sprintf(temp, "%p", static_cast<void*>(this)); @@ -134,9 +141,9 @@ bool GLES2Implementation::Initialize( unsigned int min_transfer_buffer_size, unsigned int max_transfer_buffer_size, unsigned int mapped_memory_limit) { - GPU_DCHECK_GE(starting_transfer_buffer_size, min_transfer_buffer_size); - GPU_DCHECK_LE(starting_transfer_buffer_size, max_transfer_buffer_size); - GPU_DCHECK_GE(min_transfer_buffer_size, kStartingOffset); + DCHECK_GE(starting_transfer_buffer_size, min_transfer_buffer_size); + DCHECK_LE(starting_transfer_buffer_size, max_transfer_buffer_size); + DCHECK_GE(min_transfer_buffer_size, kStartingOffset); if (!transfer_buffer_->Initialize( starting_transfer_buffer_size, @@ -307,6 +314,46 @@ void GLES2Implementation::FreeEverything() { helper_->FreeRingBuffer(); } +void GLES2Implementation::RunIfContextNotLost(const base::Closure& callback) { + if (!helper_->IsContextLost()) + callback.Run(); +} + +void GLES2Implementation::SignalSyncPoint(uint32 sync_point, + const base::Closure& callback) { + gpu_control_->SignalSyncPoint( + sync_point, + base::Bind(&GLES2Implementation::RunIfContextNotLost, + weak_ptr_factory_.GetWeakPtr(), + callback)); +} + +void GLES2Implementation::SignalQuery(uint32 query, + const base::Closure& callback) { + // Flush previously entered commands to ensure ordering with any + // glBeginQueryEXT() calls that may have been put into the context. + ShallowFlushCHROMIUM(); + gpu_control_->SignalQuery( + query, + base::Bind(&GLES2Implementation::RunIfContextNotLost, + weak_ptr_factory_.GetWeakPtr(), + callback)); +} + +void GLES2Implementation::SetSurfaceVisible(bool visible) { + // TODO(piman): This probably should be ShallowFlushCHROMIUM(). + Flush(); + surface_visible_ = visible; + gpu_control_->SetSurfaceVisible(visible); + if (!visible) + FreeEverything(); +} + +void GLES2Implementation::SendManagedMemoryStats( + const ManagedMemoryStats& stats) { + gpu_control_->SendManagedMemoryStats(stats); +} + void GLES2Implementation::WaitForCmd() { TRACE_EVENT0("gpu", "GLES2::WaitForCmd"); helper_->CommandBufferHelper::Finish(); @@ -413,7 +460,7 @@ GLenum GLES2Implementation::GetGLError() { #if defined(GL_CLIENT_FAIL_GL_ERRORS) void GLES2Implementation::FailGLError(GLenum error) { if (error != GL_NO_ERROR) { - GPU_NOTREACHED() << "Error"; + NOTREACHED() << "Error"; } } // NOTE: Calling GetGLError overwrites data in the result buffer. @@ -449,7 +496,7 @@ void GLES2Implementation::SetGLErrorInvalidEnum( bool GLES2Implementation::GetBucketContents(uint32 bucket_id, std::vector<int8>* data) { TRACE_EVENT0("gpu", "GLES2::GetBucketContents"); - GPU_DCHECK(data); + DCHECK(data); const uint32 kStartSize = 32 * 1024; ScopedTransferBufferPtr buffer(kStartSize, helper_, transfer_buffer_); if (!buffer.valid()) { @@ -495,7 +542,7 @@ bool GLES2Implementation::GetBucketContents(uint32 bucket_id, void GLES2Implementation::SetBucketContents( uint32 bucket_id, const void* data, size_t size) { - GPU_DCHECK(data); + DCHECK(data); helper_->SetBucketSize(bucket_id, size); if (size > 0u) { uint32 offset = 0; @@ -527,7 +574,7 @@ void GLES2Implementation::SetBucketAsCString( bool GLES2Implementation::GetBucketAsString( uint32 bucket_id, std::string* str) { - GPU_DCHECK(str); + DCHECK(str); std::vector<int8> data; // NOTE: strings are passed NULL terminated. That means the empty // string will have a size of 1 and no-string will have a size of 0 @@ -664,6 +711,13 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { return true; } return false; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + if (share_group_->bind_generates_resource()) { + *params = + texture_units_[active_texture_unit_].bound_texture_external_oes; + return true; + } + return false; case GL_FRAMEBUFFER_BINDING: if (share_group_->bind_generates_resource()) { *params = bound_framebuffer_; @@ -793,6 +847,8 @@ void GLES2Implementation::Flush() { // Flush our command buffer // (tell the service to execute up to the flush cmd.) helper_->CommandBufferHelper::Flush(); + if (!surface_visible_ && free_everything_when_invisible_) + FreeEverything(); } void GLES2Implementation::ShallowFlushCHROMIUM() { @@ -801,11 +857,14 @@ void GLES2Implementation::ShallowFlushCHROMIUM() { // Flush our command buffer // (tell the service to execute up to the flush cmd.) helper_->CommandBufferHelper::Flush(); + // TODO(piman): Add the FreeEverything() logic here. } void GLES2Implementation::Finish() { GPU_CLIENT_SINGLE_THREAD_CHECK(); FinishHelper(); + if (!surface_visible_ && free_everything_when_invisible_) + FreeEverything(); } void GLES2Implementation::ShallowFinishCHROMIUM() { @@ -821,7 +880,7 @@ bool GLES2Implementation::MustBeContextLost() { WaitForCmd(); context_lost = helper_->IsContextLost(); } - GPU_CHECK(context_lost); + CHECK(context_lost); return context_lost; } @@ -1005,7 +1064,7 @@ bool GLES2Implementation::DeleteProgramHelper(GLuint program) { void GLES2Implementation::DeleteProgramStub( GLsizei n, const GLuint* programs) { - GPU_DCHECK_EQ(1, n); + DCHECK_EQ(1, n); share_group_->program_info_manager()->DeleteInfo(programs[0]); helper_->DeleteProgram(programs[0]); } @@ -1023,7 +1082,7 @@ bool GLES2Implementation::DeleteShaderHelper(GLuint shader) { void GLES2Implementation::DeleteShaderStub( GLsizei n, const GLuint* shaders) { - GPU_DCHECK_EQ(1, n); + DCHECK_EQ(1, n); share_group_->program_info_manager()->DeleteInfo(shaders[0]); helper_->DeleteShader(shaders[0]); } @@ -1298,7 +1357,7 @@ void GLES2Implementation::ShaderSource( } } - GPU_DCHECK_EQ(total_size, offset); + DCHECK_EQ(total_size, offset); helper_->ShaderSourceBucket(shader, kResultBucketId); helper_->SetBucketSize(kResultBucketId, 0); @@ -1329,7 +1388,7 @@ void GLES2Implementation::BufferDataHelper( // Create new buffer. buffer = buffer_tracker_->CreateBuffer(buffer_id, size); - GPU_DCHECK(buffer); + DCHECK(buffer); if (buffer->address() && data) memcpy(buffer->address(), data, size); return; @@ -1421,8 +1480,8 @@ void GLES2Implementation::BufferSubDataHelper( void GLES2Implementation::BufferSubDataHelperImpl( GLenum target, GLintptr offset, GLsizeiptr size, const void* data, ScopedTransferBufferPtr* buffer) { - GPU_DCHECK(buffer); - GPU_DCHECK_GT(size, 0); + DCHECK(buffer); + DCHECK_GT(size, 0); const int8* source = static_cast<const int8*>(data); while (size) { @@ -1802,7 +1861,7 @@ void GLES2Implementation::TexSubImage2D( static GLint ComputeNumRowsThatFitInBuffer( GLsizeiptr padded_row_size, GLsizeiptr unpadded_row_size, unsigned int size) { - GPU_DCHECK_GE(unpadded_row_size, 0); + DCHECK_GE(unpadded_row_size, 0); if (padded_row_size == 0) { return 1; } @@ -1815,10 +1874,10 @@ void GLES2Implementation::TexSubImage2DImpl( GLsizei height, GLenum format, GLenum type, uint32 unpadded_row_size, const void* pixels, uint32 pixels_padded_row_size, GLboolean internal, ScopedTransferBufferPtr* buffer, uint32 buffer_padded_row_size) { - GPU_DCHECK(buffer); - GPU_DCHECK_GE(level, 0); - GPU_DCHECK_GT(height, 0); - GPU_DCHECK_GT(width, 0); + DCHECK(buffer); + DCHECK_GE(level, 0); + DCHECK_GT(height, 0); + DCHECK_GT(width, 0); const int8* source = reinterpret_cast<const int8*>(pixels); GLint original_yoffset = yoffset; @@ -2087,10 +2146,8 @@ const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) { case GL_EXTENSIONS: str += std::string(str.empty() ? "" : " ") + "GL_CHROMIUM_flipy " - "GL_CHROMIUM_map_sub " - "GL_CHROMIUM_shallow_flush " "GL_EXT_unpack_subimage"; - if (gpu_control_ != NULL) { + if (capabilities_.map_image) { // The first space character is intentional. str += " GL_CHROMIUM_map_image"; } @@ -2107,7 +2164,7 @@ const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) { std::set<std::string> strings; std::pair<GLStringMap::iterator, bool> insert_result = gl_strings_.insert(std::make_pair(name, strings)); - GPU_DCHECK(insert_result.second); + DCHECK(insert_result.second); it = insert_result.first; } std::set<std::string>& string_set = it->second; @@ -2117,7 +2174,7 @@ const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) { } else { std::pair<std::set<std::string>::const_iterator, bool> insert_result = string_set.insert(str); - GPU_DCHECK(insert_result.second); + DCHECK(insert_result.second); result = insert_result.first->c_str(); } } @@ -2457,6 +2514,12 @@ bool GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) { changed = true; } break; + case GL_TEXTURE_EXTERNAL_OES: + if (unit.bound_texture_external_oes != texture) { + unit.bound_texture_external_oes = texture; + changed = true; + } + break; default: changed = true; break; @@ -2584,6 +2647,9 @@ void GLES2Implementation::DeleteTexturesHelper( if (textures[ii] == unit.bound_texture_cube_map) { unit.bound_texture_cube_map = 0; } + if (textures[ii] == unit.bound_texture_external_oes) { + unit.bound_texture_external_oes = 0; + } } } } @@ -2709,6 +2775,32 @@ void GLES2Implementation::GetVertexAttribiv( CheckGLError(); } +void GLES2Implementation::Swap() { + SwapBuffers(); + gpu_control_->Echo( + base::Bind(&GLES2Implementation::OnSwapBuffersComplete, + weak_ptr_factory_.GetWeakPtr())); +} + +void GLES2Implementation::PartialSwapBuffers(gfx::Rect sub_buffer) { + PostSubBufferCHROMIUM(sub_buffer.x(), + sub_buffer.y(), + sub_buffer.width(), + sub_buffer.height()); + gpu_control_->Echo(base::Bind(&GLES2Implementation::OnSwapBuffersComplete, + weak_ptr_factory_.GetWeakPtr())); +} + +void GLES2Implementation::SetSwapBuffersCompleteCallback( + const base::Closure& swap_buffers_complete_callback) { + swap_buffers_complete_callback_ = swap_buffers_complete_callback; +} + +void GLES2Implementation::OnSwapBuffersComplete() { + if (!swap_buffers_complete_callback_.is_null()) + swap_buffers_complete_callback_.Run(); +} + GLboolean GLES2Implementation::EnableFeatureCHROMIUM( const char* feature) { GPU_CLIENT_SINGLE_THREAD_CHECK(); @@ -2760,7 +2852,7 @@ void* GLES2Implementation::MapBufferSubDataCHROMIUM( mem, MappedBuffer( access, shm_id, mem, shm_offset, target, offset, size))); - GPU_DCHECK(result.second); + DCHECK(result.second); GPU_CLIENT_LOG(" returned " << mem); return mem; } @@ -2834,7 +2926,7 @@ void* GLES2Implementation::MapTexSubImage2DCHROMIUM( MappedTexture( access, shm_id, mem, shm_offset, target, level, xoffset, yoffset, width, height, format, type))); - GPU_DCHECK(result.second); + DCHECK(result.second); GPU_CLIENT_LOG(" returned " << mem); return mem; } @@ -2890,7 +2982,7 @@ const GLchar* GLES2Implementation::GetRequestableExtensionsCHROMIUM() { } else { std::pair<std::set<std::string>::const_iterator, bool> insert_result = requestable_extensions_set_.insert(str); - GPU_DCHECK(insert_result.second); + DCHECK(insert_result.second); result = insert_result.first->c_str(); } } @@ -3072,7 +3164,7 @@ void GLES2Implementation::GetAllShaderPrecisionFormatsOnCompleted( void GLES2Implementation::GetProgramInfoCHROMIUMHelper( GLuint program, std::vector<int8>* result) { - GPU_DCHECK(result); + DCHECK(result); // Clear the bucket so if the command fails nothing will be in it. helper_->SetBucketSize(kResultBucketId, 0); helper_->GetProgramInfoCHROMIUM(program, kResultBucketId); @@ -3093,7 +3185,7 @@ void GLES2Implementation::GetProgramInfoCHROMIUM( } // Make sure they've set size to 0 else the value will be undefined on // lost context. - GPU_DCHECK(*size == 0); + DCHECK(*size == 0); std::vector<int8> result; GetProgramInfoCHROMIUMHelper(program, &result); if (result.empty()) { @@ -3309,7 +3401,7 @@ void GLES2Implementation::GetQueryObjectuivEXT( if (!query->CheckResultsAvailable(helper_)) { // TODO(gman): Speed this up. WaitForCmd(); - GPU_CHECK(query->CheckResultsAvailable(helper_)); + CHECK(query->CheckResultsAvailable(helper_)); } } *params = query->GetResult(); @@ -3398,13 +3490,12 @@ void GLES2Implementation::GenMailboxCHROMIUM( << static_cast<const void*>(mailbox) << ")"); TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM"); - helper_->GenMailboxCHROMIUM(kResultBucketId); - - std::vector<GLbyte> result; - GetBucketContents(kResultBucketId, &result); - - std::copy(result.begin(), result.end(), mailbox); - CheckGLError(); + std::vector<gpu::Mailbox> names; + if (!gpu_control_->GenerateMailboxNames(1, &names)) { + SetGLError(GL_OUT_OF_MEMORY, "glGenMailboxCHROMIUM", "Generate failed."); + return; + } + memcpy(mailbox, names[0].name, GL_MAILBOX_SIZE_CHROMIUM); } void GLES2Implementation::PushGroupMarkerEXT( @@ -3659,7 +3750,8 @@ void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) { GLuint GLES2Implementation::InsertSyncPointCHROMIUM() { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM"); - return helper_->InsertSyncPointCHROMIUM(); + helper_->CommandBufferHelper::Flush(); + return gpu_control_->InsertSyncPoint(); } GLuint GLES2Implementation::CreateImageCHROMIUMHelper( diff --git a/chromium/gpu/command_buffer/client/gles2_implementation.h b/chromium/gpu/command_buffer/client/gles2_implementation.h index 9f8a7a2516a..6b6877f18b3 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation.h @@ -13,10 +13,13 @@ #include <string> #include <vector> +#include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "gles2_impl_export.h" #include "gpu/command_buffer/client/buffer_tracker.h" #include "gpu/command_buffer/client/client_context_state.h" +#include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/client/gpu_memory_buffer_tracker.h" @@ -25,7 +28,7 @@ #include "gpu/command_buffer/client/ref_counted.h" #include "gpu/command_buffer/client/ring_buffer.h" #include "gpu/command_buffer/client/share_group.h" -#include "gpu/command_buffer/common/compiler_specific.h" +#include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/common/debug_marker_manager.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" @@ -113,7 +116,9 @@ class VertexArrayObjectManager; // be had by changing your code to use command buffers directly by using the // GLES2CmdHelper but that entails changing your code to use and deal with // shared memory and synchronization issues. -class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { +class GLES2_IMPL_EXPORT GLES2Implementation + : NON_EXPORTED_BASE(public GLES2Interface), + NON_EXPORTED_BASE(public ContextSupport) { public: enum MappedMemoryLimit { kNoLimit = MappedMemoryManager::kNoLimit, @@ -180,6 +185,7 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { ShareGroup* share_group, TransferBufferInterface* transfer_buffer, bool bind_generates_resource, + bool free_everything_when_invisible, GpuControl* gpu_control); virtual ~GLES2Implementation(); @@ -209,6 +215,13 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { virtual void GetVertexAttribiv( GLuint index, GLenum pname, GLint* params) OVERRIDE; + // ContextSupport implementation. + virtual void Swap() OVERRIDE; + virtual void PartialSwapBuffers(gfx::Rect sub_buffer) OVERRIDE; + virtual void SetSwapBuffersCompleteCallback( + const base::Closure& swap_buffers_complete_callback) + OVERRIDE; + void GetProgramInfoCHROMIUMHelper(GLuint program, std::vector<int8>* result); GLint GetAttribLocationHelper(GLuint program, const char* name); GLint GetUniformLocationHelper(GLuint program, const char* name); @@ -219,10 +232,18 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); - void FreeUnusedSharedMemory(); void FreeEverything(); + // ContextSupport implementation. + virtual void SignalSyncPoint(uint32 sync_point, + const base::Closure& callback) OVERRIDE; + virtual void SignalQuery(uint32 query, + const base::Closure& callback) OVERRIDE; + virtual void SetSurfaceVisible(bool visible) OVERRIDE; + virtual void SendManagedMemoryStats(const ManagedMemoryStats& stats) + OVERRIDE; + void SetErrorMessageCallback(ErrorMessageCallback* callback) { error_message_callback_ = callback; } @@ -231,6 +252,14 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { return share_group_.get(); } + const Capabilities& capabilities() const { + return capabilities_; + } + + GpuControl* gpu_control() { + return gpu_control_; + } + private: friend class GLES2ImplementationTest; friend class VertexArrayObjectManager; @@ -326,8 +355,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { struct TextureUnit { TextureUnit() : bound_texture_2d(0), - bound_texture_cube_map(0) { - } + bound_texture_cube_map(0), + bound_texture_external_oes(0) {} // texture currently bound to this unit's GL_TEXTURE_2D with glBindTexture GLuint bound_texture_2d; @@ -335,6 +364,10 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { // texture currently bound to this unit's GL_TEXTURE_CUBE_MAP with // glBindTexture GLuint bound_texture_cube_map; + + // texture currently bound to this unit's GL_TEXTURE_EXTERNAL_OES with + // glBindTexture + GLuint bound_texture_external_oes; }; // Checks for single threaded access. @@ -554,6 +587,10 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { // for error checking. bool MustBeContextLost(); + void RunIfContextNotLost(const base::Closure& callback); + + void OnSwapBuffersComplete(); + bool GetBoundPixelTransferBuffer( GLenum target, const char* function_name, GLuint* buffer_id); BufferTracker::Buffer* GetBoundPixelUnpackTransferBufferIfValid( @@ -673,6 +710,16 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { GpuControl* gpu_control_; + bool surface_visible_; + bool free_everything_when_invisible_; + + Capabilities capabilities_; + + bool use_echo_for_swap_ack_; + base::Closure swap_buffers_complete_callback_; + + base::WeakPtrFactory<GLES2Implementation> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(GLES2Implementation); }; diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h b/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h index c4ed4996dba..5703956e415 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -376,11 +376,15 @@ virtual void VertexAttribPointer( virtual void Viewport( GLint x, GLint y, GLsizei width, GLsizei height) OVERRIDE; -virtual void BlitFramebufferEXT( +virtual void BlitFramebufferCHROMIUM( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) OVERRIDE; +virtual void RenderbufferStorageMultisampleCHROMIUM( + GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height) OVERRIDE; + virtual void RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) OVERRIDE; @@ -551,5 +555,7 @@ virtual void WaitSyncPointCHROMIUM(GLuint sync_point) OVERRIDE; virtual void DrawBuffersEXT(GLsizei count, const GLenum* bufs) OVERRIDE; +virtual void DiscardBackbufferCHROMIUM() OVERRIDE; + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 82e0ce07aa4..3b92eb2933e 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h @@ -251,7 +251,7 @@ void GLES2Implementation::DeleteBuffers(GLsizei n, const GLuint* buffers) { }); GPU_CLIENT_DCHECK_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { - GPU_DCHECK(buffers[i] != 0); + DCHECK(buffers[i] != 0); } }); if (n < 0) { @@ -273,7 +273,7 @@ void GLES2Implementation::DeleteFramebuffers( }); GPU_CLIENT_DCHECK_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { - GPU_DCHECK(framebuffers[i] != 0); + DCHECK(framebuffers[i] != 0); } }); if (n < 0) { @@ -303,7 +303,7 @@ void GLES2Implementation::DeleteRenderbuffers( }); GPU_CLIENT_DCHECK_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { - GPU_DCHECK(renderbuffers[i] != 0); + DCHECK(renderbuffers[i] != 0); } }); if (n < 0) { @@ -332,7 +332,7 @@ void GLES2Implementation::DeleteTextures(GLsizei n, const GLuint* textures) { }); GPU_CLIENT_DCHECK_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { - GPU_DCHECK(textures[i] != 0); + DCHECK(textures[i] != 0); } }); if (n < 0) { @@ -1410,16 +1410,41 @@ void GLES2Implementation::Viewport( CheckGLError(); } -void GLES2Implementation::BlitFramebufferEXT( +void GLES2Implementation::BlitFramebufferCHROMIUM( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { GPU_CLIENT_SINGLE_THREAD_CHECK(); - GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlitFramebufferEXT(" << srcX0 << ", " << srcY0 << ", " << srcX1 << ", " << srcY1 << ", " << dstX0 << ", " << dstY0 << ", " << dstX1 << ", " << dstY1 << ", " << mask << ", " << GLES2Util::GetStringBlitFilter(filter) << ")"); // NOLINT - helper_->BlitFramebufferEXT( + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlitFramebufferCHROMIUM(" << srcX0 << ", " << srcY0 << ", " << srcX1 << ", " << srcY1 << ", " << dstX0 << ", " << dstY0 << ", " << dstX1 << ", " << dstY1 << ", " << mask << ", " << GLES2Util::GetStringBlitFilter(filter) << ")"); // NOLINT + helper_->BlitFramebufferCHROMIUM( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); CheckGLError(); } +void GLES2Implementation::RenderbufferStorageMultisampleCHROMIUM( + GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glRenderbufferStorageMultisampleCHROMIUM(" << GLES2Util::GetStringRenderBufferTarget(target) << ", " << samples << ", " << GLES2Util::GetStringRenderBufferFormat(internalformat) << ", " << width << ", " << height << ")"); // NOLINT + if (samples < 0) { + SetGLError( + GL_INVALID_VALUE, "glRenderbufferStorageMultisampleCHROMIUM", "samples < 0"); // NOLINT + return; + } + if (width < 0) { + SetGLError( + GL_INVALID_VALUE, "glRenderbufferStorageMultisampleCHROMIUM", "width < 0"); // NOLINT + return; + } + if (height < 0) { + SetGLError( + GL_INVALID_VALUE, "glRenderbufferStorageMultisampleCHROMIUM", "height < 0"); // NOLINT + return; + } + helper_->RenderbufferStorageMultisampleCHROMIUM( + target, samples, internalformat, width, height); + CheckGLError(); +} + void GLES2Implementation::RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { @@ -1511,7 +1536,7 @@ void GLES2Implementation::DeleteQueriesEXT(GLsizei n, const GLuint* queries) { }); GPU_CLIENT_DCHECK_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { - GPU_DCHECK(queries[i] != 0); + DCHECK(queries[i] != 0); } }); if (n < 0) { @@ -1553,7 +1578,7 @@ void GLES2Implementation::DeleteVertexArraysOES( }); GPU_CLIENT_DCHECK_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { - GPU_DCHECK(arrays[i] != 0); + DCHECK(arrays[i] != 0); } }); if (n < 0) { @@ -1734,5 +1759,12 @@ void GLES2Implementation::DrawBuffersEXT(GLsizei count, const GLenum* bufs) { CheckGLError(); } +void GLES2Implementation::DiscardBackbufferCHROMIUM() { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDiscardBackbufferCHROMIUM(" << ")"); // NOLINT + helper_->DiscardBackbufferCHROMIUM(); + CheckGLError(); +} + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_IMPL_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc b/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc index 84fa749fde5..e6e0861d188 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -8,11 +8,11 @@ #include <GLES2/gl2ext.h> #include <GLES2/gl2extchromium.h> +#include "base/compiler_specific.h" #include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/client/program_info_manager.h" #include "gpu/command_buffer/client/transfer_buffer.h" #include "gpu/command_buffer/common/command_buffer.h" -#include "gpu/command_buffer/common/compiler_specific.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gmock/include/gmock/gmock.h" @@ -250,7 +250,7 @@ int MockTransferBuffer::GetResultOffset() { } void MockTransferBuffer::Free() { - GPU_NOTREACHED(); + NOTREACHED(); } bool MockTransferBuffer::HaveBuffer() const { @@ -367,6 +367,8 @@ class GLES2ImplementationTest : public testing::Test { helper_->Initialize(kCommandBufferSizeBytes); gpu_control_.reset(new StrictMock<MockClientGpuControl>()); + EXPECT_CALL(*gpu_control_, GetCapabilities()) + .WillOnce(testing::Return(Capabilities())); GLES2Implementation::GLStaticState state; GLES2Implementation::GLStaticState::IntState& int_state = state.int_state; @@ -403,6 +405,7 @@ class GLES2ImplementationTest : public testing::Test { NULL, transfer_buffer_.get(), bind_generates_resource, + false /* free_everything_when_invisible */, gpu_control_.get())); ASSERT_TRUE(gl_->Initialize( kTransferBufferSize, @@ -1949,26 +1952,26 @@ TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) { GLint expected; }; const PNameValue pairs[] = { - { GL_ACTIVE_TEXTURE, GL_TEXTURE0, }, - { GL_TEXTURE_BINDING_2D, 0, }, - { GL_TEXTURE_BINDING_CUBE_MAP, 0, }, - { GL_FRAMEBUFFER_BINDING, 0, }, - { GL_RENDERBUFFER_BINDING, 0, }, - { GL_ARRAY_BUFFER_BINDING, 0, }, - { GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, }, - { GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, }, - { GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, }, - { GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, }, - { GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, }, - { GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, }, - { GL_MAX_TEXTURE_SIZE, kMaxTextureSize, }, - { GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, }, - { GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, }, - { GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, }, - { GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, }, - { GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, }, - { GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, - }; + {GL_ACTIVE_TEXTURE, GL_TEXTURE0, }, + {GL_TEXTURE_BINDING_2D, 0, }, + {GL_TEXTURE_BINDING_CUBE_MAP, 0, }, + {GL_TEXTURE_BINDING_EXTERNAL_OES, 0, }, + {GL_FRAMEBUFFER_BINDING, 0, }, + {GL_RENDERBUFFER_BINDING, 0, }, + {GL_ARRAY_BUFFER_BINDING, 0, }, + {GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, }, + {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, }, + {GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, }, + {GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, }, + {GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, }, + {GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, }, + {GL_MAX_TEXTURE_SIZE, kMaxTextureSize, }, + {GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, }, + {GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, }, + {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, }, + {GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, }, + {GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, }, + {GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, }; size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]); for (size_t ii = 0; ii < num_pairs; ++ii) { const PNameValue& pv = pairs[ii]; @@ -1999,16 +2002,16 @@ TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) { gl_->BindRenderbuffer(GL_RENDERBUFFER, 5); gl_->BindTexture(GL_TEXTURE_2D, 6); gl_->BindTexture(GL_TEXTURE_CUBE_MAP, 7); - - const PNameValue pairs[] = { - { GL_ACTIVE_TEXTURE, GL_TEXTURE4, }, - { GL_ARRAY_BUFFER_BINDING, 2, }, - { GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, }, - { GL_FRAMEBUFFER_BINDING, 4, }, - { GL_RENDERBUFFER_BINDING, 5, }, - { GL_TEXTURE_BINDING_2D, 6, }, - { GL_TEXTURE_BINDING_CUBE_MAP, 7, }, - }; + gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, 8); + + const PNameValue pairs[] = {{GL_ACTIVE_TEXTURE, GL_TEXTURE4, }, + {GL_ARRAY_BUFFER_BINDING, 2, }, + {GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, }, + {GL_FRAMEBUFFER_BINDING, 4, }, + {GL_RENDERBUFFER_BINDING, 5, }, + {GL_TEXTURE_BINDING_2D, 6, }, + {GL_TEXTURE_BINDING_CUBE_MAP, 7, }, + {GL_TEXTURE_BINDING_EXTERNAL_OES, 8, }, }; size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]); for (size_t ii = 0; ii < num_pairs; ++ii) { const PNameValue& pv = pairs[ii]; @@ -2419,14 +2422,13 @@ TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) { GLenum pname; GLint expected; }; - const PNameValue pairs[] = { - { GL_TEXTURE_BINDING_2D, 1, }, - { GL_TEXTURE_BINDING_CUBE_MAP, 2, }, - { GL_FRAMEBUFFER_BINDING, 3, }, - { GL_RENDERBUFFER_BINDING, 4, }, - { GL_ARRAY_BUFFER_BINDING, 5, }, - { GL_ELEMENT_ARRAY_BUFFER_BINDING, 6, }, - }; + const PNameValue pairs[] = {{GL_TEXTURE_BINDING_2D, 1, }, + {GL_TEXTURE_BINDING_CUBE_MAP, 2, }, + {GL_TEXTURE_BINDING_EXTERNAL_OES, 3, }, + {GL_FRAMEBUFFER_BINDING, 4, }, + {GL_RENDERBUFFER_BINDING, 5, }, + {GL_ARRAY_BUFFER_BINDING, 6, }, + {GL_ELEMENT_ARRAY_BUFFER_BINDING, 7, }, }; size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]); for (size_t ii = 0; ii < num_pairs; ++ii) { const PNameValue& pv = pairs[ii]; @@ -2478,10 +2480,7 @@ TEST_F(GLES2ImplementationTest, GetString) { const char* expected_str = "foobar " "GL_CHROMIUM_flipy " - "GL_CHROMIUM_map_sub " - "GL_CHROMIUM_shallow_flush " - "GL_EXT_unpack_subimage " - "GL_CHROMIUM_map_image"; + "GL_EXT_unpack_subimage"; const char kBad = 0x12; struct Cmds { cmd::SetBucketSize set_bucket_size1; diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index a1ea5873a36..38e32a69b25 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -1524,14 +1524,26 @@ TEST_F(GLES2ImplementationTest, Viewport) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -TEST_F(GLES2ImplementationTest, BlitFramebufferEXT) { +TEST_F(GLES2ImplementationTest, BlitFramebufferCHROMIUM) { struct Cmds { - cmds::BlitFramebufferEXT cmd; + cmds::BlitFramebufferCHROMIUM cmd; }; Cmds expected; expected.cmd.Init(1, 2, 3, 4, 5, 6, 7, 8, 9, GL_NEAREST); - gl_->BlitFramebufferEXT(1, 2, 3, 4, 5, 6, 7, 8, 9, GL_NEAREST); + gl_->BlitFramebufferCHROMIUM(1, 2, 3, 4, 5, 6, 7, 8, 9, GL_NEAREST); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, RenderbufferStorageMultisampleCHROMIUM) { + struct Cmds { + cmds::RenderbufferStorageMultisampleCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(GL_RENDERBUFFER, 2, GL_RGBA4, 4, 5); + + gl_->RenderbufferStorageMultisampleCHROMIUM( + GL_RENDERBUFFER, 2, GL_RGBA4, 4, 5); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } @@ -1735,6 +1747,7 @@ TEST_F(GLES2ImplementationTest, VertexAttribDivisorANGLE) { gl_->VertexAttribDivisorANGLE(1, 2); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +// TODO: Implement unit test for GenMailboxCHROMIUM TEST_F(GLES2ImplementationTest, ProduceTextureCHROMIUM) { GLbyte data[64] = {0}; @@ -1849,5 +1862,16 @@ TEST_F(GLES2ImplementationTest, DrawBuffersEXT) { gl_->DrawBuffersEXT(1, &data[0][0]); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } + +TEST_F(GLES2ImplementationTest, DiscardBackbufferCHROMIUM) { + struct Cmds { + cmds::DiscardBackbufferCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(); + + gl_->DiscardBackbufferCHROMIUM(); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_UNITTEST_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_interface.cc b/chromium/gpu/command_buffer/client/gles2_interface.cc deleted file mode 100644 index a94f167eb34..00000000000 --- a/chromium/gpu/command_buffer/client/gles2_interface.cc +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gpu/command_buffer/client/gles2_interface.h" - -namespace gpu { -namespace gles2 { - -GLES2Interface::GLES2Interface() { -} - -GLES2Interface::~GLES2Interface() { -} - -} // namespace gles2 -} // namespace gpu - - diff --git a/chromium/gpu/command_buffer/client/gles2_interface.h b/chromium/gpu/command_buffer/client/gles2_interface.h index d1659bf73f7..ca053081c74 100644 --- a/chromium/gpu/command_buffer/client/gles2_interface.h +++ b/chromium/gpu/command_buffer/client/gles2_interface.h @@ -6,16 +6,17 @@ #define GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_H_ #include <GLES2/gl2.h> -#include "gles2_impl_export.h" + +#include "base/compiler_specific.h" namespace gpu { namespace gles2 { // This class is the interface for all client side GL functions. -class GLES2_IMPL_EXPORT GLES2Interface { +class GLES2Interface { public: - GLES2Interface(); - virtual ~GLES2Interface(); + GLES2Interface() {} + virtual ~GLES2Interface() {} // Include the auto-generated part of this class. We split this because // it means we can easily edit the non-auto generated parts right here in diff --git a/chromium/gpu/command_buffer/client/gles2_interface_autogen.h b/chromium/gpu/command_buffer/client/gles2_interface_autogen.h index 24ce83bc2f5..029bf691bc1 100644 --- a/chromium/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_interface_autogen.h @@ -217,9 +217,12 @@ virtual void VertexAttribPointer( GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) = 0; virtual void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) = 0; -virtual void BlitFramebufferEXT( +virtual void BlitFramebufferCHROMIUM( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) = 0; +virtual void RenderbufferStorageMultisampleCHROMIUM( + GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height) = 0; virtual void RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) = 0; @@ -319,5 +322,6 @@ virtual void LoseContextCHROMIUM(GLenum current, GLenum other) = 0; virtual GLuint InsertSyncPointCHROMIUM() = 0; virtual void WaitSyncPointCHROMIUM(GLuint sync_point) = 0; virtual void DrawBuffersEXT(GLsizei count, const GLenum* bufs) = 0; +virtual void DiscardBackbufferCHROMIUM() = 0; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_interface_stub.h b/chromium/gpu/command_buffer/client/gles2_interface_stub.h index 342fc9bad0b..cf3fb41de6f 100644 --- a/chromium/gpu/command_buffer/client/gles2_interface_stub.h +++ b/chromium/gpu/command_buffer/client/gles2_interface_stub.h @@ -5,7 +5,6 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_H_ #define GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_H_ -#include "gpu/command_buffer/common/compiler_specific.h" #include "gpu/command_buffer/client/gles2_interface.h" namespace gpu { diff --git a/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 7650cd667ac..59c0ce9e8fb 100644 --- a/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -241,10 +241,13 @@ virtual void VertexAttribPointer( const void* ptr) OVERRIDE; virtual void Viewport( GLint x, GLint y, GLsizei width, GLsizei height) OVERRIDE; -virtual void BlitFramebufferEXT( +virtual void BlitFramebufferCHROMIUM( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) OVERRIDE; +virtual void RenderbufferStorageMultisampleCHROMIUM( + GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height) OVERRIDE; virtual void RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) OVERRIDE; @@ -350,5 +353,6 @@ virtual void LoseContextCHROMIUM(GLenum current, GLenum other) OVERRIDE; virtual GLuint InsertSyncPointCHROMIUM() OVERRIDE; virtual void WaitSyncPointCHROMIUM(GLuint sync_point) OVERRIDE; virtual void DrawBuffersEXT(GLsizei count, const GLenum* bufs) OVERRIDE; +virtual void DiscardBackbufferCHROMIUM() OVERRIDE; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 6778fcfbc9a..e6a26d43d40 100644 --- a/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -450,11 +450,15 @@ void GLES2InterfaceStub::VertexAttribPointer( void GLES2InterfaceStub::Viewport( GLint /* x */, GLint /* y */, GLsizei /* width */, GLsizei /* height */) { } -void GLES2InterfaceStub::BlitFramebufferEXT( +void GLES2InterfaceStub::BlitFramebufferCHROMIUM( GLint /* srcX0 */, GLint /* srcY0 */, GLint /* srcX1 */, GLint /* srcY1 */, GLint /* dstX0 */, GLint /* dstY0 */, GLint /* dstX1 */, GLint /* dstY1 */, GLbitfield /* mask */, GLenum /* filter */) { } +void GLES2InterfaceStub::RenderbufferStorageMultisampleCHROMIUM( + GLenum /* target */, GLsizei /* samples */, GLenum /* internalformat */, + GLsizei /* width */, GLsizei /* height */) { +} void GLES2InterfaceStub::RenderbufferStorageMultisampleEXT( GLenum /* target */, GLsizei /* samples */, GLenum /* internalformat */, GLsizei /* width */, GLsizei /* height */) { @@ -661,5 +665,7 @@ void GLES2InterfaceStub::WaitSyncPointCHROMIUM(GLuint /* sync_point */) { void GLES2InterfaceStub::DrawBuffersEXT( GLsizei /* count */, const GLenum* /* bufs */) { } +void GLES2InterfaceStub::DiscardBackbufferCHROMIUM() { +} #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_IMPL_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_trace_implementation.h b/chromium/gpu/command_buffer/client/gles2_trace_implementation.h index 18e6a793cfe..c215231e8e7 100644 --- a/chromium/gpu/command_buffer/client/gles2_trace_implementation.h +++ b/chromium/gpu/command_buffer/client/gles2_trace_implementation.h @@ -5,15 +5,16 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_H_ #define GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_H_ +#include "base/compiler_specific.h" #include "gles2_impl_export.h" #include "gpu/command_buffer/client/gles2_interface.h" -#include "gpu/command_buffer/common/compiler_specific.h" namespace gpu { namespace gles2 { // GLES2TraceImplementation is calls TRACE for every GL call. -class GLES2_IMPL_EXPORT GLES2TraceImplementation : public GLES2Interface { +class GLES2_IMPL_EXPORT GLES2TraceImplementation + : NON_EXPORTED_BASE(public GLES2Interface) { public: explicit GLES2TraceImplementation(GLES2Interface* gl); virtual ~GLES2TraceImplementation(); diff --git a/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 4f3ce31b88a..d811db571a8 100644 --- a/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h @@ -241,10 +241,13 @@ virtual void VertexAttribPointer( const void* ptr) OVERRIDE; virtual void Viewport( GLint x, GLint y, GLsizei width, GLsizei height) OVERRIDE; -virtual void BlitFramebufferEXT( +virtual void BlitFramebufferCHROMIUM( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) OVERRIDE; +virtual void RenderbufferStorageMultisampleCHROMIUM( + GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height) OVERRIDE; virtual void RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) OVERRIDE; @@ -350,5 +353,6 @@ virtual void LoseContextCHROMIUM(GLenum current, GLenum other) OVERRIDE; virtual GLuint InsertSyncPointCHROMIUM() OVERRIDE; virtual void WaitSyncPointCHROMIUM(GLuint sync_point) OVERRIDE; virtual void DrawBuffersEXT(GLsizei count, const GLenum* bufs) OVERRIDE; +virtual void DiscardBackbufferCHROMIUM() OVERRIDE; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 1a2604a3974..49d7ab2a947 100644 --- a/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h @@ -838,14 +838,22 @@ void GLES2TraceImplementation::Viewport( gl_->Viewport(x, y, width, height); } -void GLES2TraceImplementation::BlitFramebufferEXT( +void GLES2TraceImplementation::BlitFramebufferCHROMIUM( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BlitFramebufferEXT"); - gl_->BlitFramebufferEXT( + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BlitFramebufferCHROMIUM"); + gl_->BlitFramebufferCHROMIUM( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } +void GLES2TraceImplementation::RenderbufferStorageMultisampleCHROMIUM( + GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::RenderbufferStorageMultisampleCHROMIUM"); // NOLINT + gl_->RenderbufferStorageMultisampleCHROMIUM( + target, samples, internalformat, width, height); +} + void GLES2TraceImplementation::RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { @@ -1229,5 +1237,10 @@ void GLES2TraceImplementation::DrawBuffersEXT( gl_->DrawBuffersEXT(count, bufs); } +void GLES2TraceImplementation::DiscardBackbufferCHROMIUM() { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DiscardBackbufferCHROMIUM"); + gl_->DiscardBackbufferCHROMIUM(); +} + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_IMPL_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc b/chromium/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc index a957cc4b8dc..863028ad125 100644 --- a/chromium/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc +++ b/chromium/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc @@ -32,7 +32,7 @@ int32 GpuMemoryBufferTracker::CreateBuffer( std::pair<BufferMap::iterator, bool> result = buffers_.insert(std::make_pair(image_id, buffer)); - GPU_DCHECK(result.second); + DCHECK(result.second); return image_id; } diff --git a/chromium/gpu/command_buffer/client/gpu_memory_buffer_tracker.h b/chromium/gpu/command_buffer/client/gpu_memory_buffer_tracker.h index 0b07dd0a148..84158818a37 100644 --- a/chromium/gpu/command_buffer/client/gpu_memory_buffer_tracker.h +++ b/chromium/gpu/command_buffer/client/gpu_memory_buffer_tracker.h @@ -6,8 +6,8 @@ #define GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_TRACKER_H_ #include "base/basictypes.h" +#include "base/containers/hash_tables.h" #include "gles2_impl_export.h" -#include "gpu/command_buffer/client/hash_tables.h" namespace gfx { class GpuMemoryBuffer; @@ -29,7 +29,7 @@ class GLES2_IMPL_EXPORT GpuMemoryBufferTracker { void RemoveBuffer(int32 image_id); private: - typedef gpu::hash_map<int32, gfx::GpuMemoryBuffer*> BufferMap; + typedef base::hash_map<int32, gfx::GpuMemoryBuffer*> BufferMap; BufferMap buffers_; GpuControl* gpu_control_; diff --git a/chromium/gpu/command_buffer/client/hash_tables.h b/chromium/gpu/command_buffer/client/hash_tables.h deleted file mode 100644 index fff3098dea6..00000000000 --- a/chromium/gpu/command_buffer/client/hash_tables.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_HASH_TABLES_H_ -#define GPU_COMMAND_BUFFER_CLIENT_HASH_TABLES_H_ - -#if defined(__native_client__) -#include <tr1/unordered_map> -namespace gpu { -template <typename key, typename value> -struct hash_map : public std::tr1::unordered_map<key, value> { -}; -} -#else -#include "base/containers/hash_tables.h" -namespace gpu { -template <typename key, typename value> -struct hash_map : public base::hash_map<key, value> { -}; -} -#endif - -#endif // GPU_COMMAND_BUFFER_CLIENT_HASH_TABLES_H_ diff --git a/chromium/gpu/command_buffer/client/mapped_memory.cc b/chromium/gpu/command_buffer/client/mapped_memory.cc index c367e696c50..15584aaaf07 100644 --- a/chromium/gpu/command_buffer/client/mapped_memory.cc +++ b/chromium/gpu/command_buffer/client/mapped_memory.cc @@ -8,6 +8,7 @@ #include <functional> #include "base/debug/trace_event.h" +#include "base/logging.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" namespace gpu { @@ -38,8 +39,8 @@ MappedMemoryManager::~MappedMemoryManager() { void* MappedMemoryManager::Alloc( unsigned int size, int32* shm_id, unsigned int* shm_offset) { - GPU_DCHECK(shm_id); - GPU_DCHECK(shm_offset); + DCHECK(shm_id); + DCHECK(shm_offset); if (size <= allocated_memory_) { size_t total_bytes_in_use = 0; // See if any of the chunks can satisfy this request. @@ -49,7 +50,7 @@ void* MappedMemoryManager::Alloc( total_bytes_in_use += chunk->bytes_in_use(); if (chunk->GetLargestFreeSizeWithoutWaiting() >= size) { void* mem = chunk->Alloc(size); - GPU_DCHECK(mem); + DCHECK(mem); *shm_id = chunk->shm_id(); *shm_offset = chunk->GetOffset(mem); return mem; @@ -66,7 +67,7 @@ void* MappedMemoryManager::Alloc( MemoryChunk* chunk = chunks_[ii]; if (chunk->GetLargestFreeSizeWithWaiting() >= size) { void* mem = chunk->Alloc(size); - GPU_DCHECK(mem); + DCHECK(mem); *shm_id = chunk->shm_id(); *shm_offset = chunk->GetOffset(mem); return mem; @@ -88,7 +89,7 @@ void* MappedMemoryManager::Alloc( allocated_memory_ += mc->GetSize(); chunks_.push_back(mc); void* mem = mc->Alloc(size); - GPU_DCHECK(mem); + DCHECK(mem); *shm_id = mc->shm_id(); *shm_offset = mc->GetOffset(mem); return mem; @@ -102,7 +103,7 @@ void MappedMemoryManager::Free(void* pointer) { return; } } - GPU_NOTREACHED(); + NOTREACHED(); } void MappedMemoryManager::FreePendingToken(void* pointer, int32 token) { @@ -113,7 +114,7 @@ void MappedMemoryManager::FreePendingToken(void* pointer, int32 token) { return; } } - GPU_NOTREACHED(); + NOTREACHED(); } void MappedMemoryManager::FreeUnused() { diff --git a/chromium/gpu/command_buffer/client/mapped_memory.h b/chromium/gpu/command_buffer/client/mapped_memory.h index db73ca7a609..b8f3129eb4a 100644 --- a/chromium/gpu/command_buffer/client/mapped_memory.h +++ b/chromium/gpu/command_buffer/client/mapped_memory.h @@ -33,7 +33,7 @@ class GPU_EXPORT MemoryChunk { // Gets the size of the chunk. unsigned int GetSize() const { - return shm_.size; + return static_cast<unsigned int>(shm_.size); } // The shared memory id for this chunk. diff --git a/chromium/gpu/command_buffer/client/program_info_manager.cc b/chromium/gpu/command_buffer/client/program_info_manager.cc index fb0c1f3f940..1b5a348d6cc 100644 --- a/chromium/gpu/command_buffer/client/program_info_manager.cc +++ b/chromium/gpu/command_buffer/client/program_info_manager.cc @@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "gpu/command_buffer/client/program_info_manager.h" + #include <map> #include "base/compiler_specific.h" -#include "gpu/command_buffer/client/atomicops.h" +#include "base/synchronization/lock.h" #include "gpu/command_buffer/client/gles2_implementation.h" -#include "gpu/command_buffer/client/program_info_manager.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" namespace gpu { @@ -220,7 +221,7 @@ class CachedProgramInfoManager : public ProgramInfoManager { ProgramInfoMap program_infos_; - mutable Lock lock_; + mutable base::Lock lock_; }; CachedProgramInfoManager::Program::UniformInfo::UniformInfo( @@ -229,7 +230,7 @@ CachedProgramInfoManager::Program::UniformInfo::UniformInfo( type(_type), name(_name) { is_array = (!name.empty() && name[name.size() - 1] == ']'); - GPU_DCHECK(!(size > 1 && !is_array)); + DCHECK(!(size > 1 && !is_array)); } CachedProgramInfoManager::Program::Program() @@ -308,7 +309,7 @@ template<typename T> static T LocalGetAs( const std::vector<int8>& data, uint32 offset, size_t size) { const int8* p = &data[0] + offset; if (offset + size > data.size()) { - GPU_NOTREACHED(); + NOTREACHED(); return NULL; } return static_cast<T>(static_cast<const void*>(p)); @@ -325,7 +326,7 @@ void CachedProgramInfoManager::Program::Update( // This should only happen on a lost context. return; } - GPU_DCHECK_GE(result.size(), sizeof(ProgramInfoHeader)); + DCHECK_GE(result.size(), sizeof(ProgramInfoHeader)); const ProgramInfoHeader* header = LocalGetAs<const ProgramInfoHeader*>( result, 0, sizeof(header)); link_status_ = header->link_status != 0; @@ -367,7 +368,7 @@ void CachedProgramInfoManager::Program::Update( uniform_infos_.push_back(info); ++input; } - GPU_DCHECK_EQ(header->num_attribs + header->num_uniforms, + DCHECK_EQ(header->num_attribs + header->num_uniforms, static_cast<uint32>(input - inputs)); cached_ = true; } @@ -392,12 +393,12 @@ CachedProgramInfoManager::Program* } void CachedProgramInfoManager::CreateInfo(GLuint program) { - AutoLock auto_lock(lock_); + base::AutoLock auto_lock(lock_); DeleteInfo(program); std::pair<ProgramInfoMap::iterator, bool> result = program_infos_.insert(std::make_pair(program, Program())); - GPU_DCHECK(result.second); + DCHECK(result.second); } void CachedProgramInfoManager::DeleteInfo(GLuint program) { @@ -406,7 +407,7 @@ void CachedProgramInfoManager::DeleteInfo(GLuint program) { bool CachedProgramInfoManager::GetProgramiv( GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) { - AutoLock auto_lock(lock_); + base::AutoLock auto_lock(lock_); Program* info = GetProgramInfo(gl, program); if (!info) { return false; @@ -416,7 +417,7 @@ bool CachedProgramInfoManager::GetProgramiv( GLint CachedProgramInfoManager::GetAttribLocation( GLES2Implementation* gl, GLuint program, const char* name) { - AutoLock auto_lock(lock_); + base::AutoLock auto_lock(lock_); Program* info = GetProgramInfo(gl, program); if (info) { return info->GetAttribLocation(name); @@ -426,7 +427,7 @@ GLint CachedProgramInfoManager::GetAttribLocation( GLint CachedProgramInfoManager::GetUniformLocation( GLES2Implementation* gl, GLuint program, const char* name) { - AutoLock auto_lock(lock_); + base::AutoLock auto_lock(lock_); Program* info = GetProgramInfo(gl, program); if (info) { return info->GetUniformLocation(name); @@ -438,7 +439,7 @@ bool CachedProgramInfoManager::GetActiveAttrib( GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { - AutoLock auto_lock(lock_); + base::AutoLock auto_lock(lock_); Program* info = GetProgramInfo(gl, program); if (info) { const Program::VertexAttrib* attrib_info = @@ -473,7 +474,7 @@ bool CachedProgramInfoManager::GetActiveUniform( GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { - AutoLock auto_lock(lock_); + base::AutoLock auto_lock(lock_); Program* info = GetProgramInfo(gl, program); if (info) { const Program::UniformInfo* uniform_info = info->GetUniformInfo(index); diff --git a/chromium/gpu/command_buffer/client/query_tracker.cc b/chromium/gpu/command_buffer/client/query_tracker.cc index 307b615c6fd..285560590b3 100644 --- a/chromium/gpu/command_buffer/client/query_tracker.cc +++ b/chromium/gpu/command_buffer/client/query_tracker.cc @@ -8,7 +8,6 @@ #include <GLES2/gl2ext.h> #include <GLES2/gl2extchromium.h> -#include "gpu/command_buffer/client/atomicops.h" #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "gpu/command_buffer/client/mapped_memory.h" @@ -19,7 +18,7 @@ namespace gles2 { QuerySyncManager::QuerySyncManager(MappedMemoryManager* manager) : mapped_memory_(manager) { - GPU_DCHECK(manager); + DCHECK(manager); } QuerySyncManager::~QuerySyncManager() { @@ -31,7 +30,7 @@ QuerySyncManager::~QuerySyncManager() { } bool QuerySyncManager::Alloc(QuerySyncManager::QueryInfo* info) { - GPU_DCHECK(info); + DCHECK(info); if (free_queries_.empty()) { int32 shm_id; unsigned int shm_offset; @@ -151,14 +150,14 @@ bool QueryTracker::Query::CheckResultsAvailable( helper->IsContextLost()) { // Need a MemoryBarrier here so that sync->result read after // sync->process_count. - gpu::MemoryBarrier(); + base::subtle::MemoryBarrier(); switch (target()) { case GL_COMMANDS_ISSUED_CHROMIUM: result_ = std::min(info_.sync->result, static_cast<uint64>(0xFFFFFFFFL)); break; case GL_LATENCY_QUERY_CHROMIUM: - GPU_DCHECK(info_.sync->result >= client_begin_time_us_); + DCHECK(info_.sync->result >= client_begin_time_us_); result_ = std::min(info_.sync->result - client_begin_time_us_, static_cast<uint64>(0xFFFFFFFFL)); break; @@ -187,7 +186,7 @@ bool QueryTracker::Query::CheckResultsAvailable( } uint32 QueryTracker::Query::GetResult() const { - GPU_DCHECK(state_ == kComplete || state_ == kUninitialized); + DCHECK(state_ == kComplete || state_ == kUninitialized); return result_; } @@ -207,7 +206,7 @@ QueryTracker::~QueryTracker() { } QueryTracker::Query* QueryTracker::CreateQuery(GLuint id, GLenum target) { - GPU_DCHECK_NE(0u, id); + DCHECK_NE(0u, id); FreeCompletedQueries(); QuerySyncManager::QueryInfo info; if (!query_sync_manager_.Alloc(&info)) { @@ -216,7 +215,7 @@ QueryTracker::Query* QueryTracker::CreateQuery(GLuint id, GLenum target) { Query* query = new Query(id, target, info); std::pair<QueryMap::iterator, bool> result = queries_.insert(std::make_pair(id, query)); - GPU_DCHECK(result.second); + DCHECK(result.second); return query; } diff --git a/chromium/gpu/command_buffer/client/query_tracker.h b/chromium/gpu/command_buffer/client/query_tracker.h index 81861c997a9..9e7f501768b 100644 --- a/chromium/gpu/command_buffer/client/query_tracker.h +++ b/chromium/gpu/command_buffer/client/query_tracker.h @@ -10,8 +10,8 @@ #include <deque> #include <list> +#include "base/containers/hash_tables.h" #include "gles2_impl_export.h" -#include "gpu/command_buffer/client/hash_tables.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" namespace gpu { @@ -161,7 +161,7 @@ class GLES2_IMPL_EXPORT QueryTracker { void FreeCompletedQueries(); private: - typedef gpu::hash_map<GLuint, Query*> QueryMap; + typedef base::hash_map<GLuint, Query*> QueryMap; typedef std::list<Query*> QueryList; QueryMap queries_; diff --git a/chromium/gpu/command_buffer/client/ring_buffer.cc b/chromium/gpu/command_buffer/client/ring_buffer.cc index 42e09bd3e1f..25f63425d85 100644 --- a/chromium/gpu/command_buffer/client/ring_buffer.cc +++ b/chromium/gpu/command_buffer/client/ring_buffer.cc @@ -5,7 +5,10 @@ // This file contains the implementation of the RingBuffer class. #include "gpu/command_buffer/client/ring_buffer.h" + #include <algorithm> + +#include "base/logging.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" namespace gpu { @@ -27,9 +30,9 @@ RingBuffer::~RingBuffer() { } void RingBuffer::FreeOldestBlock() { - GPU_DCHECK(!blocks_.empty()) << "no free blocks"; + DCHECK(!blocks_.empty()) << "no free blocks"; Block& block = blocks_.front(); - GPU_DCHECK(block.state != IN_USE) + DCHECK(block.state != IN_USE) << "attempt to allocate more than maximum memory"; if (block.state == FREE_PENDING_TOKEN) { helper_->WaitForToken(block.token); @@ -47,8 +50,8 @@ void RingBuffer::FreeOldestBlock() { } RingBuffer::Offset RingBuffer::Alloc(unsigned int size) { - GPU_DCHECK_LE(size, size_) << "attempt to allocate more than maximum memory"; - GPU_DCHECK(blocks_.empty() || blocks_.back().state != IN_USE) + DCHECK_LE(size, size_) << "attempt to allocate more than maximum memory"; + DCHECK(blocks_.empty() || blocks_.back().state != IN_USE) << "Attempt to alloc another block before freeing the previous."; // Similarly to malloc, an allocation of 0 allocates at least 1 byte, to // return different pointers every time. @@ -77,20 +80,20 @@ RingBuffer::Offset RingBuffer::Alloc(unsigned int size) { void RingBuffer::FreePendingToken(RingBuffer::Offset offset, unsigned int token) { offset -= base_offset_; - GPU_DCHECK(!blocks_.empty()) << "no allocations to free"; + DCHECK(!blocks_.empty()) << "no allocations to free"; for (Container::reverse_iterator it = blocks_.rbegin(); it != blocks_.rend(); ++it) { Block& block = *it; if (block.offset == offset) { - GPU_DCHECK(block.state == IN_USE) + DCHECK(block.state == IN_USE) << "block that corresponds to offset already freed"; block.token = token; block.state = FREE_PENDING_TOKEN; return; } } - GPU_NOTREACHED() << "attempt to free non-existant block"; + NOTREACHED() << "attempt to free non-existant block"; } unsigned int RingBuffer::GetLargestFreeSizeNoWaiting() { @@ -103,7 +106,7 @@ unsigned int RingBuffer::GetLargestFreeSizeNoWaiting() { if (free_offset_ == in_use_offset_) { if (blocks_.empty()) { // The entire buffer is free. - GPU_DCHECK_EQ(free_offset_, 0u); + DCHECK_EQ(free_offset_, 0u); return size_; } else { // The entire buffer is in use. diff --git a/chromium/gpu/command_buffer/client/ring_buffer.h b/chromium/gpu/command_buffer/client/ring_buffer.h index d1f70a26c69..81f1cddafa5 100644 --- a/chromium/gpu/command_buffer/client/ring_buffer.h +++ b/chromium/gpu/command_buffer/client/ring_buffer.h @@ -9,7 +9,7 @@ #include <deque> -#include "gpu/command_buffer/common/logging.h" +#include "base/logging.h" #include "gpu/command_buffer/common/types.h" #include "gpu/gpu_export.h" @@ -162,7 +162,7 @@ class RingBufferWrapper { // pointer: the pointer to the memory block to free. // token: the token value to wait for before re-using the memory. void FreePendingToken(void* pointer, unsigned int token) { - GPU_DCHECK(pointer); + DCHECK(pointer); allocator_.FreePendingToken(GetOffset(pointer), token); } diff --git a/chromium/gpu/command_buffer/client/share_group.cc b/chromium/gpu/command_buffer/client/share_group.cc index 9526df2efd6..cb9f9bca5c6 100644 --- a/chromium/gpu/command_buffer/client/share_group.cc +++ b/chromium/gpu/command_buffer/client/share_group.cc @@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "gpu/command_buffer/client/atomicops.h" +#include "gpu/command_buffer/client/share_group.h" + +#include "base/logging.h" +#include "base/synchronization/lock.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "gpu/command_buffer/client/program_info_manager.h" -#include "gpu/command_buffer/client/share_group.h" #include "gpu/command_buffer/common/id_allocator.h" -#include "gpu/command_buffer/common/logging.h" namespace gpu { namespace gles2 { @@ -67,7 +68,7 @@ class StrictIdHandler : public IdHandler { // Overridden from IdHandler. virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE { - GPU_DCHECK(id == 0 || id_allocator_.InUse(id)); + DCHECK(id == 0 || id_allocator_.InUse(id)); return IdHandler::MarkAsUsedForBind(id); } }; @@ -156,7 +157,7 @@ class ThreadSafeIdHandlerWrapper : public IdHandlerInterface { GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE { - AutoLock auto_lock(lock_); + base::AutoLock auto_lock(lock_); id_handler_->MakeIds(gl_impl, id_offset, n, ids); } @@ -165,19 +166,19 @@ class ThreadSafeIdHandlerWrapper : public IdHandlerInterface { GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE { - AutoLock auto_lock(lock_); + base::AutoLock auto_lock(lock_); return id_handler_->FreeIds(gl_impl, n, ids, delete_fn); } // Overridden from IdHandlerInterface. virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE { - AutoLock auto_lock(lock_); + base::AutoLock auto_lock(lock_); return id_handler_->MarkAsUsedForBind(id); } private: scoped_ptr<IdHandlerInterface> id_handler_; - Lock lock_; + base::Lock lock_; }; ShareGroup::ShareGroup(bool bind_generates_resource) diff --git a/chromium/gpu/command_buffer/client/transfer_buffer.cc b/chromium/gpu/command_buffer/client/transfer_buffer.cc index f4fe66c9d64..c4b84a14f32 100644 --- a/chromium/gpu/command_buffer/client/transfer_buffer.cc +++ b/chromium/gpu/command_buffer/client/transfer_buffer.cc @@ -5,6 +5,8 @@ // A class to Manage a growing transfer buffer. #include "gpu/command_buffer/client/transfer_buffer.h" + +#include "base/logging.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" namespace gpu { @@ -118,7 +120,7 @@ static int Log2Floor(uint32 n) { log += shift; } } - GPU_DCHECK_EQ(value, 1u); + DCHECK_EQ(value, 1u); return log; } @@ -153,7 +155,7 @@ void TransferBuffer::ReallocateRingBuffer(unsigned int size) { void* TransferBuffer::AllocUpTo( unsigned int size, unsigned int* size_allocated) { - GPU_DCHECK(size_allocated); + DCHECK(size_allocated); ReallocateRingBuffer(size); diff --git a/chromium/gpu/command_buffer/client/transfer_buffer.h b/chromium/gpu/command_buffer/client/transfer_buffer.h index 273f0170bb0..11173985819 100644 --- a/chromium/gpu/command_buffer/client/transfer_buffer.h +++ b/chromium/gpu/command_buffer/client/transfer_buffer.h @@ -5,10 +5,10 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_ #define GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_ +#include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/client/ring_buffer.h" #include "gpu/command_buffer/common/buffer.h" -#include "gpu/command_buffer/common/compiler_specific.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/gpu_export.h" diff --git a/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc b/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc index 411e662871f..39ce923f78c 100644 --- a/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc +++ b/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc @@ -6,10 +6,10 @@ #include "gpu/command_buffer/client/transfer_buffer.h" +#include "base/compiler_specific.h" #include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" #include "gpu/command_buffer/common/command_buffer.h" -#include "gpu/command_buffer/common/compiler_specific.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gmock/include/gmock/gmock.h" diff --git a/chromium/gpu/command_buffer/client/vertex_array_object_manager.cc b/chromium/gpu/command_buffer/client/vertex_array_object_manager.cc index f2a156e9560..3e98bd08450 100644 --- a/chromium/gpu/command_buffer/client/vertex_array_object_manager.cc +++ b/chromium/gpu/command_buffer/client/vertex_array_object_manager.cc @@ -4,9 +4,9 @@ #include "gpu/command_buffer/client/vertex_array_object_manager.h" +#include "base/logging.h" #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/gles2_implementation.h" -#include "gpu/command_buffer/common/logging.h" #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS @@ -234,7 +234,7 @@ void VertexArrayObject::SetAttribEnable(GLuint index, bool enabled) { if (attrib.enabled() != enabled) { if (attrib.IsClientSide()) { num_client_side_pointers_enabled_ += enabled ? 1 : -1; - GPU_DCHECK_GE(num_client_side_pointers_enabled_, 0); + DCHECK_GE(num_client_side_pointers_enabled_, 0); } attrib.set_enabled(enabled); } @@ -253,7 +253,7 @@ void VertexArrayObject::SetAttribPointer( VertexAttrib& attrib = vertex_attribs_[index]; if (attrib.IsClientSide() && attrib.enabled()) { --num_client_side_pointers_enabled_; - GPU_DCHECK_GE(num_client_side_pointers_enabled_, 0); + DCHECK_GE(num_client_side_pointers_enabled_, 0); } attrib.SetInfo(buffer_id, size, type, normalized, stride, ptr); @@ -368,18 +368,18 @@ bool VertexArrayObjectManager::BindElementArray(GLuint id) { void VertexArrayObjectManager::GenVertexArrays( GLsizei n, const GLuint* arrays) { - GPU_DCHECK_GE(n, 0); + DCHECK_GE(n, 0); for (GLsizei i = 0; i < n; ++i) { std::pair<VertexArrayObjectMap::iterator, bool> result = vertex_array_objects_.insert(std::make_pair( arrays[i], new VertexArrayObject(max_vertex_attribs_))); - GPU_DCHECK(result.second); + DCHECK(result.second); } } void VertexArrayObjectManager::DeleteVertexArrays( GLsizei n, const GLuint* arrays) { - GPU_DCHECK_GE(n, 0); + DCHECK_GE(n, 0); for (GLsizei i = 0; i < n; ++i) { GLuint id = arrays[i]; if (id) { @@ -534,7 +534,7 @@ bool VertexArrayObjectManager::SetupSimulatedClientSideBuffers( ii, attrib.size(), attrib.type(), attrib.normalized(), 0, array_buffer_offset_); array_buffer_offset_ += RoundUpToMultipleOf4(bytes_collected); - GPU_DCHECK_LE(array_buffer_offset_, array_buffer_size_); + DCHECK_LE(array_buffer_offset_, array_buffer_size_); } } #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) diff --git a/chromium/gpu/command_buffer/client/vertex_array_object_manager.h b/chromium/gpu/command_buffer/client/vertex_array_object_manager.h index 254b15da055..d5b07ec0e88 100644 --- a/chromium/gpu/command_buffer/client/vertex_array_object_manager.h +++ b/chromium/gpu/command_buffer/client/vertex_array_object_manager.h @@ -6,9 +6,9 @@ #define GPU_COMMAND_BUFFER_CLIENT_VERTEX_ARRAY_OBJECT_MANAGER_H_ #include <GLES2/gl2.h> +#include "base/containers/hash_tables.h" #include "base/memory/scoped_ptr.h" #include "gles2_impl_export.h" -#include "gpu/command_buffer/client/hash_tables.h" #include "gpu/command_buffer/common/types.h" namespace gpu { @@ -93,7 +93,7 @@ class GLES2_IMPL_EXPORT VertexArrayObjectManager { GLuint bound_element_array_buffer() const; private: - typedef gpu::hash_map<GLuint, VertexArrayObject*> VertexArrayObjectMap; + typedef base::hash_map<GLuint, VertexArrayObject*> VertexArrayObjectMap; bool IsDefaultVAOBound() const; diff --git a/chromium/gpu/command_buffer/cmd_buffer_functions.txt b/chromium/gpu/command_buffer/cmd_buffer_functions.txt index f7b9a5b74b5..eeb47601658 100644 --- a/chromium/gpu/command_buffer/cmd_buffer_functions.txt +++ b/chromium/gpu/command_buffer/cmd_buffer_functions.txt @@ -148,7 +148,8 @@ GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GL GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLintVertexAttribSize size, GLenumVertexAttribType type, GLboolean normalized, GLsizei stride, const void* ptr); GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenumBlitFilter filter); +GL_APICALL void GL_APIENTRY glBlitFramebufferCHROMIUM (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenumBlitFilter filter); +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleCHROMIUM (GLenumRenderBufferTarget target, GLsizei samples, GLenumRenderBufferFormat internalformat, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenumRenderBufferTarget target, GLsizei samples, GLenumRenderBufferFormat internalformat, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenumFrameBufferTarget target, GLenumAttachment attachment, GLenumTextureTarget textarget, GLidTexture texture, GLintZeroOnly level, GLsizei samples); GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenumTextureTarget target, GLsizei levels, GLenumTextureInternalFormatStorage internalFormat, GLsizei width, GLsizei height); @@ -218,5 +219,6 @@ GL_APICALL void GL_APIENTRY glLoseContextCHROMIUM (GLenum current, GLenu GL_APICALL GLuint GL_APIENTRY glInsertSyncPointCHROMIUM (void); GL_APICALL void GL_APIENTRY glWaitSyncPointCHROMIUM (GLuint sync_point); GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei count, const GLenum* bufs); +GL_APICALL void GL_APIENTRY glDiscardBackbufferCHROMIUM (void); diff --git a/chromium/gpu/command_buffer/command_buffer.gypi b/chromium/gpu/command_buffer/command_buffer.gypi index e63a1c1b7f1..473da92eebd 100644 --- a/chromium/gpu/command_buffer/command_buffer.gypi +++ b/chromium/gpu/command_buffer/command_buffer.gypi @@ -18,18 +18,6 @@ 'common/gles2_cmd_utils.cc', 'common/gles2_cmd_utils.h', 'common/gles2_utils_export.h', - 'common/logging.cc', - 'common/logging.h', - ], - 'conditions': [ - ['OS=="android"', { - 'sources!': [ - 'common/logging.cc', - ], - 'sources': [ - 'common/logging_android.cc', - ], - }], ], }], ], diff --git a/chromium/gpu/command_buffer/common/capabilities.cc b/chromium/gpu/command_buffer/common/capabilities.cc new file mode 100644 index 00000000000..9f35c8258d3 --- /dev/null +++ b/chromium/gpu/command_buffer/common/capabilities.cc @@ -0,0 +1,22 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/command_buffer/common/capabilities.h" + +namespace gpu { + +Capabilities::Capabilities() + : post_sub_buffer(false), + fast_npot_mo8_textures(false), + egl_image_external(false), + texture_format_bgra8888(false), + texture_format_etc1(false), + texture_rectangle(false), + iosurface(false), + texture_usage(false), + texture_storage(false), + discard_framebuffer(false), + map_image(false) {} + +} // namespace gpu diff --git a/chromium/gpu/command_buffer/common/capabilities.h b/chromium/gpu/command_buffer/common/capabilities.h new file mode 100644 index 00000000000..b6c34daeefa --- /dev/null +++ b/chromium/gpu/command_buffer/common/capabilities.h @@ -0,0 +1,32 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_COMMON_CAPABILITIES_H_ +#define GPU_COMMAND_BUFFER_COMMON_CAPABILITIES_H_ + +#include "gpu/gpu_export.h" + +namespace gpu { + +struct GPU_EXPORT Capabilities { + bool post_sub_buffer; + bool fast_npot_mo8_textures; + bool egl_image_external; + bool texture_format_bgra8888; + bool texture_format_etc1; + bool texture_rectangle; + bool iosurface; + bool texture_usage; + bool texture_storage; + bool discard_framebuffer; + + // Capabilities below are not populated by GLES2Decoder. + bool map_image; + + Capabilities(); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_COMMON_CAPABILITIES_H_ diff --git a/chromium/gpu/command_buffer/common/cmd_buffer_common.cc b/chromium/gpu/command_buffer/common/cmd_buffer_common.cc index bfa625c7384..80a1e16dc3c 100644 --- a/chromium/gpu/command_buffer/common/cmd_buffer_common.cc +++ b/chromium/gpu/command_buffer/common/cmd_buffer_common.cc @@ -6,8 +6,8 @@ // command buffer commands. #include "gpu/command_buffer/common/cmd_buffer_common.h" + #include "gpu/command_buffer/common/command_buffer.h" -#include "gpu/command_buffer/common/logging.h" namespace gpu { #if !defined(_WIN32) diff --git a/chromium/gpu/command_buffer/common/cmd_buffer_common.h b/chromium/gpu/command_buffer/common/cmd_buffer_common.h index 090819805a5..cf09378e00c 100644 --- a/chromium/gpu/command_buffer/common/cmd_buffer_common.h +++ b/chromium/gpu/command_buffer/common/cmd_buffer_common.h @@ -9,8 +9,8 @@ #include <stddef.h> +#include "base/logging.h" #include "gpu/command_buffer/common/bitfield_helpers.h" -#include "gpu/command_buffer/common/logging.h" #include "gpu/command_buffer/common/types.h" #include "gpu/gpu_export.h" @@ -43,7 +43,7 @@ struct CommandHeader { GPU_EXPORT static const int32 kMaxSize = (1 << 21) - 1; void Init(uint32 _command, int32 _size) { - GPU_DCHECK_LE(_size, kMaxSize); + DCHECK_LE(_size, kMaxSize); command = _command; size = _size; } @@ -68,7 +68,7 @@ struct CommandHeader { template <typename T> void SetCmdByTotalSize(uint32 size_in_bytes) { COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); - GPU_DCHECK_GE(size_in_bytes, sizeof(T)); // NOLINT + DCHECK_GE(size_in_bytes, sizeof(T)); // NOLINT Init(T::kCmdId, ComputeNumEntries(size_in_bytes)); } }; @@ -133,7 +133,7 @@ void* NextImmediateCmdAddress(void* cmd, uint32 size_of_data_in_bytes) { template <typename T> void* NextImmediateCmdAddressTotalSize(void* cmd, uint32 total_size_in_bytes) { COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); - GPU_DCHECK_GE(total_size_in_bytes, sizeof(T)); // NOLINT + DCHECK_GE(total_size_in_bytes, sizeof(T)); // NOLINT return reinterpret_cast<char*>(cmd) + RoundSizeToMultipleOfEntries(total_size_in_bytes); } @@ -179,7 +179,7 @@ struct Noop { static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; void SetHeader(uint32 skip_count) { - GPU_DCHECK_GT(skip_count, 0u); + DCHECK_GT(skip_count, 0u); header.Init(kCmdId, skip_count); } diff --git a/chromium/gpu/command_buffer/common/command_buffer.h b/chromium/gpu/command_buffer/common/command_buffer.h index 3078bca2ba3..394ccf3c4f7 100644 --- a/chromium/gpu/command_buffer/common/command_buffer.h +++ b/chromium/gpu/command_buffer/common/command_buffer.h @@ -137,10 +137,6 @@ class GPU_EXPORT CommandBuffer { virtual error::Error GetLastError(); #endif - // Inserts a sync point, returning its ID. Sync point IDs are global and can - // be used for cross-context synchronization. - virtual uint32 InsertSyncPoint() = 0; - private: DISALLOW_COPY_AND_ASSIGN(CommandBuffer); }; diff --git a/chromium/gpu/command_buffer/common/compiler_specific.h b/chromium/gpu/command_buffer/common/compiler_specific.h deleted file mode 100644 index 2669bff5740..00000000000 --- a/chromium/gpu/command_buffer/common/compiler_specific.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef GPU_COMMAND_BUFFER_COMMON_COMPILER_SPECIFIC_H_ -#define GPU_COMMAND_BUFFER_COMMON_COMPILER_SPECIFIC_H_ - -// Annotate a virtual method indicating it must be overriding a virtual -// method in the parent class. -// Use like: -// virtual void foo() OVERRIDE; -#ifndef OVERRIDE -#ifdef _MSC_VER -#define OVERRIDE override -#elif defined(__clang__) -#define OVERRIDE override -#else -#define OVERRIDE -#endif -#endif - -#endif // GPU_COMMAND_BUFFER_COMMON_COMPILER_SPECIFIC_H_ diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format.h b/chromium/gpu/command_buffer/common/gles2_cmd_format.h index 76bb3fe1d4d..b2ab12e7063 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format.h @@ -243,66 +243,6 @@ COMPILE_ASSERT(offsetof(GetAttribLocation, location_shm_offset) == 20, COMPILE_ASSERT(offsetof(GetAttribLocation, data_size) == 24, OffsetOf_GetAttribLocation_data_size_not_24); -struct GetAttribLocationImmediate { - typedef GetAttribLocationImmediate ValueType; - static const CommandId kCmdId = kGetAttribLocationImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - typedef GLint Result; - - static uint32 ComputeDataSize(const char* s) { - return base::checked_numeric_cast<uint32>(strlen(s)); - } - - static uint32 ComputeSize(const char* s) { - return base::checked_numeric_cast<uint32>(sizeof(ValueType) + - ComputeDataSize(s)); - } - - void SetHeader(const char* s) { - header.SetCmdByTotalSize<ValueType>(ComputeSize(s)); - } - - void Init( - GLuint _program, const char* _name, - uint32 _location_shm_id, uint32 _location_shm_offset) { - SetHeader(_name); - program = _program; - location_shm_id = _location_shm_id; - location_shm_offset = _location_shm_offset; - data_size = ComputeDataSize(_name); - memcpy(ImmediateDataAddress(this), _name, data_size); - } - - void* Set( - void* cmd, GLuint _program, const char* _name, - uint32 _location_shm_id, uint32 _location_shm_offset) { - uint32 total_size = ComputeSize(_name); - static_cast<ValueType*>( - cmd)->Init(_program, _name, _location_shm_id, _location_shm_offset); - return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); - } - - CommandHeader header; - uint32 program; - uint32 location_shm_id; - uint32 location_shm_offset; - uint32 data_size; -}; - -COMPILE_ASSERT(sizeof(GetAttribLocationImmediate) == 20, - Sizeof_GetAttribLocationImmediate_is_not_20); -COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, header) == 0, - OffsetOf_GetAttribLocationImmediate_header_not_0); -COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, program) == 4, - OffsetOf_GetAttribLocationImmediate_program_not_4); -COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, location_shm_id) == 8, - OffsetOf_GetAttribLocationImmediate_location_shm_id_not_8); -COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, location_shm_offset) == 12, - OffsetOf_GetAttribLocationImmediate_location_shm_offset_not_12); -COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, data_size) == 16, - OffsetOf_GetAttribLocationImmediate_data_size_not_16); - struct GetAttribLocationBucket { typedef GetAttribLocationBucket ValueType; @@ -424,67 +364,6 @@ COMPILE_ASSERT(offsetof(GetUniformLocation, location_shm_offset) == 20, COMPILE_ASSERT(offsetof(GetUniformLocation, data_size) == 24, OffsetOf_GetUniformLocation_data_size_not_24); -struct GetUniformLocationImmediate { - typedef GetUniformLocationImmediate ValueType; - static const CommandId kCmdId = kGetUniformLocationImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - typedef GLint Result; - - static uint32 ComputeDataSize(const char* s) { - return base::checked_numeric_cast<uint32>(strlen(s)); - } - - static uint32 ComputeSize(const char* s) { - return base::checked_numeric_cast<uint32>(sizeof(ValueType) + - ComputeDataSize(s)); - } - - void SetHeader(const char* s) { - header.SetCmdByTotalSize<ValueType>(ComputeSize(s)); - } - - void Init( - GLuint _program, const char* _name, - uint32 _location_shm_id, uint32 _location_shm_offset) { - SetHeader(_name); - program = _program; - location_shm_id = _location_shm_id; - location_shm_offset = _location_shm_offset; - data_size = ComputeDataSize(_name); - memcpy(ImmediateDataAddress(this), _name, data_size); - } - - void* Set( - void* cmd, GLuint _program, const char* _name, - uint32 _location_shm_id, uint32 _location_shm_offset) { - uint32 total_size = ComputeSize(_name); - static_cast<ValueType*>( - cmd)->Init(_program, _name, _location_shm_id, _location_shm_offset); - return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); - } - - CommandHeader header; - uint32 program; - uint32 location_shm_id; - uint32 location_shm_offset; - uint32 data_size; -}; - -COMPILE_ASSERT(sizeof(GetUniformLocationImmediate) == 20, - Sizeof_GetUniformLocationImmediate_is_not_20); -COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, header) == 0, - OffsetOf_GetUniformLocationImmediate_header_not_0); -COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, program) == 4, - OffsetOf_GetUniformLocationImmediate_program_not_4); -COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, location_shm_id) == 8, - OffsetOf_GetUniformLocationImmediate_location_shm_id_not_8); -COMPILE_ASSERT( - offsetof(GetUniformLocationImmediate, location_shm_offset) == 12, - OffsetOf_GetUniformLocationImmediate_location_shm_offset_not_12); -COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, data_size) == 16, - OffsetOf_GetUniformLocationImmediate_data_size_not_16); - struct GetUniformLocationBucket { typedef GetUniformLocationBucket ValueType; static const CommandId kCmdId = kGetUniformLocationBucket; @@ -540,6 +419,13 @@ COMPILE_ASSERT(offsetof(GetUniformLocationBucket, location_shm_id) == 12, COMPILE_ASSERT(offsetof(GetUniformLocationBucket, location_shm_offset) == 16, OffsetOf_GetUniformLocationBucket_location_shm_offset_not_16); +struct GenMailboxCHROMIUM { + typedef GenMailboxCHROMIUM ValueType; + static const CommandId kCmdId = kGenMailboxCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + CommandHeader header; +}; + struct InsertSyncPointCHROMIUM { typedef InsertSyncPointCHROMIUM ValueType; static const CommandId kCmdId = kInsertSyncPointCHROMIUM; diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 11b990145d2..248ad460001 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -137,53 +137,6 @@ COMPILE_ASSERT(offsetof(BindAttribLocation, name_shm_offset) == 16, COMPILE_ASSERT(offsetof(BindAttribLocation, data_size) == 20, OffsetOf_BindAttribLocation_data_size_not_20); -struct BindAttribLocationImmediate { - typedef BindAttribLocationImmediate ValueType; - static const CommandId kCmdId = kBindAttribLocationImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - static uint32 ComputeSize(uint32 data_size) { - return static_cast<uint32>( - sizeof(ValueType) + data_size); // NOLINT - } - - void SetHeader(uint32 data_size) { - header.SetCmdBySize<ValueType>(data_size); - } - - void Init( - GLuint _program, GLuint _index, const char* _name, uint32 _data_size) { - SetHeader(_data_size); - program = _program; - index = _index; - data_size = _data_size; - memcpy(ImmediateDataAddress(this), _name, _data_size); - } - - void* Set( - void* cmd, GLuint _program, GLuint _index, const char* _name, - uint32 _data_size) { - static_cast<ValueType*>(cmd)->Init(_program, _index, _name, _data_size); - return NextImmediateCmdAddress<ValueType>(cmd, _data_size); - } - - gpu::CommandHeader header; - uint32 program; - uint32 index; - uint32 data_size; -}; - -COMPILE_ASSERT(sizeof(BindAttribLocationImmediate) == 16, - Sizeof_BindAttribLocationImmediate_is_not_16); -COMPILE_ASSERT(offsetof(BindAttribLocationImmediate, header) == 0, - OffsetOf_BindAttribLocationImmediate_header_not_0); -COMPILE_ASSERT(offsetof(BindAttribLocationImmediate, program) == 4, - OffsetOf_BindAttribLocationImmediate_program_not_4); -COMPILE_ASSERT(offsetof(BindAttribLocationImmediate, index) == 8, - OffsetOf_BindAttribLocationImmediate_index_not_8); -COMPILE_ASSERT(offsetof(BindAttribLocationImmediate, data_size) == 12, - OffsetOf_BindAttribLocationImmediate_data_size_not_12); - struct BindAttribLocationBucket { typedef BindAttribLocationBucket ValueType; static const CommandId kCmdId = kBindAttribLocationBucket; @@ -641,52 +594,6 @@ COMPILE_ASSERT(offsetof(BufferData, data_shm_offset) == 16, COMPILE_ASSERT(offsetof(BufferData, usage) == 20, OffsetOf_BufferData_usage_not_20); -struct BufferDataImmediate { - typedef BufferDataImmediate ValueType; - static const CommandId kCmdId = kBufferDataImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - static uint32 ComputeSize(uint32 size_in_bytes) { - return static_cast<uint32>( - sizeof(ValueType) + // NOLINT - RoundSizeToMultipleOfEntries(size_in_bytes)); - } - - void SetHeader(uint32 size_in_bytes) { - header.SetCmdByTotalSize<ValueType>(size_in_bytes); - } - - void Init(GLenum _target, GLsizeiptr _size, GLenum _usage) { - uint32 total_size = 0; // TODO(gman): get correct size. - SetHeader(total_size); - target = _target; - size = _size; - usage = _usage; - } - - void* Set(void* cmd, GLenum _target, GLsizeiptr _size, GLenum _usage) { - uint32 total_size = 0; // TODO(gman): get correct size. - static_cast<ValueType*>(cmd)->Init(_target, _size, _usage); - return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); - } - - gpu::CommandHeader header; - uint32 target; - int32 size; - uint32 usage; -}; - -COMPILE_ASSERT(sizeof(BufferDataImmediate) == 16, - Sizeof_BufferDataImmediate_is_not_16); -COMPILE_ASSERT(offsetof(BufferDataImmediate, header) == 0, - OffsetOf_BufferDataImmediate_header_not_0); -COMPILE_ASSERT(offsetof(BufferDataImmediate, target) == 4, - OffsetOf_BufferDataImmediate_target_not_4); -COMPILE_ASSERT(offsetof(BufferDataImmediate, size) == 8, - OffsetOf_BufferDataImmediate_size_not_8); -COMPILE_ASSERT(offsetof(BufferDataImmediate, usage) == 12, - OffsetOf_BufferDataImmediate_usage_not_12); - struct BufferSubData { typedef BufferSubData ValueType; static const CommandId kCmdId = kBufferSubData; @@ -742,52 +649,6 @@ COMPILE_ASSERT(offsetof(BufferSubData, data_shm_id) == 16, COMPILE_ASSERT(offsetof(BufferSubData, data_shm_offset) == 20, OffsetOf_BufferSubData_data_shm_offset_not_20); -struct BufferSubDataImmediate { - typedef BufferSubDataImmediate ValueType; - static const CommandId kCmdId = kBufferSubDataImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - static uint32 ComputeSize(uint32 size_in_bytes) { - return static_cast<uint32>( - sizeof(ValueType) + // NOLINT - RoundSizeToMultipleOfEntries(size_in_bytes)); - } - - void SetHeader(uint32 size_in_bytes) { - header.SetCmdByTotalSize<ValueType>(size_in_bytes); - } - - void Init(GLenum _target, GLintptr _offset, GLsizeiptr _size) { - uint32 total_size = ComputeSize(_size); - SetHeader(total_size); - target = _target; - offset = _offset; - size = _size; - } - - void* Set(void* cmd, GLenum _target, GLintptr _offset, GLsizeiptr _size) { - uint32 total_size = ComputeSize(_size); - static_cast<ValueType*>(cmd)->Init(_target, _offset, _size); - return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); - } - - gpu::CommandHeader header; - uint32 target; - int32 offset; - int32 size; -}; - -COMPILE_ASSERT(sizeof(BufferSubDataImmediate) == 16, - Sizeof_BufferSubDataImmediate_is_not_16); -COMPILE_ASSERT(offsetof(BufferSubDataImmediate, header) == 0, - OffsetOf_BufferSubDataImmediate_header_not_0); -COMPILE_ASSERT(offsetof(BufferSubDataImmediate, target) == 4, - OffsetOf_BufferSubDataImmediate_target_not_4); -COMPILE_ASSERT(offsetof(BufferSubDataImmediate, offset) == 8, - OffsetOf_BufferSubDataImmediate_offset_not_8); -COMPILE_ASSERT(offsetof(BufferSubDataImmediate, size) == 12, - OffsetOf_BufferSubDataImmediate_size_not_12); - struct CheckFramebufferStatus { typedef CheckFramebufferStatus ValueType; static const CommandId kCmdId = kCheckFramebufferStatus; @@ -1143,75 +1004,6 @@ COMPILE_ASSERT(offsetof(CompressedTexImage2D, data_shm_id) == 32, COMPILE_ASSERT(offsetof(CompressedTexImage2D, data_shm_offset) == 36, OffsetOf_CompressedTexImage2D_data_shm_offset_not_36); -struct CompressedTexImage2DImmediate { - typedef CompressedTexImage2DImmediate ValueType; - static const CommandId kCmdId = kCompressedTexImage2DImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - static uint32 ComputeSize(uint32 size_in_bytes) { - return static_cast<uint32>( - sizeof(ValueType) + // NOLINT - RoundSizeToMultipleOfEntries(size_in_bytes)); - } - - void SetHeader(uint32 size_in_bytes) { - header.SetCmdByTotalSize<ValueType>(size_in_bytes); - } - - void Init( - GLenum _target, GLint _level, GLenum _internalformat, GLsizei _width, - GLsizei _height, GLint _border, GLsizei _imageSize) { - uint32 total_size = 0; // TODO(gman): get correct size. - SetHeader(total_size); - target = _target; - level = _level; - internalformat = _internalformat; - width = _width; - height = _height; - border = _border; - imageSize = _imageSize; - } - - void* Set( - void* cmd, GLenum _target, GLint _level, GLenum _internalformat, - GLsizei _width, GLsizei _height, GLint _border, GLsizei _imageSize) { - uint32 total_size = 0; // TODO(gman): get correct size. - static_cast<ValueType*>( - cmd)->Init( - _target, _level, _internalformat, _width, _height, _border, - _imageSize); - return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); - } - - gpu::CommandHeader header; - uint32 target; - int32 level; - uint32 internalformat; - int32 width; - int32 height; - int32 border; - int32 imageSize; -}; - -COMPILE_ASSERT(sizeof(CompressedTexImage2DImmediate) == 32, - Sizeof_CompressedTexImage2DImmediate_is_not_32); -COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, header) == 0, - OffsetOf_CompressedTexImage2DImmediate_header_not_0); -COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, target) == 4, - OffsetOf_CompressedTexImage2DImmediate_target_not_4); -COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, level) == 8, - OffsetOf_CompressedTexImage2DImmediate_level_not_8); -COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, internalformat) == 12, - OffsetOf_CompressedTexImage2DImmediate_internalformat_not_12); -COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, width) == 16, - OffsetOf_CompressedTexImage2DImmediate_width_not_16); -COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, height) == 20, - OffsetOf_CompressedTexImage2DImmediate_height_not_20); -COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, border) == 24, - OffsetOf_CompressedTexImage2DImmediate_border_not_24); -COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, imageSize) == 28, - OffsetOf_CompressedTexImage2DImmediate_imageSize_not_28); - struct CompressedTexImage2DBucket { typedef CompressedTexImage2DBucket ValueType; static const CommandId kCmdId = kCompressedTexImage2DBucket; @@ -1356,79 +1148,6 @@ COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, data_shm_id) == 36, COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, data_shm_offset) == 40, OffsetOf_CompressedTexSubImage2D_data_shm_offset_not_40); -struct CompressedTexSubImage2DImmediate { - typedef CompressedTexSubImage2DImmediate ValueType; - static const CommandId kCmdId = kCompressedTexSubImage2DImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - static uint32 ComputeSize(uint32 size_in_bytes) { - return static_cast<uint32>( - sizeof(ValueType) + // NOLINT - RoundSizeToMultipleOfEntries(size_in_bytes)); - } - - void SetHeader(uint32 size_in_bytes) { - header.SetCmdByTotalSize<ValueType>(size_in_bytes); - } - - void Init( - GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, - GLsizei _width, GLsizei _height, GLenum _format, GLsizei _imageSize) { - uint32 total_size = ComputeSize(_imageSize); - SetHeader(total_size); - target = _target; - level = _level; - xoffset = _xoffset; - yoffset = _yoffset; - width = _width; - height = _height; - format = _format; - imageSize = _imageSize; - } - - void* Set( - void* cmd, GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, - GLsizei _width, GLsizei _height, GLenum _format, GLsizei _imageSize) { - uint32 total_size = ComputeSize(_imageSize); - static_cast<ValueType*>( - cmd)->Init( - _target, _level, _xoffset, _yoffset, _width, _height, _format, - _imageSize); - return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); - } - - gpu::CommandHeader header; - uint32 target; - int32 level; - int32 xoffset; - int32 yoffset; - int32 width; - int32 height; - uint32 format; - int32 imageSize; -}; - -COMPILE_ASSERT(sizeof(CompressedTexSubImage2DImmediate) == 36, - Sizeof_CompressedTexSubImage2DImmediate_is_not_36); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, header) == 0, - OffsetOf_CompressedTexSubImage2DImmediate_header_not_0); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, target) == 4, - OffsetOf_CompressedTexSubImage2DImmediate_target_not_4); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, level) == 8, - OffsetOf_CompressedTexSubImage2DImmediate_level_not_8); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, xoffset) == 12, - OffsetOf_CompressedTexSubImage2DImmediate_xoffset_not_12); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, yoffset) == 16, - OffsetOf_CompressedTexSubImage2DImmediate_yoffset_not_16); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, width) == 20, - OffsetOf_CompressedTexSubImage2DImmediate_width_not_20); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, height) == 24, - OffsetOf_CompressedTexSubImage2DImmediate_height_not_24); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, format) == 28, - OffsetOf_CompressedTexSubImage2DImmediate_format_not_28); -COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, imageSize) == 32, - OffsetOf_CompressedTexSubImage2DImmediate_imageSize_not_32); - struct CompressedTexSubImage2DBucket { typedef CompressedTexSubImage2DBucket ValueType; static const CommandId kCmdId = kCompressedTexSubImage2DBucket; @@ -5238,48 +4957,6 @@ COMPILE_ASSERT(offsetof(ShaderSource, data_shm_offset) == 12, COMPILE_ASSERT(offsetof(ShaderSource, data_size) == 16, OffsetOf_ShaderSource_data_size_not_16); -struct ShaderSourceImmediate { - typedef ShaderSourceImmediate ValueType; - static const CommandId kCmdId = kShaderSourceImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - static uint32 ComputeSize(uint32 size_in_bytes) { - return static_cast<uint32>( - sizeof(ValueType) + // NOLINT - RoundSizeToMultipleOfEntries(size_in_bytes)); - } - - void SetHeader(uint32 size_in_bytes) { - header.SetCmdByTotalSize<ValueType>(size_in_bytes); - } - - void Init(GLuint _shader, uint32 _data_size) { - uint32 total_size = ComputeSize(_data_size); - SetHeader(total_size); - shader = _shader; - data_size = _data_size; - } - - void* Set(void* cmd, GLuint _shader, uint32 _data_size) { - uint32 total_size = ComputeSize(_data_size); - static_cast<ValueType*>(cmd)->Init(_shader, _data_size); - return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); - } - - gpu::CommandHeader header; - uint32 shader; - uint32 data_size; -}; - -COMPILE_ASSERT(sizeof(ShaderSourceImmediate) == 12, - Sizeof_ShaderSourceImmediate_is_not_12); -COMPILE_ASSERT(offsetof(ShaderSourceImmediate, header) == 0, - OffsetOf_ShaderSourceImmediate_header_not_0); -COMPILE_ASSERT(offsetof(ShaderSourceImmediate, shader) == 4, - OffsetOf_ShaderSourceImmediate_shader_not_4); -COMPILE_ASSERT(offsetof(ShaderSourceImmediate, data_size) == 8, - OffsetOf_ShaderSourceImmediate_data_size_not_8); - struct ShaderSourceBucket { typedef ShaderSourceBucket ValueType; static const CommandId kCmdId = kShaderSourceBucket; @@ -5646,80 +5323,6 @@ COMPILE_ASSERT(offsetof(TexImage2D, pixels_shm_id) == 36, COMPILE_ASSERT(offsetof(TexImage2D, pixels_shm_offset) == 40, OffsetOf_TexImage2D_pixels_shm_offset_not_40); -struct TexImage2DImmediate { - typedef TexImage2DImmediate ValueType; - static const CommandId kCmdId = kTexImage2DImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - static uint32 ComputeSize(uint32 size_in_bytes) { - return static_cast<uint32>( - sizeof(ValueType) + // NOLINT - RoundSizeToMultipleOfEntries(size_in_bytes)); - } - - void SetHeader(uint32 size_in_bytes) { - header.SetCmdByTotalSize<ValueType>(size_in_bytes); - } - - void Init( - GLenum _target, GLint _level, GLint _internalformat, GLsizei _width, - GLsizei _height, GLint _border, GLenum _format, GLenum _type) { - uint32 total_size = 0; // TODO(gman): get correct size. - SetHeader(total_size); - target = _target; - level = _level; - internalformat = _internalformat; - width = _width; - height = _height; - border = _border; - format = _format; - type = _type; - } - - void* Set( - void* cmd, GLenum _target, GLint _level, GLint _internalformat, - GLsizei _width, GLsizei _height, GLint _border, GLenum _format, - GLenum _type) { - uint32 total_size = 0; // TODO(gman): get correct size. - static_cast<ValueType*>( - cmd)->Init( - _target, _level, _internalformat, _width, _height, _border, _format, - _type); - return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); - } - - gpu::CommandHeader header; - uint32 target; - int32 level; - int32 internalformat; - int32 width; - int32 height; - int32 border; - uint32 format; - uint32 type; -}; - -COMPILE_ASSERT(sizeof(TexImage2DImmediate) == 36, - Sizeof_TexImage2DImmediate_is_not_36); -COMPILE_ASSERT(offsetof(TexImage2DImmediate, header) == 0, - OffsetOf_TexImage2DImmediate_header_not_0); -COMPILE_ASSERT(offsetof(TexImage2DImmediate, target) == 4, - OffsetOf_TexImage2DImmediate_target_not_4); -COMPILE_ASSERT(offsetof(TexImage2DImmediate, level) == 8, - OffsetOf_TexImage2DImmediate_level_not_8); -COMPILE_ASSERT(offsetof(TexImage2DImmediate, internalformat) == 12, - OffsetOf_TexImage2DImmediate_internalformat_not_12); -COMPILE_ASSERT(offsetof(TexImage2DImmediate, width) == 16, - OffsetOf_TexImage2DImmediate_width_not_16); -COMPILE_ASSERT(offsetof(TexImage2DImmediate, height) == 20, - OffsetOf_TexImage2DImmediate_height_not_20); -COMPILE_ASSERT(offsetof(TexImage2DImmediate, border) == 24, - OffsetOf_TexImage2DImmediate_border_not_24); -COMPILE_ASSERT(offsetof(TexImage2DImmediate, format) == 28, - OffsetOf_TexImage2DImmediate_format_not_28); -COMPILE_ASSERT(offsetof(TexImage2DImmediate, type) == 32, - OffsetOf_TexImage2DImmediate_type_not_32); - struct TexParameterf { typedef TexParameterf ValueType; static const CommandId kCmdId = kTexParameterf; @@ -6083,85 +5686,6 @@ COMPILE_ASSERT(offsetof(TexSubImage2D, pixels_shm_offset) == 40, COMPILE_ASSERT(offsetof(TexSubImage2D, internal) == 44, OffsetOf_TexSubImage2D_internal_not_44); -struct TexSubImage2DImmediate { - typedef TexSubImage2DImmediate ValueType; - static const CommandId kCmdId = kTexSubImage2DImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - static uint32 ComputeSize(uint32 size_in_bytes) { - return static_cast<uint32>( - sizeof(ValueType) + // NOLINT - RoundSizeToMultipleOfEntries(size_in_bytes)); - } - - void SetHeader(uint32 size_in_bytes) { - header.SetCmdByTotalSize<ValueType>(size_in_bytes); - } - - void Init( - GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, - GLsizei _width, GLsizei _height, GLenum _format, GLenum _type, - GLboolean _internal) { - uint32 total_size = 0; // TODO(gman): get correct size. - SetHeader(total_size); - target = _target; - level = _level; - xoffset = _xoffset; - yoffset = _yoffset; - width = _width; - height = _height; - format = _format; - type = _type; - internal = _internal; - } - - void* Set( - void* cmd, GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, - GLsizei _width, GLsizei _height, GLenum _format, GLenum _type, - GLboolean _internal) { - uint32 total_size = 0; // TODO(gman): get correct size. - static_cast<ValueType*>( - cmd)->Init( - _target, _level, _xoffset, _yoffset, _width, _height, _format, - _type, _internal); - return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); - } - - gpu::CommandHeader header; - uint32 target; - int32 level; - int32 xoffset; - int32 yoffset; - int32 width; - int32 height; - uint32 format; - uint32 type; - uint32 internal; -}; - -COMPILE_ASSERT(sizeof(TexSubImage2DImmediate) == 40, - Sizeof_TexSubImage2DImmediate_is_not_40); -COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, header) == 0, - OffsetOf_TexSubImage2DImmediate_header_not_0); -COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, target) == 4, - OffsetOf_TexSubImage2DImmediate_target_not_4); -COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, level) == 8, - OffsetOf_TexSubImage2DImmediate_level_not_8); -COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, xoffset) == 12, - OffsetOf_TexSubImage2DImmediate_xoffset_not_12); -COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, yoffset) == 16, - OffsetOf_TexSubImage2DImmediate_yoffset_not_16); -COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, width) == 20, - OffsetOf_TexSubImage2DImmediate_width_not_20); -COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, height) == 24, - OffsetOf_TexSubImage2DImmediate_height_not_24); -COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, format) == 28, - OffsetOf_TexSubImage2DImmediate_format_not_28); -COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, type) == 32, - OffsetOf_TexSubImage2DImmediate_type_not_32); -COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, internal) == 36, - OffsetOf_TexSubImage2DImmediate_internal_not_36); - struct Uniform1f { typedef Uniform1f ValueType; static const CommandId kCmdId = kUniform1f; @@ -8337,9 +7861,9 @@ COMPILE_ASSERT(offsetof(Viewport, width) == 12, COMPILE_ASSERT(offsetof(Viewport, height) == 16, OffsetOf_Viewport_height_not_16); -struct BlitFramebufferEXT { - typedef BlitFramebufferEXT ValueType; - static const CommandId kCmdId = kBlitFramebufferEXT; +struct BlitFramebufferCHROMIUM { + typedef BlitFramebufferCHROMIUM ValueType; + static const CommandId kCmdId = kBlitFramebufferCHROMIUM; static const cmd::ArgFlags kArgFlags = cmd::kFixed; static uint32 ComputeSize() { @@ -8391,31 +7915,89 @@ struct BlitFramebufferEXT { uint32 filter; }; -COMPILE_ASSERT(sizeof(BlitFramebufferEXT) == 44, - Sizeof_BlitFramebufferEXT_is_not_44); -COMPILE_ASSERT(offsetof(BlitFramebufferEXT, header) == 0, - OffsetOf_BlitFramebufferEXT_header_not_0); -COMPILE_ASSERT(offsetof(BlitFramebufferEXT, srcX0) == 4, - OffsetOf_BlitFramebufferEXT_srcX0_not_4); -COMPILE_ASSERT(offsetof(BlitFramebufferEXT, srcY0) == 8, - OffsetOf_BlitFramebufferEXT_srcY0_not_8); -COMPILE_ASSERT(offsetof(BlitFramebufferEXT, srcX1) == 12, - OffsetOf_BlitFramebufferEXT_srcX1_not_12); -COMPILE_ASSERT(offsetof(BlitFramebufferEXT, srcY1) == 16, - OffsetOf_BlitFramebufferEXT_srcY1_not_16); -COMPILE_ASSERT(offsetof(BlitFramebufferEXT, dstX0) == 20, - OffsetOf_BlitFramebufferEXT_dstX0_not_20); -COMPILE_ASSERT(offsetof(BlitFramebufferEXT, dstY0) == 24, - OffsetOf_BlitFramebufferEXT_dstY0_not_24); -COMPILE_ASSERT(offsetof(BlitFramebufferEXT, dstX1) == 28, - OffsetOf_BlitFramebufferEXT_dstX1_not_28); -COMPILE_ASSERT(offsetof(BlitFramebufferEXT, dstY1) == 32, - OffsetOf_BlitFramebufferEXT_dstY1_not_32); -COMPILE_ASSERT(offsetof(BlitFramebufferEXT, mask) == 36, - OffsetOf_BlitFramebufferEXT_mask_not_36); -COMPILE_ASSERT(offsetof(BlitFramebufferEXT, filter) == 40, - OffsetOf_BlitFramebufferEXT_filter_not_40); +COMPILE_ASSERT(sizeof(BlitFramebufferCHROMIUM) == 44, + Sizeof_BlitFramebufferCHROMIUM_is_not_44); +COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, header) == 0, + OffsetOf_BlitFramebufferCHROMIUM_header_not_0); +COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, srcX0) == 4, + OffsetOf_BlitFramebufferCHROMIUM_srcX0_not_4); +COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, srcY0) == 8, + OffsetOf_BlitFramebufferCHROMIUM_srcY0_not_8); +COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, srcX1) == 12, + OffsetOf_BlitFramebufferCHROMIUM_srcX1_not_12); +COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, srcY1) == 16, + OffsetOf_BlitFramebufferCHROMIUM_srcY1_not_16); +COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, dstX0) == 20, + OffsetOf_BlitFramebufferCHROMIUM_dstX0_not_20); +COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, dstY0) == 24, + OffsetOf_BlitFramebufferCHROMIUM_dstY0_not_24); +COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, dstX1) == 28, + OffsetOf_BlitFramebufferCHROMIUM_dstX1_not_28); +COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, dstY1) == 32, + OffsetOf_BlitFramebufferCHROMIUM_dstY1_not_32); +COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, mask) == 36, + OffsetOf_BlitFramebufferCHROMIUM_mask_not_36); +COMPILE_ASSERT(offsetof(BlitFramebufferCHROMIUM, filter) == 40, + OffsetOf_BlitFramebufferCHROMIUM_filter_not_40); + +// GL_CHROMIUM_framebuffer_multisample +struct RenderbufferStorageMultisampleCHROMIUM { + typedef RenderbufferStorageMultisampleCHROMIUM ValueType; + static const CommandId kCmdId = kRenderbufferStorageMultisampleCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLsizei _samples, GLenum _internalformat, GLsizei _width, + GLsizei _height) { + SetHeader(); + target = _target; + samples = _samples; + internalformat = _internalformat; + width = _width; + height = _height; + } + + void* Set( + void* cmd, GLenum _target, GLsizei _samples, GLenum _internalformat, + GLsizei _width, GLsizei _height) { + static_cast<ValueType*>( + cmd)->Init(_target, _samples, _internalformat, _width, _height); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 target; + int32 samples; + uint32 internalformat; + int32 width; + int32 height; +}; +COMPILE_ASSERT(sizeof(RenderbufferStorageMultisampleCHROMIUM) == 24, + Sizeof_RenderbufferStorageMultisampleCHROMIUM_is_not_24); +COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleCHROMIUM, header) == 0, + OffsetOf_RenderbufferStorageMultisampleCHROMIUM_header_not_0); +COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleCHROMIUM, target) == 4, + OffsetOf_RenderbufferStorageMultisampleCHROMIUM_target_not_4); +COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleCHROMIUM, samples) == 8, + OffsetOf_RenderbufferStorageMultisampleCHROMIUM_samples_not_8); +COMPILE_ASSERT( + offsetof(RenderbufferStorageMultisampleCHROMIUM, internalformat) == 12, + OffsetOf_RenderbufferStorageMultisampleCHROMIUM_internalformat_not_12); // NOLINT +COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleCHROMIUM, width) == 16, + OffsetOf_RenderbufferStorageMultisampleCHROMIUM_width_not_16); +COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleCHROMIUM, height) == 20, + OffsetOf_RenderbufferStorageMultisampleCHROMIUM_height_not_20); + +// GL_EXT_multisampled_render_to_texture struct RenderbufferStorageMultisampleEXT { typedef RenderbufferStorageMultisampleEXT ValueType; static const CommandId kCmdId = kRenderbufferStorageMultisampleEXT; @@ -10145,42 +9727,6 @@ COMPILE_ASSERT(offsetof(VertexAttribDivisorANGLE, index) == 4, COMPILE_ASSERT(offsetof(VertexAttribDivisorANGLE, divisor) == 8, OffsetOf_VertexAttribDivisorANGLE_divisor_not_8); -struct GenMailboxCHROMIUM { - typedef GenMailboxCHROMIUM ValueType; - static const CommandId kCmdId = kGenMailboxCHROMIUM; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - typedef SizedResult<GLint> Result; - - static uint32 ComputeSize() { - return static_cast<uint32>(sizeof(ValueType)); // NOLINT - } - - void SetHeader() { - header.SetCmd<ValueType>(); - } - - void Init(GLuint _bucket_id) { - SetHeader(); - bucket_id = _bucket_id; - } - - void* Set(void* cmd, GLuint _bucket_id) { - static_cast<ValueType*>(cmd)->Init(_bucket_id); - return NextCmdAddress<ValueType>(cmd); - } - - gpu::CommandHeader header; - uint32 bucket_id; -}; - -COMPILE_ASSERT(sizeof(GenMailboxCHROMIUM) == 8, - Sizeof_GenMailboxCHROMIUM_is_not_8); -COMPILE_ASSERT(offsetof(GenMailboxCHROMIUM, header) == 0, - OffsetOf_GenMailboxCHROMIUM_header_not_0); -COMPILE_ASSERT(offsetof(GenMailboxCHROMIUM, bucket_id) == 4, - OffsetOf_GenMailboxCHROMIUM_bucket_id_not_4); - struct ProduceTextureCHROMIUM { typedef ProduceTextureCHROMIUM ValueType; static const CommandId kCmdId = kProduceTextureCHROMIUM; @@ -10415,53 +9961,6 @@ COMPILE_ASSERT(offsetof(BindUniformLocationCHROMIUM, name_shm_offset) == 16, COMPILE_ASSERT(offsetof(BindUniformLocationCHROMIUM, data_size) == 20, OffsetOf_BindUniformLocationCHROMIUM_data_size_not_20); -struct BindUniformLocationCHROMIUMImmediate { - typedef BindUniformLocationCHROMIUMImmediate ValueType; - static const CommandId kCmdId = kBindUniformLocationCHROMIUMImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - static uint32 ComputeSize(uint32 data_size) { - return static_cast<uint32>( - sizeof(ValueType) + data_size); // NOLINT - } - - void SetHeader(uint32 data_size) { - header.SetCmdBySize<ValueType>(data_size); - } - - void Init( - GLuint _program, GLint _location, const char* _name, uint32 _data_size) { - SetHeader(_data_size); - program = _program; - location = _location; - data_size = _data_size; - memcpy(ImmediateDataAddress(this), _name, _data_size); - } - - void* Set( - void* cmd, GLuint _program, GLint _location, const char* _name, - uint32 _data_size) { - static_cast<ValueType*>(cmd)->Init(_program, _location, _name, _data_size); - return NextImmediateCmdAddress<ValueType>(cmd, _data_size); - } - - gpu::CommandHeader header; - uint32 program; - int32 location; - uint32 data_size; -}; - -COMPILE_ASSERT(sizeof(BindUniformLocationCHROMIUMImmediate) == 16, - Sizeof_BindUniformLocationCHROMIUMImmediate_is_not_16); -COMPILE_ASSERT(offsetof(BindUniformLocationCHROMIUMImmediate, header) == 0, - OffsetOf_BindUniformLocationCHROMIUMImmediate_header_not_0); -COMPILE_ASSERT(offsetof(BindUniformLocationCHROMIUMImmediate, program) == 4, - OffsetOf_BindUniformLocationCHROMIUMImmediate_program_not_4); -COMPILE_ASSERT(offsetof(BindUniformLocationCHROMIUMImmediate, location) == 8, - OffsetOf_BindUniformLocationCHROMIUMImmediate_location_not_8); -COMPILE_ASSERT(offsetof(BindUniformLocationCHROMIUMImmediate, data_size) == 12, - OffsetOf_BindUniformLocationCHROMIUMImmediate_data_size_not_12); - struct BindUniformLocationCHROMIUMBucket { typedef BindUniformLocationCHROMIUMBucket ValueType; static const CommandId kCmdId = kBindUniformLocationCHROMIUMBucket; @@ -11097,6 +10596,36 @@ COMPILE_ASSERT(offsetof(DrawBuffersEXTImmediate, header) == 0, COMPILE_ASSERT(offsetof(DrawBuffersEXTImmediate, count) == 4, OffsetOf_DrawBuffersEXTImmediate_count_not_4); +struct DiscardBackbufferCHROMIUM { + typedef DiscardBackbufferCHROMIUM ValueType; + static const CommandId kCmdId = kDiscardBackbufferCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init() { + SetHeader(); + } + + void* Set(void* cmd) { + static_cast<ValueType*>(cmd)->Init(); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; +}; + +COMPILE_ASSERT(sizeof(DiscardBackbufferCHROMIUM) == 4, + Sizeof_DiscardBackbufferCHROMIUM_is_not_4); +COMPILE_ASSERT(offsetof(DiscardBackbufferCHROMIUM, header) == 0, + OffsetOf_DiscardBackbufferCHROMIUM_header_not_0); + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 740e6cb82fd..9672db4c749 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -61,35 +61,6 @@ TEST_F(GLES2FormatTest, BindAttribLocation) { next_cmd, sizeof(cmd)); } - -TEST_F(GLES2FormatTest, BindAttribLocationImmediate) { - cmds::BindAttribLocationImmediate& cmd = - *GetBufferAs<cmds::BindAttribLocationImmediate>(); - static const char* const test_str = "test string"; - void* next_cmd = cmd.Set( - &cmd, - static_cast<GLuint>(11), - static_cast<GLuint>(12), - test_str, - strlen(test_str)); - EXPECT_EQ(static_cast<uint32>(cmds::BindAttribLocationImmediate::kCmdId), - cmd.header.command); - EXPECT_EQ(sizeof(cmd) + - RoundSizeToMultipleOfEntries(strlen(test_str)), - cmd.header.size * 4u); - EXPECT_EQ(static_cast<char*>(next_cmd), - reinterpret_cast<char*>(&cmd) + sizeof(cmd) + - RoundSizeToMultipleOfEntries(strlen(test_str))); - EXPECT_EQ(static_cast<GLuint>(11), cmd.program); - EXPECT_EQ(static_cast<GLuint>(12), cmd.index); - EXPECT_EQ(static_cast<uint32>(strlen(test_str)), cmd.data_size); - EXPECT_EQ(0, memcmp(test_str, ImmediateDataAddress(&cmd), strlen(test_str))); - CheckBytesWritten( - next_cmd, - sizeof(cmd) + RoundSizeToMultipleOfEntries(strlen(test_str)), - sizeof(cmd) + strlen(test_str)); -} - TEST_F(GLES2FormatTest, BindAttribLocationBucket) { cmds::BindAttribLocationBucket& cmd = *GetBufferAs<cmds::BindAttribLocationBucket>(); @@ -271,7 +242,6 @@ TEST_F(GLES2FormatTest, BufferData) { next_cmd, sizeof(cmd)); } -// TODO(gman): Implement test for BufferDataImmediate TEST_F(GLES2FormatTest, BufferSubData) { cmds::BufferSubData& cmd = *GetBufferAs<cmds::BufferSubData>(); void* next_cmd = cmd.Set( @@ -293,7 +263,6 @@ TEST_F(GLES2FormatTest, BufferSubData) { next_cmd, sizeof(cmd)); } -// TODO(gman): Implement test for BufferSubDataImmediate TEST_F(GLES2FormatTest, CheckFramebufferStatus) { cmds::CheckFramebufferStatus& cmd = *GetBufferAs<cmds::CheckFramebufferStatus>(); @@ -431,7 +400,6 @@ TEST_F(GLES2FormatTest, CompressedTexImage2D) { next_cmd, sizeof(cmd)); } -// TODO(gman): Implement test for CompressedTexImage2DImmediate TEST_F(GLES2FormatTest, CompressedTexImage2DBucket) { cmds::CompressedTexImage2DBucket& cmd = *GetBufferAs<cmds::CompressedTexImage2DBucket>(); @@ -490,7 +458,6 @@ TEST_F(GLES2FormatTest, CompressedTexSubImage2D) { next_cmd, sizeof(cmd)); } -// TODO(gman): Implement test for CompressedTexSubImage2DImmediate TEST_F(GLES2FormatTest, CompressedTexSubImage2DBucket) { cmds::CompressedTexSubImage2DBucket& cmd = *GetBufferAs<cmds::CompressedTexSubImage2DBucket>(); @@ -1215,7 +1182,6 @@ TEST_F(GLES2FormatTest, GetAttachedShaders) { } // TODO(gman): Write test for GetAttribLocation -// TODO(gman): Write test for GetAttribLocationImmediate // TODO(gman): Write test for GetAttribLocationBucket TEST_F(GLES2FormatTest, GetBooleanv) { cmds::GetBooleanv& cmd = *GetBufferAs<cmds::GetBooleanv>(); @@ -1540,7 +1506,6 @@ TEST_F(GLES2FormatTest, GetUniformiv) { } // TODO(gman): Write test for GetUniformLocation -// TODO(gman): Write test for GetUniformLocationImmediate // TODO(gman): Write test for GetUniformLocationBucket TEST_F(GLES2FormatTest, GetVertexAttribfv) { cmds::GetVertexAttribfv& cmd = *GetBufferAs<cmds::GetVertexAttribfv>(); @@ -1932,7 +1897,6 @@ TEST_F(GLES2FormatTest, ShaderSource) { next_cmd, sizeof(cmd)); } -// TODO(gman): Implement test for ShaderSourceImmediate TEST_F(GLES2FormatTest, ShaderSourceBucket) { cmds::ShaderSourceBucket& cmd = *GetBufferAs<cmds::ShaderSourceBucket>(); void* next_cmd = cmd.Set( @@ -2079,7 +2043,6 @@ TEST_F(GLES2FormatTest, TexImage2D) { next_cmd, sizeof(cmd)); } -// TODO(gman): Implement test for TexImage2DImmediate TEST_F(GLES2FormatTest, TexParameterf) { cmds::TexParameterf& cmd = *GetBufferAs<cmds::TexParameterf>(); void* next_cmd = cmd.Set( @@ -2235,7 +2198,6 @@ TEST_F(GLES2FormatTest, TexSubImage2D) { next_cmd, sizeof(cmd)); } -// TODO(gman): Implement test for TexSubImage2DImmediate TEST_F(GLES2FormatTest, Uniform1f) { cmds::Uniform1f& cmd = *GetBufferAs<cmds::Uniform1f>(); void* next_cmd = cmd.Set( @@ -3272,8 +3234,9 @@ TEST_F(GLES2FormatTest, Viewport) { next_cmd, sizeof(cmd)); } -TEST_F(GLES2FormatTest, BlitFramebufferEXT) { - cmds::BlitFramebufferEXT& cmd = *GetBufferAs<cmds::BlitFramebufferEXT>(); +TEST_F(GLES2FormatTest, BlitFramebufferCHROMIUM) { + cmds::BlitFramebufferCHROMIUM& cmd = + *GetBufferAs<cmds::BlitFramebufferCHROMIUM>(); void* next_cmd = cmd.Set( &cmd, static_cast<GLint>(11), @@ -3286,7 +3249,7 @@ TEST_F(GLES2FormatTest, BlitFramebufferEXT) { static_cast<GLint>(18), static_cast<GLbitfield>(19), static_cast<GLenum>(20)); - EXPECT_EQ(static_cast<uint32>(cmds::BlitFramebufferEXT::kCmdId), + EXPECT_EQ(static_cast<uint32>(cmds::BlitFramebufferCHROMIUM::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); EXPECT_EQ(static_cast<GLint>(11), cmd.srcX0); @@ -3303,6 +3266,30 @@ TEST_F(GLES2FormatTest, BlitFramebufferEXT) { next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, RenderbufferStorageMultisampleCHROMIUM) { + cmds::RenderbufferStorageMultisampleCHROMIUM& cmd = + *GetBufferAs<cmds::RenderbufferStorageMultisampleCHROMIUM>(); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLsizei>(12), + static_cast<GLenum>(13), + static_cast<GLsizei>(14), + static_cast<GLsizei>(15)); + EXPECT_EQ( + static_cast<uint32>( + cmds::RenderbufferStorageMultisampleCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.samples); + EXPECT_EQ(static_cast<GLenum>(13), cmd.internalformat); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.height); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, RenderbufferStorageMultisampleEXT) { cmds::RenderbufferStorageMultisampleEXT& cmd = *GetBufferAs<cmds::RenderbufferStorageMultisampleEXT>(); @@ -3985,19 +3972,7 @@ TEST_F(GLES2FormatTest, VertexAttribDivisorANGLE) { next_cmd, sizeof(cmd)); } -TEST_F(GLES2FormatTest, GenMailboxCHROMIUM) { - cmds::GenMailboxCHROMIUM& cmd = *GetBufferAs<cmds::GenMailboxCHROMIUM>(); - void* next_cmd = cmd.Set( - &cmd, - static_cast<GLuint>(11)); - EXPECT_EQ(static_cast<uint32>(cmds::GenMailboxCHROMIUM::kCmdId), - cmd.header.command); - EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<GLuint>(11), cmd.bucket_id); - CheckBytesWrittenMatchesExpectedSize( - next_cmd, sizeof(cmd)); -} - +// TODO(gman): Write test for GenMailboxCHROMIUM TEST_F(GLES2FormatTest, ProduceTextureCHROMIUM) { cmds::ProduceTextureCHROMIUM& cmd = *GetBufferAs<cmds::ProduceTextureCHROMIUM>(); @@ -4228,36 +4203,6 @@ TEST_F(GLES2FormatTest, BindUniformLocationCHROMIUM) { next_cmd, sizeof(cmd)); } - -TEST_F(GLES2FormatTest, BindUniformLocationCHROMIUMImmediate) { - cmds::BindUniformLocationCHROMIUMImmediate& cmd = - *GetBufferAs<cmds::BindUniformLocationCHROMIUMImmediate>(); - static const char* const test_str = "test string"; - void* next_cmd = cmd.Set( - &cmd, - static_cast<GLuint>(11), - static_cast<GLint>(12), - test_str, - strlen(test_str)); - EXPECT_EQ( - static_cast<uint32>(cmds::BindUniformLocationCHROMIUMImmediate::kCmdId), - cmd.header.command); - EXPECT_EQ(sizeof(cmd) + - RoundSizeToMultipleOfEntries(strlen(test_str)), - cmd.header.size * 4u); - EXPECT_EQ(static_cast<char*>(next_cmd), - reinterpret_cast<char*>(&cmd) + sizeof(cmd) + - RoundSizeToMultipleOfEntries(strlen(test_str))); - EXPECT_EQ(static_cast<GLuint>(11), cmd.program); - EXPECT_EQ(static_cast<GLint>(12), cmd.location); - EXPECT_EQ(static_cast<uint32>(strlen(test_str)), cmd.data_size); - EXPECT_EQ(0, memcmp(test_str, ImmediateDataAddress(&cmd), strlen(test_str))); - CheckBytesWritten( - next_cmd, - sizeof(cmd) + RoundSizeToMultipleOfEntries(strlen(test_str)), - sizeof(cmd) + strlen(test_str)); -} - TEST_F(GLES2FormatTest, BindUniformLocationCHROMIUMBucket) { cmds::BindUniformLocationCHROMIUMBucket& cmd = *GetBufferAs<cmds::BindUniformLocationCHROMIUMBucket>(); @@ -4529,5 +4474,17 @@ TEST_F(GLES2FormatTest, DrawBuffersEXTImmediate) { // TODO(gman): Check that data was inserted; } +TEST_F(GLES2FormatTest, DiscardBackbufferCHROMIUM) { + cmds::DiscardBackbufferCHROMIUM& cmd = + *GetBufferAs<cmds::DiscardBackbufferCHROMIUM>(); + void* next_cmd = cmd.Set( + &cmd); + EXPECT_EQ(static_cast<uint32>(cmds::DiscardBackbufferCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd)); +} + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 6fd070975d8..e26e8d22d91 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -13,247 +13,238 @@ OP(ActiveTexture) /* 256 */ \ OP(AttachShader) /* 257 */ \ OP(BindAttribLocation) /* 258 */ \ - OP(BindAttribLocationImmediate) /* 259 */ \ - OP(BindAttribLocationBucket) /* 260 */ \ - OP(BindBuffer) /* 261 */ \ - OP(BindFramebuffer) /* 262 */ \ - OP(BindRenderbuffer) /* 263 */ \ - OP(BindTexture) /* 264 */ \ - OP(BlendColor) /* 265 */ \ - OP(BlendEquation) /* 266 */ \ - OP(BlendEquationSeparate) /* 267 */ \ - OP(BlendFunc) /* 268 */ \ - OP(BlendFuncSeparate) /* 269 */ \ - OP(BufferData) /* 270 */ \ - OP(BufferDataImmediate) /* 271 */ \ - OP(BufferSubData) /* 272 */ \ - OP(BufferSubDataImmediate) /* 273 */ \ - OP(CheckFramebufferStatus) /* 274 */ \ - OP(Clear) /* 275 */ \ - OP(ClearColor) /* 276 */ \ - OP(ClearDepthf) /* 277 */ \ - OP(ClearStencil) /* 278 */ \ - OP(ColorMask) /* 279 */ \ - OP(CompileShader) /* 280 */ \ - OP(CompressedTexImage2D) /* 281 */ \ - OP(CompressedTexImage2DImmediate) /* 282 */ \ - OP(CompressedTexImage2DBucket) /* 283 */ \ - OP(CompressedTexSubImage2D) /* 284 */ \ - OP(CompressedTexSubImage2DImmediate) /* 285 */ \ - OP(CompressedTexSubImage2DBucket) /* 286 */ \ - OP(CopyTexImage2D) /* 287 */ \ - OP(CopyTexSubImage2D) /* 288 */ \ - OP(CreateProgram) /* 289 */ \ - OP(CreateShader) /* 290 */ \ - OP(CullFace) /* 291 */ \ - OP(DeleteBuffers) /* 292 */ \ - OP(DeleteBuffersImmediate) /* 293 */ \ - OP(DeleteFramebuffers) /* 294 */ \ - OP(DeleteFramebuffersImmediate) /* 295 */ \ - OP(DeleteProgram) /* 296 */ \ - OP(DeleteRenderbuffers) /* 297 */ \ - OP(DeleteRenderbuffersImmediate) /* 298 */ \ - OP(DeleteShader) /* 299 */ \ - OP(DeleteTextures) /* 300 */ \ - OP(DeleteTexturesImmediate) /* 301 */ \ - OP(DepthFunc) /* 302 */ \ - OP(DepthMask) /* 303 */ \ - OP(DepthRangef) /* 304 */ \ - OP(DetachShader) /* 305 */ \ - OP(Disable) /* 306 */ \ - OP(DisableVertexAttribArray) /* 307 */ \ - OP(DrawArrays) /* 308 */ \ - OP(DrawElements) /* 309 */ \ - OP(Enable) /* 310 */ \ - OP(EnableVertexAttribArray) /* 311 */ \ - OP(Finish) /* 312 */ \ - OP(Flush) /* 313 */ \ - OP(FramebufferRenderbuffer) /* 314 */ \ - OP(FramebufferTexture2D) /* 315 */ \ - OP(FrontFace) /* 316 */ \ - OP(GenBuffers) /* 317 */ \ - OP(GenBuffersImmediate) /* 318 */ \ - OP(GenerateMipmap) /* 319 */ \ - OP(GenFramebuffers) /* 320 */ \ - OP(GenFramebuffersImmediate) /* 321 */ \ - OP(GenRenderbuffers) /* 322 */ \ - OP(GenRenderbuffersImmediate) /* 323 */ \ - OP(GenTextures) /* 324 */ \ - OP(GenTexturesImmediate) /* 325 */ \ - OP(GetActiveAttrib) /* 326 */ \ - OP(GetActiveUniform) /* 327 */ \ - OP(GetAttachedShaders) /* 328 */ \ - OP(GetAttribLocation) /* 329 */ \ - OP(GetAttribLocationImmediate) /* 330 */ \ - OP(GetAttribLocationBucket) /* 331 */ \ - OP(GetBooleanv) /* 332 */ \ - OP(GetBufferParameteriv) /* 333 */ \ - OP(GetError) /* 334 */ \ - OP(GetFloatv) /* 335 */ \ - OP(GetFramebufferAttachmentParameteriv) /* 336 */ \ - OP(GetIntegerv) /* 337 */ \ - OP(GetProgramiv) /* 338 */ \ - OP(GetProgramInfoLog) /* 339 */ \ - OP(GetRenderbufferParameteriv) /* 340 */ \ - OP(GetShaderiv) /* 341 */ \ - OP(GetShaderInfoLog) /* 342 */ \ - OP(GetShaderPrecisionFormat) /* 343 */ \ - OP(GetShaderSource) /* 344 */ \ - OP(GetString) /* 345 */ \ - OP(GetTexParameterfv) /* 346 */ \ - OP(GetTexParameteriv) /* 347 */ \ - OP(GetUniformfv) /* 348 */ \ - OP(GetUniformiv) /* 349 */ \ - OP(GetUniformLocation) /* 350 */ \ - OP(GetUniformLocationImmediate) /* 351 */ \ - OP(GetUniformLocationBucket) /* 352 */ \ - OP(GetVertexAttribfv) /* 353 */ \ - OP(GetVertexAttribiv) /* 354 */ \ - OP(GetVertexAttribPointerv) /* 355 */ \ - OP(Hint) /* 356 */ \ - OP(IsBuffer) /* 357 */ \ - OP(IsEnabled) /* 358 */ \ - OP(IsFramebuffer) /* 359 */ \ - OP(IsProgram) /* 360 */ \ - OP(IsRenderbuffer) /* 361 */ \ - OP(IsShader) /* 362 */ \ - OP(IsTexture) /* 363 */ \ - OP(LineWidth) /* 364 */ \ - OP(LinkProgram) /* 365 */ \ - OP(PixelStorei) /* 366 */ \ - OP(PolygonOffset) /* 367 */ \ - OP(ReadPixels) /* 368 */ \ - OP(ReleaseShaderCompiler) /* 369 */ \ - OP(RenderbufferStorage) /* 370 */ \ - OP(SampleCoverage) /* 371 */ \ - OP(Scissor) /* 372 */ \ - OP(ShaderBinary) /* 373 */ \ - OP(ShaderSource) /* 374 */ \ - OP(ShaderSourceImmediate) /* 375 */ \ - OP(ShaderSourceBucket) /* 376 */ \ - OP(StencilFunc) /* 377 */ \ - OP(StencilFuncSeparate) /* 378 */ \ - OP(StencilMask) /* 379 */ \ - OP(StencilMaskSeparate) /* 380 */ \ - OP(StencilOp) /* 381 */ \ - OP(StencilOpSeparate) /* 382 */ \ - OP(TexImage2D) /* 383 */ \ - OP(TexImage2DImmediate) /* 384 */ \ - OP(TexParameterf) /* 385 */ \ - OP(TexParameterfv) /* 386 */ \ - OP(TexParameterfvImmediate) /* 387 */ \ - OP(TexParameteri) /* 388 */ \ - OP(TexParameteriv) /* 389 */ \ - OP(TexParameterivImmediate) /* 390 */ \ - OP(TexSubImage2D) /* 391 */ \ - OP(TexSubImage2DImmediate) /* 392 */ \ - OP(Uniform1f) /* 393 */ \ - OP(Uniform1fv) /* 394 */ \ - OP(Uniform1fvImmediate) /* 395 */ \ - OP(Uniform1i) /* 396 */ \ - OP(Uniform1iv) /* 397 */ \ - OP(Uniform1ivImmediate) /* 398 */ \ - OP(Uniform2f) /* 399 */ \ - OP(Uniform2fv) /* 400 */ \ - OP(Uniform2fvImmediate) /* 401 */ \ - OP(Uniform2i) /* 402 */ \ - OP(Uniform2iv) /* 403 */ \ - OP(Uniform2ivImmediate) /* 404 */ \ - OP(Uniform3f) /* 405 */ \ - OP(Uniform3fv) /* 406 */ \ - OP(Uniform3fvImmediate) /* 407 */ \ - OP(Uniform3i) /* 408 */ \ - OP(Uniform3iv) /* 409 */ \ - OP(Uniform3ivImmediate) /* 410 */ \ - OP(Uniform4f) /* 411 */ \ - OP(Uniform4fv) /* 412 */ \ - OP(Uniform4fvImmediate) /* 413 */ \ - OP(Uniform4i) /* 414 */ \ - OP(Uniform4iv) /* 415 */ \ - OP(Uniform4ivImmediate) /* 416 */ \ - OP(UniformMatrix2fv) /* 417 */ \ - OP(UniformMatrix2fvImmediate) /* 418 */ \ - OP(UniformMatrix3fv) /* 419 */ \ - OP(UniformMatrix3fvImmediate) /* 420 */ \ - OP(UniformMatrix4fv) /* 421 */ \ - OP(UniformMatrix4fvImmediate) /* 422 */ \ - OP(UseProgram) /* 423 */ \ - OP(ValidateProgram) /* 424 */ \ - OP(VertexAttrib1f) /* 425 */ \ - OP(VertexAttrib1fv) /* 426 */ \ - OP(VertexAttrib1fvImmediate) /* 427 */ \ - OP(VertexAttrib2f) /* 428 */ \ - OP(VertexAttrib2fv) /* 429 */ \ - OP(VertexAttrib2fvImmediate) /* 430 */ \ - OP(VertexAttrib3f) /* 431 */ \ - OP(VertexAttrib3fv) /* 432 */ \ - OP(VertexAttrib3fvImmediate) /* 433 */ \ - OP(VertexAttrib4f) /* 434 */ \ - OP(VertexAttrib4fv) /* 435 */ \ - OP(VertexAttrib4fvImmediate) /* 436 */ \ - OP(VertexAttribPointer) /* 437 */ \ - OP(Viewport) /* 438 */ \ - OP(BlitFramebufferEXT) /* 439 */ \ - OP(RenderbufferStorageMultisampleEXT) /* 440 */ \ - OP(FramebufferTexture2DMultisampleEXT) /* 441 */ \ - OP(TexStorage2DEXT) /* 442 */ \ - OP(GenQueriesEXT) /* 443 */ \ - OP(GenQueriesEXTImmediate) /* 444 */ \ - OP(DeleteQueriesEXT) /* 445 */ \ - OP(DeleteQueriesEXTImmediate) /* 446 */ \ - OP(BeginQueryEXT) /* 447 */ \ - OP(EndQueryEXT) /* 448 */ \ - OP(InsertEventMarkerEXT) /* 449 */ \ - OP(PushGroupMarkerEXT) /* 450 */ \ - OP(PopGroupMarkerEXT) /* 451 */ \ - OP(GenVertexArraysOES) /* 452 */ \ - OP(GenVertexArraysOESImmediate) /* 453 */ \ - OP(DeleteVertexArraysOES) /* 454 */ \ - OP(DeleteVertexArraysOESImmediate) /* 455 */ \ - OP(IsVertexArrayOES) /* 456 */ \ - OP(BindVertexArrayOES) /* 457 */ \ - OP(SwapBuffers) /* 458 */ \ - OP(GetMaxValueInBufferCHROMIUM) /* 459 */ \ - OP(GenSharedIdsCHROMIUM) /* 460 */ \ - OP(DeleteSharedIdsCHROMIUM) /* 461 */ \ - OP(RegisterSharedIdsCHROMIUM) /* 462 */ \ - OP(EnableFeatureCHROMIUM) /* 463 */ \ - OP(ResizeCHROMIUM) /* 464 */ \ - OP(GetRequestableExtensionsCHROMIUM) /* 465 */ \ - OP(RequestExtensionCHROMIUM) /* 466 */ \ - OP(GetMultipleIntegervCHROMIUM) /* 467 */ \ - OP(GetProgramInfoCHROMIUM) /* 468 */ \ - OP(CreateStreamTextureCHROMIUM) /* 469 */ \ - OP(DestroyStreamTextureCHROMIUM) /* 470 */ \ - OP(GetTranslatedShaderSourceANGLE) /* 471 */ \ - OP(PostSubBufferCHROMIUM) /* 472 */ \ - OP(TexImageIOSurface2DCHROMIUM) /* 473 */ \ - OP(CopyTextureCHROMIUM) /* 474 */ \ - OP(DrawArraysInstancedANGLE) /* 475 */ \ - OP(DrawElementsInstancedANGLE) /* 476 */ \ - OP(VertexAttribDivisorANGLE) /* 477 */ \ - OP(GenMailboxCHROMIUM) /* 478 */ \ - OP(ProduceTextureCHROMIUM) /* 479 */ \ - OP(ProduceTextureCHROMIUMImmediate) /* 480 */ \ - OP(ConsumeTextureCHROMIUM) /* 481 */ \ - OP(ConsumeTextureCHROMIUMImmediate) /* 482 */ \ - OP(BindUniformLocationCHROMIUM) /* 483 */ \ - OP(BindUniformLocationCHROMIUMImmediate) /* 484 */ \ - OP(BindUniformLocationCHROMIUMBucket) /* 485 */ \ - OP(BindTexImage2DCHROMIUM) /* 486 */ \ - OP(ReleaseTexImage2DCHROMIUM) /* 487 */ \ - OP(TraceBeginCHROMIUM) /* 488 */ \ - OP(TraceEndCHROMIUM) /* 489 */ \ - OP(AsyncTexSubImage2DCHROMIUM) /* 490 */ \ - OP(AsyncTexImage2DCHROMIUM) /* 491 */ \ - OP(WaitAsyncTexImage2DCHROMIUM) /* 492 */ \ - OP(DiscardFramebufferEXT) /* 493 */ \ - OP(DiscardFramebufferEXTImmediate) /* 494 */ \ - OP(LoseContextCHROMIUM) /* 495 */ \ - OP(InsertSyncPointCHROMIUM) /* 496 */ \ - OP(WaitSyncPointCHROMIUM) /* 497 */ \ - OP(DrawBuffersEXT) /* 498 */ \ - OP(DrawBuffersEXTImmediate) /* 499 */ \ + OP(BindAttribLocationBucket) /* 259 */ \ + OP(BindBuffer) /* 260 */ \ + OP(BindFramebuffer) /* 261 */ \ + OP(BindRenderbuffer) /* 262 */ \ + OP(BindTexture) /* 263 */ \ + OP(BlendColor) /* 264 */ \ + OP(BlendEquation) /* 265 */ \ + OP(BlendEquationSeparate) /* 266 */ \ + OP(BlendFunc) /* 267 */ \ + OP(BlendFuncSeparate) /* 268 */ \ + OP(BufferData) /* 269 */ \ + OP(BufferSubData) /* 270 */ \ + OP(CheckFramebufferStatus) /* 271 */ \ + OP(Clear) /* 272 */ \ + OP(ClearColor) /* 273 */ \ + OP(ClearDepthf) /* 274 */ \ + OP(ClearStencil) /* 275 */ \ + OP(ColorMask) /* 276 */ \ + OP(CompileShader) /* 277 */ \ + OP(CompressedTexImage2D) /* 278 */ \ + OP(CompressedTexImage2DBucket) /* 279 */ \ + OP(CompressedTexSubImage2D) /* 280 */ \ + OP(CompressedTexSubImage2DBucket) /* 281 */ \ + OP(CopyTexImage2D) /* 282 */ \ + OP(CopyTexSubImage2D) /* 283 */ \ + OP(CreateProgram) /* 284 */ \ + OP(CreateShader) /* 285 */ \ + OP(CullFace) /* 286 */ \ + OP(DeleteBuffers) /* 287 */ \ + OP(DeleteBuffersImmediate) /* 288 */ \ + OP(DeleteFramebuffers) /* 289 */ \ + OP(DeleteFramebuffersImmediate) /* 290 */ \ + OP(DeleteProgram) /* 291 */ \ + OP(DeleteRenderbuffers) /* 292 */ \ + OP(DeleteRenderbuffersImmediate) /* 293 */ \ + OP(DeleteShader) /* 294 */ \ + OP(DeleteTextures) /* 295 */ \ + OP(DeleteTexturesImmediate) /* 296 */ \ + OP(DepthFunc) /* 297 */ \ + OP(DepthMask) /* 298 */ \ + OP(DepthRangef) /* 299 */ \ + OP(DetachShader) /* 300 */ \ + OP(Disable) /* 301 */ \ + OP(DisableVertexAttribArray) /* 302 */ \ + OP(DrawArrays) /* 303 */ \ + OP(DrawElements) /* 304 */ \ + OP(Enable) /* 305 */ \ + OP(EnableVertexAttribArray) /* 306 */ \ + OP(Finish) /* 307 */ \ + OP(Flush) /* 308 */ \ + OP(FramebufferRenderbuffer) /* 309 */ \ + OP(FramebufferTexture2D) /* 310 */ \ + OP(FrontFace) /* 311 */ \ + OP(GenBuffers) /* 312 */ \ + OP(GenBuffersImmediate) /* 313 */ \ + OP(GenerateMipmap) /* 314 */ \ + OP(GenFramebuffers) /* 315 */ \ + OP(GenFramebuffersImmediate) /* 316 */ \ + OP(GenRenderbuffers) /* 317 */ \ + OP(GenRenderbuffersImmediate) /* 318 */ \ + OP(GenTextures) /* 319 */ \ + OP(GenTexturesImmediate) /* 320 */ \ + OP(GetActiveAttrib) /* 321 */ \ + OP(GetActiveUniform) /* 322 */ \ + OP(GetAttachedShaders) /* 323 */ \ + OP(GetAttribLocation) /* 324 */ \ + OP(GetAttribLocationBucket) /* 325 */ \ + OP(GetBooleanv) /* 326 */ \ + OP(GetBufferParameteriv) /* 327 */ \ + OP(GetError) /* 328 */ \ + OP(GetFloatv) /* 329 */ \ + OP(GetFramebufferAttachmentParameteriv) /* 330 */ \ + OP(GetIntegerv) /* 331 */ \ + OP(GetProgramiv) /* 332 */ \ + OP(GetProgramInfoLog) /* 333 */ \ + OP(GetRenderbufferParameteriv) /* 334 */ \ + OP(GetShaderiv) /* 335 */ \ + OP(GetShaderInfoLog) /* 336 */ \ + OP(GetShaderPrecisionFormat) /* 337 */ \ + OP(GetShaderSource) /* 338 */ \ + OP(GetString) /* 339 */ \ + OP(GetTexParameterfv) /* 340 */ \ + OP(GetTexParameteriv) /* 341 */ \ + OP(GetUniformfv) /* 342 */ \ + OP(GetUniformiv) /* 343 */ \ + OP(GetUniformLocation) /* 344 */ \ + OP(GetUniformLocationBucket) /* 345 */ \ + OP(GetVertexAttribfv) /* 346 */ \ + OP(GetVertexAttribiv) /* 347 */ \ + OP(GetVertexAttribPointerv) /* 348 */ \ + OP(Hint) /* 349 */ \ + OP(IsBuffer) /* 350 */ \ + OP(IsEnabled) /* 351 */ \ + OP(IsFramebuffer) /* 352 */ \ + OP(IsProgram) /* 353 */ \ + OP(IsRenderbuffer) /* 354 */ \ + OP(IsShader) /* 355 */ \ + OP(IsTexture) /* 356 */ \ + OP(LineWidth) /* 357 */ \ + OP(LinkProgram) /* 358 */ \ + OP(PixelStorei) /* 359 */ \ + OP(PolygonOffset) /* 360 */ \ + OP(ReadPixels) /* 361 */ \ + OP(ReleaseShaderCompiler) /* 362 */ \ + OP(RenderbufferStorage) /* 363 */ \ + OP(SampleCoverage) /* 364 */ \ + OP(Scissor) /* 365 */ \ + OP(ShaderBinary) /* 366 */ \ + OP(ShaderSource) /* 367 */ \ + OP(ShaderSourceBucket) /* 368 */ \ + OP(StencilFunc) /* 369 */ \ + OP(StencilFuncSeparate) /* 370 */ \ + OP(StencilMask) /* 371 */ \ + OP(StencilMaskSeparate) /* 372 */ \ + OP(StencilOp) /* 373 */ \ + OP(StencilOpSeparate) /* 374 */ \ + OP(TexImage2D) /* 375 */ \ + OP(TexParameterf) /* 376 */ \ + OP(TexParameterfv) /* 377 */ \ + OP(TexParameterfvImmediate) /* 378 */ \ + OP(TexParameteri) /* 379 */ \ + OP(TexParameteriv) /* 380 */ \ + OP(TexParameterivImmediate) /* 381 */ \ + OP(TexSubImage2D) /* 382 */ \ + OP(Uniform1f) /* 383 */ \ + OP(Uniform1fv) /* 384 */ \ + OP(Uniform1fvImmediate) /* 385 */ \ + OP(Uniform1i) /* 386 */ \ + OP(Uniform1iv) /* 387 */ \ + OP(Uniform1ivImmediate) /* 388 */ \ + OP(Uniform2f) /* 389 */ \ + OP(Uniform2fv) /* 390 */ \ + OP(Uniform2fvImmediate) /* 391 */ \ + OP(Uniform2i) /* 392 */ \ + OP(Uniform2iv) /* 393 */ \ + OP(Uniform2ivImmediate) /* 394 */ \ + OP(Uniform3f) /* 395 */ \ + OP(Uniform3fv) /* 396 */ \ + OP(Uniform3fvImmediate) /* 397 */ \ + OP(Uniform3i) /* 398 */ \ + OP(Uniform3iv) /* 399 */ \ + OP(Uniform3ivImmediate) /* 400 */ \ + OP(Uniform4f) /* 401 */ \ + OP(Uniform4fv) /* 402 */ \ + OP(Uniform4fvImmediate) /* 403 */ \ + OP(Uniform4i) /* 404 */ \ + OP(Uniform4iv) /* 405 */ \ + OP(Uniform4ivImmediate) /* 406 */ \ + OP(UniformMatrix2fv) /* 407 */ \ + OP(UniformMatrix2fvImmediate) /* 408 */ \ + OP(UniformMatrix3fv) /* 409 */ \ + OP(UniformMatrix3fvImmediate) /* 410 */ \ + OP(UniformMatrix4fv) /* 411 */ \ + OP(UniformMatrix4fvImmediate) /* 412 */ \ + OP(UseProgram) /* 413 */ \ + OP(ValidateProgram) /* 414 */ \ + OP(VertexAttrib1f) /* 415 */ \ + OP(VertexAttrib1fv) /* 416 */ \ + OP(VertexAttrib1fvImmediate) /* 417 */ \ + OP(VertexAttrib2f) /* 418 */ \ + OP(VertexAttrib2fv) /* 419 */ \ + OP(VertexAttrib2fvImmediate) /* 420 */ \ + OP(VertexAttrib3f) /* 421 */ \ + OP(VertexAttrib3fv) /* 422 */ \ + OP(VertexAttrib3fvImmediate) /* 423 */ \ + OP(VertexAttrib4f) /* 424 */ \ + OP(VertexAttrib4fv) /* 425 */ \ + OP(VertexAttrib4fvImmediate) /* 426 */ \ + OP(VertexAttribPointer) /* 427 */ \ + OP(Viewport) /* 428 */ \ + OP(BlitFramebufferCHROMIUM) /* 429 */ \ + OP(RenderbufferStorageMultisampleCHROMIUM) /* 430 */ \ + OP(RenderbufferStorageMultisampleEXT) /* 431 */ \ + OP(FramebufferTexture2DMultisampleEXT) /* 432 */ \ + OP(TexStorage2DEXT) /* 433 */ \ + OP(GenQueriesEXT) /* 434 */ \ + OP(GenQueriesEXTImmediate) /* 435 */ \ + OP(DeleteQueriesEXT) /* 436 */ \ + OP(DeleteQueriesEXTImmediate) /* 437 */ \ + OP(BeginQueryEXT) /* 438 */ \ + OP(EndQueryEXT) /* 439 */ \ + OP(InsertEventMarkerEXT) /* 440 */ \ + OP(PushGroupMarkerEXT) /* 441 */ \ + OP(PopGroupMarkerEXT) /* 442 */ \ + OP(GenVertexArraysOES) /* 443 */ \ + OP(GenVertexArraysOESImmediate) /* 444 */ \ + OP(DeleteVertexArraysOES) /* 445 */ \ + OP(DeleteVertexArraysOESImmediate) /* 446 */ \ + OP(IsVertexArrayOES) /* 447 */ \ + OP(BindVertexArrayOES) /* 448 */ \ + OP(SwapBuffers) /* 449 */ \ + OP(GetMaxValueInBufferCHROMIUM) /* 450 */ \ + OP(GenSharedIdsCHROMIUM) /* 451 */ \ + OP(DeleteSharedIdsCHROMIUM) /* 452 */ \ + OP(RegisterSharedIdsCHROMIUM) /* 453 */ \ + OP(EnableFeatureCHROMIUM) /* 454 */ \ + OP(ResizeCHROMIUM) /* 455 */ \ + OP(GetRequestableExtensionsCHROMIUM) /* 456 */ \ + OP(RequestExtensionCHROMIUM) /* 457 */ \ + OP(GetMultipleIntegervCHROMIUM) /* 458 */ \ + OP(GetProgramInfoCHROMIUM) /* 459 */ \ + OP(CreateStreamTextureCHROMIUM) /* 460 */ \ + OP(DestroyStreamTextureCHROMIUM) /* 461 */ \ + OP(GetTranslatedShaderSourceANGLE) /* 462 */ \ + OP(PostSubBufferCHROMIUM) /* 463 */ \ + OP(TexImageIOSurface2DCHROMIUM) /* 464 */ \ + OP(CopyTextureCHROMIUM) /* 465 */ \ + OP(DrawArraysInstancedANGLE) /* 466 */ \ + OP(DrawElementsInstancedANGLE) /* 467 */ \ + OP(VertexAttribDivisorANGLE) /* 468 */ \ + OP(GenMailboxCHROMIUM) /* 469 */ \ + OP(ProduceTextureCHROMIUM) /* 470 */ \ + OP(ProduceTextureCHROMIUMImmediate) /* 471 */ \ + OP(ConsumeTextureCHROMIUM) /* 472 */ \ + OP(ConsumeTextureCHROMIUMImmediate) /* 473 */ \ + OP(BindUniformLocationCHROMIUM) /* 474 */ \ + OP(BindUniformLocationCHROMIUMBucket) /* 475 */ \ + OP(BindTexImage2DCHROMIUM) /* 476 */ \ + OP(ReleaseTexImage2DCHROMIUM) /* 477 */ \ + OP(TraceBeginCHROMIUM) /* 478 */ \ + OP(TraceEndCHROMIUM) /* 479 */ \ + OP(AsyncTexSubImage2DCHROMIUM) /* 480 */ \ + OP(AsyncTexImage2DCHROMIUM) /* 481 */ \ + OP(WaitAsyncTexImage2DCHROMIUM) /* 482 */ \ + OP(DiscardFramebufferEXT) /* 483 */ \ + OP(DiscardFramebufferEXTImmediate) /* 484 */ \ + OP(LoseContextCHROMIUM) /* 485 */ \ + OP(InsertSyncPointCHROMIUM) /* 486 */ \ + OP(WaitSyncPointCHROMIUM) /* 487 */ \ + OP(DrawBuffersEXT) /* 488 */ \ + OP(DrawBuffersEXTImmediate) /* 489 */ \ + OP(DiscardBackbufferCHROMIUM) /* 490 */ \ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc b/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc index 301ef4a1a11..b7d5e525e6d 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc +++ b/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc @@ -555,7 +555,7 @@ uint32 GLES2Util::GLErrorToErrorBit(uint32 error) { case GL_INVALID_FRAMEBUFFER_OPERATION: return gl_error_bit::kInvalidFrameBufferOperation; default: - GPU_NOTREACHED(); + NOTREACHED(); return gl_error_bit::kNoError; } } @@ -573,7 +573,7 @@ uint32 GLES2Util::GLErrorBitToGLError(uint32 error_bit) { case gl_error_bit::kInvalidFrameBufferOperation: return GL_INVALID_FRAMEBUFFER_OPERATION; default: - GPU_NOTREACHED(); + NOTREACHED(); return GL_NO_ERROR; } } @@ -590,6 +590,43 @@ uint32 GLES2Util::IndexToGLFaceTarget(int index) { return faces[index]; } +uint32 GLES2Util::GetPreferredGLReadPixelsFormat(uint32 internal_format) { + switch (internal_format) { + case GL_RGB16F_EXT: + case GL_RGB32F_EXT: + return GL_RGB; + case GL_RGBA16F_EXT: + case GL_RGBA32F_EXT: + return GL_RGBA; + default: + return GL_RGBA; + } +} + +uint32 GLES2Util::GetPreferredGLReadPixelsType( + uint32 internal_format, uint32 texture_type) { + switch (internal_format) { + case GL_RGBA32F_EXT: + case GL_RGB32F_EXT: + return GL_FLOAT; + case GL_RGBA16F_EXT: + case GL_RGB16F_EXT: + return GL_HALF_FLOAT_OES; + case GL_RGBA: + case GL_RGB: + // Unsized internal format, check the type + switch (texture_type) { + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + return GL_FLOAT; + default: + return GL_UNSIGNED_BYTE; + } + default: + return GL_UNSIGNED_BYTE; + } +} + uint32 GLES2Util::GetChannelsForFormat(int format) { switch (format) { case GL_ALPHA: @@ -734,6 +771,7 @@ const int32 kBufferDestroyed = 0x3095; // EGL_BUFFER_DESTROYED // Chromium only. const int32 kShareResources = 0x10000; const int32 kBindGeneratesResource = 0x10001; +const int32 kFailIfMajorPerfCaveat = 0x10002; } // namespace @@ -748,7 +786,8 @@ ContextCreationAttribHelper::ContextCreationAttribHelper() sample_buffers_(-1), buffer_preserved_(true), share_resources_(false), - bind_generates_resource_(true) { + bind_generates_resource_(true), + fail_if_major_perf_caveat_(false) { } void ContextCreationAttribHelper::Serialize(std::vector<int32>* attribs) { @@ -790,6 +829,8 @@ void ContextCreationAttribHelper::Serialize(std::vector<int32>* attribs) { attribs->push_back(share_resources_ ? 1 : 0); attribs->push_back(kBindGeneratesResource); attribs->push_back(bind_generates_resource_ ? 1 : 0); + attribs->push_back(kFailIfMajorPerfCaveat); + attribs->push_back(fail_if_major_perf_caveat_ ? 1 : 0); attribs->push_back(kNone); } @@ -801,8 +842,8 @@ bool ContextCreationAttribHelper::Parse(const std::vector<int32>& attribs) { return true; } - GPU_DLOG(ERROR) << "Missing value after context creation attribute: " - << attrib; + DLOG(ERROR) << "Missing value after context creation attribute: " + << attrib; return false; } @@ -841,11 +882,14 @@ bool ContextCreationAttribHelper::Parse(const std::vector<int32>& attribs) { case kBindGeneratesResource: bind_generates_resource_ = value != 0; break; + case kFailIfMajorPerfCaveat: + fail_if_major_perf_caveat_ = value != 0; + break; case kNone: // Terminate list, even if more attributes. return true; default: - GPU_DLOG(ERROR) << "Invalid context creation attribute: " << attrib; + DLOG(ERROR) << "Invalid context creation attribute: " << attrib; return false; } } diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_utils.h b/chromium/gpu/command_buffer/common/gles2_cmd_utils.h index b8619e61d37..59b5d96de8c 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_utils.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_utils.h @@ -132,6 +132,11 @@ class GLES2_UTILS_EXPORT GLES2Util { static uint32 IndexToGLFaceTarget(int index); + static uint32 GetPreferredGLReadPixelsFormat(uint32 internal_format); + + static uint32 GetPreferredGLReadPixelsType( + uint32 internal_format, uint32 texture_type); + // Returns a bitmask for the channels the given format supports. // See ChannelBits. static uint32 GetChannelsForFormat(int format); @@ -193,6 +198,7 @@ class GLES2_UTILS_EXPORT ContextCreationAttribHelper { bool buffer_preserved_; bool share_resources_; bool bind_generates_resource_; + bool fail_if_major_perf_caveat_; }; } // namespace gles2 diff --git a/chromium/gpu/command_buffer/common/gpu_control.h b/chromium/gpu/command_buffer/common/gpu_control.h index 5534ca78967..d9719727111 100644 --- a/chromium/gpu/command_buffer/common/gpu_control.h +++ b/chromium/gpu/command_buffer/common/gpu_control.h @@ -5,6 +5,12 @@ #ifndef GPU_COMMAND_BUFFER_COMMON_GPU_CONTROL_H_ #define GPU_COMMAND_BUFFER_COMMON_GPU_CONTROL_H_ +#include <vector> + +#include "base/callback.h" +#include "gpu/command_buffer/common/capabilities.h" +#include "gpu/command_buffer/common/mailbox.h" +#include "gpu/command_buffer/common/types.h" #include "gpu/gpu_export.h" namespace gfx { @@ -12,6 +18,7 @@ class GpuMemoryBuffer; } namespace gpu { +struct ManagedMemoryStats; // Common interface for GpuControl implementations. class GPU_EXPORT GpuControl { @@ -19,6 +26,8 @@ class GPU_EXPORT GpuControl { GpuControl() {} virtual ~GpuControl() {} + virtual Capabilities GetCapabilities() = 0; + // Create a gpu memory buffer of the given dimensions and format. Returns // its ID or -1 on error. virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer( @@ -30,6 +39,30 @@ class GPU_EXPORT GpuControl { // Destroy a gpu memory buffer. The ID must be positive. virtual void DestroyGpuMemoryBuffer(int32 id) = 0; + // Generates n unique mailbox names that can be used with + // GL_texture_mailbox_CHROMIUM. + virtual bool GenerateMailboxNames(unsigned num, + std::vector<gpu::Mailbox>* names) = 0; + + // Inserts a sync point, returning its ID. Sync point IDs are global and can + // be used for cross-context synchronization. + virtual uint32 InsertSyncPoint() = 0; + + // Runs |callback| when a sync point is reached. + virtual void SignalSyncPoint(uint32 sync_point, + const base::Closure& callback) = 0; + + // Runs |callback| when a query created via glCreateQueryEXT() has cleared + // passed the glEndQueryEXT() point. + virtual void SignalQuery(uint32 query, const base::Closure& callback) = 0; + + virtual void SetSurfaceVisible(bool visible) = 0; + + virtual void SendManagedMemoryStats(const ManagedMemoryStats& stats) = 0; + + // Invokes the callback once the context has been flushed. + virtual void Echo(const base::Closure& callback) = 0; + private: DISALLOW_COPY_AND_ASSIGN(GpuControl); }; diff --git a/chromium/gpu/command_buffer/common/gpu_memory_allocation.h b/chromium/gpu/command_buffer/common/gpu_memory_allocation.h new file mode 100644 index 00000000000..57be4c5490f --- /dev/null +++ b/chromium/gpu/command_buffer/common/gpu_memory_allocation.h @@ -0,0 +1,95 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_COMMON_GPU_MEMORY_ALLOCATION_H_ +#define GPU_COMMAND_BUFFER_COMMON_GPU_MEMORY_ALLOCATION_H_ + +#include "base/basictypes.h" + +namespace gpu { + +// These are per context memory allocation limits set by the GpuMemoryManager +// and assigned to the browser and renderer context. +// They will change over time, given memory availability, and browser state. +struct MemoryAllocation { + enum PriorityCutoff { + // Allow no allocations. + CUTOFF_ALLOW_NOTHING, + // Allow only allocations that are strictly required for correct rendering. + // For compositors, this is what is visible. + CUTOFF_ALLOW_REQUIRED_ONLY, + // Allow allocations that are not strictly needed for correct rendering, but + // are nice to have for performance. For compositors, this includes textures + // that are a few screens away from being visible. + CUTOFF_ALLOW_NICE_TO_HAVE, + // Allow all allocations. + CUTOFF_ALLOW_EVERYTHING, + }; + + // Limits when this renderer is visible. + uint64 bytes_limit_when_visible; + PriorityCutoff priority_cutoff_when_visible; + + MemoryAllocation() + : bytes_limit_when_visible(0), + priority_cutoff_when_visible(CUTOFF_ALLOW_NOTHING) { + } + + MemoryAllocation(uint64 bytes_limit_when_visible) + : bytes_limit_when_visible(bytes_limit_when_visible), + priority_cutoff_when_visible(CUTOFF_ALLOW_EVERYTHING) { + } + + bool Equals(const MemoryAllocation& other) const { + return bytes_limit_when_visible == + other.bytes_limit_when_visible && + priority_cutoff_when_visible == other.priority_cutoff_when_visible; + } +}; + +// Memory Allocation request which is sent by a client, to help GpuMemoryManager +// more ideally split memory allocations across clients. +struct ManagedMemoryStats { + // Bytes required for correct rendering. + uint64 bytes_required; + + // Bytes that are not strictly required for correctness, but, if allocated, + // will provide good performance. + uint64 bytes_nice_to_have; + + // The number of bytes currently allocated. + uint64 bytes_allocated; + + // Whether or not a backbuffer is currently requested (the memory usage + // of the buffer is known by the GPU process). + bool backbuffer_requested; + + ManagedMemoryStats() + : bytes_required(0), + bytes_nice_to_have(0), + bytes_allocated(0), + backbuffer_requested(false) { + } + + ManagedMemoryStats(uint64 bytes_required, + uint64 bytes_nice_to_have, + uint64 bytes_allocated, + bool backbuffer_requested) + : bytes_required(bytes_required), + bytes_nice_to_have(bytes_nice_to_have), + bytes_allocated(bytes_allocated), + backbuffer_requested(backbuffer_requested) { + } + + bool Equals(const ManagedMemoryStats& other) const { + return bytes_required == other.bytes_required && + bytes_nice_to_have == other.bytes_nice_to_have && + bytes_allocated == other.bytes_allocated && + backbuffer_requested == other.backbuffer_requested; + } +}; + +} // namespace content + +#endif // GPU_COMMAND_BUFFER_COMMON_GPU_MEMORY_ALLOCATION_H_ diff --git a/chromium/gpu/command_buffer/common/id_allocator.cc b/chromium/gpu/command_buffer/common/id_allocator.cc index b881e051a5a..7802e1766be 100644 --- a/chromium/gpu/command_buffer/common/id_allocator.cc +++ b/chromium/gpu/command_buffer/common/id_allocator.cc @@ -5,7 +5,8 @@ // This file contains the implementation of IdAllocator. #include "gpu/command_buffer/common/id_allocator.h" -#include "gpu/command_buffer/common/logging.h" + +#include "base/logging.h" namespace gpu { @@ -51,7 +52,7 @@ ResourceId IdAllocator::AllocateIDAtOrAbove(ResourceId desired_id) { } bool IdAllocator::MarkAsUsed(ResourceId id) { - GPU_DCHECK(id); + DCHECK(id); free_ids_.erase(id); std::pair<ResourceIdSet::iterator, bool> result = used_ids_.insert(id); return result.second; @@ -106,7 +107,7 @@ ResourceId NonReusedIdAllocator::AllocateIDAtOrAbove(ResourceId desired_id) { } bool NonReusedIdAllocator::MarkAsUsed(ResourceId id) { - GPU_NOTREACHED(); + NOTREACHED(); return false; } @@ -114,7 +115,7 @@ void NonReusedIdAllocator::FreeID(ResourceId id) { } bool NonReusedIdAllocator::InUse(ResourceId id) const { - GPU_NOTREACHED(); + NOTREACHED(); return false; } diff --git a/chromium/gpu/command_buffer/common/logging.cc b/chromium/gpu/command_buffer/common/logging.cc deleted file mode 100644 index 4bc35103008..00000000000 --- a/chromium/gpu/command_buffer/common/logging.cc +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gpu/command_buffer/common/logging.h" - -#include <iostream> - -namespace gpu { - -std::ostream& Logger::stream() { - return std::cerr; -} - -Logger::~Logger() { - if (!condition_) { - std::cerr << std::endl; - std::cerr.flush(); - if (level_ == FATAL) - assert(false); - } -} - -} // namespace gpu diff --git a/chromium/gpu/command_buffer/common/logging.h b/chromium/gpu/command_buffer/common/logging.h deleted file mode 100644 index 2133a87bc0a..00000000000 --- a/chromium/gpu/command_buffer/common/logging.h +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef GPU_COMMAND_BUFFER_COMMON_LOGGING_H_ -#define GPU_COMMAND_BUFFER_COMMON_LOGGING_H_ - -#include <assert.h> - -#include <ostream> - -#include "gpu/command_buffer/common/gles2_utils_export.h" - -// Windows defines an ERROR macro. -#ifdef ERROR -#undef ERROR -#endif - -namespace gpu { - -// Members are uppercase instead of kCamelCase for consistency with base log -// severity enum. -enum LogLevel { - INFO, - WARNING, - ERROR, - FATAL -}; - -// This is a very simple logger for use in command buffer code. Common and -// command buffer code cannot be dependent on base. It just outputs the message -// to stderr. -class GLES2_UTILS_EXPORT Logger { - public: - Logger(bool condition, LogLevel level) - : condition_(condition), - level_(level) { - } - - template <typename X> - static Logger CheckTrue(const X& x, - const char* file, int line, - const char* x_name, - const char* check_name) { - if (!!x) - return Logger(true, FATAL); - - return Logger(false, FATAL) - << file << "(" << line << "): " << check_name - << "(" << x_name << " (" << x << ")) failed. "; - } - - template <typename X, typename Y> - static Logger CheckEqual(const X& x, const Y& y, - const char* file, int line, - const char* x_name, const char* y_name, - const char* check_name) { - if (x == y) - return Logger(true, FATAL); - - return Logger(false, FATAL) - << file << "(" << line << "): " << check_name - << "(" << x_name << " (" << x << "), " - << y_name << "(" << y << ")) failed. "; - } - - template <typename X, typename Y> - static Logger CheckNotEqual(const X& x, const Y& y, - const char* file, int line, - const char* x_name, const char* y_name, - const char* check_name) { - if (x != y) - return Logger(true, FATAL); - - return Logger(false, FATAL) - << file << "(" << line << "): " << check_name - << "(" << x_name << " (" << x << "), " - << y_name << "(" << y << ")) failed. "; - } - - template <typename X, typename Y> - static Logger CheckLessThan(const X& x, const Y& y, - const char* file, int line, - const char* x_name, const char* y_name, - const char* check_name) { - if (x < y) - return Logger(true, FATAL); - - return Logger(false, FATAL) - << file << "(" << line << "): " << check_name - << "(" << x_name << " (" << x << "), " - << y_name << "(" << y << ")) failed. "; - } - - template <typename X, typename Y> - static Logger CheckGreaterThan(const X& x, const Y& y, - const char* file, int line, - const char* x_name, const char* y_name, - const char* check_name) { - if (x > y) - return Logger(true, FATAL); - - return Logger(false, FATAL) - << file << "(" << line << "): " << check_name - << "(" << x_name << " (" << x << "), " - << y_name << "(" << y << ")) failed. "; - } - - template <typename X, typename Y> - static Logger CheckLessEqual(const X& x, const Y& y, - const char* file, int line, - const char* x_name, const char* y_name, - const char* check_name) { - if (x <= y) - return Logger(true, FATAL); - - return Logger(false, FATAL) - << file << "(" << line << "): " << check_name - << "(" << x_name << " (" << x << "), " - << y_name << "(" << y << ")) failed. "; - } - - template <typename X, typename Y> - static Logger CheckGreaterEqual(const X& x, const Y& y, - const char* file, int line, - const char* x_name, const char* y_name, - const char* check_name) { - if (x >= y) - return Logger(true, FATAL); - - return Logger(false, FATAL) - << file << "(" << line << "): " << check_name - << "(" << x_name << " (" << x << "), " - << y_name << "(" << y << ")) failed. "; - } - - // Retrieves the stream that we write to. This header cannot depend on - // <iostream> because that will add static initializers to all files that - // include this header. - std::ostream& stream(); - - ~Logger(); - - template <typename T> - Logger& operator<<(const T& value) { - if (!condition_) - stream() << value; - return *this; - } - - private: - Logger(const Logger& logger) - : condition_(logger.condition_), - level_(logger.level_) { - } - - const bool condition_; - const LogLevel level_; -}; - -} // namespace gpu - -#define GPU_CHECK(X) ::gpu::Logger::CheckTrue( \ - (X), __FILE__, __LINE__, #X, "GPU_CHECK") -#define GPU_CHECK_EQ(X, Y) ::gpu::Logger::CheckEqual( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_EQ") -#define GPU_CHECK_NE(X, Y) ::gpu::Logger::CheckNotEqual( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_NE") -#define GPU_CHECK_GT(X, Y) ::gpu::Logger::CheckGreaterThan( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_GT") -#define GPU_CHECK_LT(X, Y) ::gpu::Logger::CheckLessThan( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_LT") -#define GPU_CHECK_GE(X, Y) ::gpu::Logger::CheckGreaterEqual( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_GE") -#define GPU_CHECK_LE(X, Y) ::gpu::Logger::CheckLessEqual( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_LE") -#define GPU_LOG(LEVEL) ::gpu::Logger(false, LEVEL) - - -#if defined(NDEBUG) -#define GPU_DEBUG_IS_ON false -#else -#define GPU_DEBUG_IS_ON true -#endif - - -#define GPU_DCHECK(X) \ - if (GPU_DEBUG_IS_ON) \ - ::gpu::Logger::CheckTrue( \ - (X), __FILE__, __LINE__, #X, "GPU_DCHECK") -#define GPU_DCHECK_EQ(X, Y) \ - if (GPU_DEBUG_IS_ON) \ - ::gpu::Logger::CheckEqual( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_EQ") -#define GPU_DCHECK_NE(X, Y) \ - if (GPU_DEBUG_IS_ON) \ - ::gpu::Logger::CheckNotEqual( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_NE") -#define GPU_DCHECK_GT(X, Y) \ - if (GPU_DEBUG_IS_ON) \ - ::gpu::Logger::CheckGreaterThan( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_GT") -#define GPU_DCHECK_LT(X, Y) \ - if (GPU_DEBUG_IS_ON) \ - ::gpu::Logger::CheckLessThan( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_LT") -#define GPU_DCHECK_GE(X, Y) \ - if (GPU_DEBUG_IS_ON) \ - ::gpu::Logger::CheckGreaterEqual( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_GE") -#define GPU_DCHECK_LE(X, Y) \ - if (GPU_DEBUG_IS_ON) \ - ::gpu::Logger::CheckLessEqual( \ - (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_LE") -#define GPU_DLOG(LEVEL) if (GPU_DEBUG_IS_ON) ::gpu::Logger(true, LEVEL) - - - -#define GPU_NOTREACHED() GPU_DCHECK(false) - -#endif // GPU_COMMAND_BUFFER_COMMON_LOGGING_H_ diff --git a/chromium/gpu/command_buffer/common/logging_android.cc b/chromium/gpu/command_buffer/common/logging_android.cc deleted file mode 100644 index d660080d4c7..00000000000 --- a/chromium/gpu/command_buffer/common/logging_android.cc +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2013 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 <android/log.h> -#include <iostream> -#include <sstream> - -#include "gpu/command_buffer/common/logging.h" - -namespace gpu { - -namespace { -std::stringstream* g_log; -const char* kLogTag = "chromium-gpu"; -} - -std::ostream& Logger::stream() { - if (!g_log) - g_log = new std::stringstream(); - return *g_log; -} - -Logger::~Logger() { - if (!condition_) { - __android_log_print(ANDROID_LOG_INFO, kLogTag, "%s", g_log->str().c_str()); - g_log->str(std::string()); - if (level_ == FATAL) - assert(false); - } -} - -} // namespace gpu diff --git a/chromium/gpu/command_buffer/common/mailbox.cc b/chromium/gpu/command_buffer/common/mailbox.cc index be2bebf9653..8d8393fa63c 100644 --- a/chromium/gpu/command_buffer/common/mailbox.cc +++ b/chromium/gpu/command_buffer/common/mailbox.cc @@ -6,7 +6,7 @@ #include <string.h> -#include "gpu/command_buffer/common/logging.h" +#include "base/logging.h" namespace gpu { @@ -27,7 +27,7 @@ void Mailbox::SetZero() { } void Mailbox::SetName(const int8* n) { - GPU_DCHECK(IsZero() || !memcmp(name, n, sizeof(name))); + DCHECK(IsZero() || !memcmp(name, n, sizeof(name))); memcpy(name, n, sizeof(name)); } diff --git a/chromium/gpu/command_buffer/common/mailbox.h b/chromium/gpu/command_buffer/common/mailbox.h index d0e4c2c9a57..938167f5cf8 100644 --- a/chromium/gpu/command_buffer/common/mailbox.h +++ b/chromium/gpu/command_buffer/common/mailbox.h @@ -5,6 +5,8 @@ #ifndef GPU_COMMAND_BUFFER_MAILBOX_H_ #define GPU_COMMAND_BUFFER_MAILBOX_H_ +#include <string.h> + #include "gpu/command_buffer/common/types.h" #include "gpu/gpu_export.h" @@ -16,6 +18,9 @@ struct GPU_EXPORT Mailbox { void SetZero(); void SetName(const int8* name); int8 name[64]; + bool operator<(const Mailbox& other) const { + return memcmp(this, &other, sizeof other) < 0; + } }; } // namespace gpu diff --git a/chromium/gpu/command_buffer/common/unittest_main.cc b/chromium/gpu/command_buffer/common/unittest_main.cc index 08c4b348038..db22191fde2 100644 --- a/chromium/gpu/command_buffer/common/unittest_main.cc +++ b/chromium/gpu/command_buffer/common/unittest_main.cc @@ -3,11 +3,29 @@ // found in the LICENSE file. #include "base/at_exit.h" +#include "base/bind.h" #include "base/command_line.h" +#include "base/test/launcher/unit_test_launcher.h" +#include "base/test/test_suite.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_implementation.h" +namespace { + +class NoAtExitBaseTestSuite : public base::TestSuite { + public: + NoAtExitBaseTestSuite(int argc, char** argv) + : base::TestSuite(argc, argv, false) { + } +}; + +int RunTestSuite(int argc, char** argv) { + return NoAtExitBaseTestSuite(argc, argv).Run(); +} + +} // namespace + int main(int argc, char** argv) { // On Android, AtExitManager is created in // testing/android/native_test_wrapper.cc before main() is called. @@ -18,5 +36,7 @@ int main(int argc, char** argv) { CommandLine::Init(argc, argv); gfx::InitializeGLBindings(gfx::kGLImplementationMockGL); testing::InitGoogleMock(&argc, argv); - return RUN_ALL_TESTS(); + return base::LaunchUnitTests(argc, + argv, + base::Bind(&RunTestSuite, argc, argv)); } diff --git a/chromium/gpu/command_buffer/service/cmd_parser.cc b/chromium/gpu/command_buffer/service/cmd_parser.cc index 0ca1e616a86..65abc71f63c 100644 --- a/chromium/gpu/command_buffer/service/cmd_parser.cc +++ b/chromium/gpu/command_buffer/service/cmd_parser.cc @@ -7,9 +7,7 @@ #include "gpu/command_buffer/service/cmd_parser.h" #include "base/logging.h" -#include "base/command_line.h" #include "base/debug/trace_event.h" -#include "gpu/command_buffer/service/gpu_switches.h" namespace gpu { @@ -18,10 +16,7 @@ CommandParser::CommandParser(AsyncAPIInterface* handler) put_(0), buffer_(NULL), entry_count_(0), - handler_(handler), - trace_gl_commands_(false) { - trace_gl_commands_ = - CommandLine::ForCurrentProcess()->HasSwitch(switches::kTraceGL); + handler_(handler) { } void CommandParser::SetBuffer( @@ -65,8 +60,8 @@ error::Error CommandParser::ProcessCommand() { return error::kOutOfBounds; } - if (trace_gl_commands_) - TRACE_EVENT_BEGIN0("cb_command", handler_->GetCommandName(header.command)); + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cb_command"), + handler_->GetCommandName(header.command)); error::Error result = handler_->DoCommand( header.command, header.size - 1, buffer_ + get); @@ -82,8 +77,6 @@ error::Error CommandParser::ProcessCommand() { if (get == get_ && result != error::kDeferCommandUntilLater) get_ = (get + header.size) % entry_count_; - if (trace_gl_commands_) - TRACE_EVENT_END0("cb_command", handler_->GetCommandName(header.command)); return result; } diff --git a/chromium/gpu/command_buffer/service/cmd_parser.h b/chromium/gpu/command_buffer/service/cmd_parser.h index c808c4e7e66..de2fe2977ff 100644 --- a/chromium/gpu/command_buffer/service/cmd_parser.h +++ b/chromium/gpu/command_buffer/service/cmd_parser.h @@ -69,7 +69,6 @@ class GPU_EXPORT CommandParser { CommandBufferEntry* buffer_; int32 entry_count_; AsyncAPIInterface* handler_; - bool trace_gl_commands_; }; // This class defines the interface for an asynchronous API handler, that diff --git a/chromium/gpu/command_buffer/service/command_buffer_service.cc b/chromium/gpu/command_buffer/service/command_buffer_service.cc index 1cd68f53ea4..bae2d801dd5 100644 --- a/chromium/gpu/command_buffer/service/command_buffer_service.cc +++ b/chromium/gpu/command_buffer/service/command_buffer_service.cc @@ -202,9 +202,4 @@ void CommandBufferService::SetParseErrorCallback( parse_error_callback_ = callback; } -uint32 CommandBufferService::InsertSyncPoint() { - NOTREACHED(); - return 0; -} - } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/command_buffer_service.h b/chromium/gpu/command_buffer/service/command_buffer_service.h index 232bdc0a56b..b1f8fa15fea 100644 --- a/chromium/gpu/command_buffer/service/command_buffer_service.h +++ b/chromium/gpu/command_buffer/service/command_buffer_service.h @@ -38,7 +38,6 @@ class GPU_EXPORT CommandBufferService : public CommandBuffer { virtual void SetToken(int32 token) OVERRIDE; virtual void SetParseError(error::Error error) OVERRIDE; virtual void SetContextLostReason(error::ContextLostReason) OVERRIDE; - virtual uint32 InsertSyncPoint() OVERRIDE; // Sets a callback that is called whenever the put offset is changed. When // called with sync==true, the callback must not return until some progress diff --git a/chromium/gpu/command_buffer/service/context_group.cc b/chromium/gpu/command_buffer/service/context_group.cc index 0cb6e51aa23..27af0abafad 100644 --- a/chromium/gpu/command_buffer/service/context_group.cc +++ b/chromium/gpu/command_buffer/service/context_group.cc @@ -33,6 +33,7 @@ ContextGroup::ContextGroup( ImageManager* image_manager, MemoryTracker* memory_tracker, StreamTextureManager* stream_texture_manager, + FeatureInfo* feature_info, bool bind_generates_resource) : mailbox_manager_(mailbox_manager ? mailbox_manager : new MailboxManager), image_manager_(image_manager ? image_manager : new ImageManager), @@ -51,7 +52,7 @@ ContextGroup::ContextGroup( max_color_attachments_(1u), max_draw_buffers_(1u), program_cache_(NULL), - feature_info_(new FeatureInfo()), + feature_info_(feature_info ? feature_info : new FeatureInfo), draw_buffer_(GL_BACK) { { TransferBufferManager* manager = new TransferBufferManager(); diff --git a/chromium/gpu/command_buffer/service/context_group.h b/chromium/gpu/command_buffer/service/context_group.h index dd236ffa793..391db1a4ace 100644 --- a/chromium/gpu/command_buffer/service/context_group.h +++ b/chromium/gpu/command_buffer/service/context_group.h @@ -48,6 +48,7 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { ImageManager* image_manager, MemoryTracker* memory_tracker, StreamTextureManager* stream_texture_manager, + FeatureInfo* feature_info, bool bind_generates_resource); // This should only be called by GLES2Decoder. This must be paired with a diff --git a/chromium/gpu/command_buffer/service/context_group_unittest.cc b/chromium/gpu/command_buffer/service/context_group_unittest.cc index 59bc796405c..0c710362d69 100644 --- a/chromium/gpu/command_buffer/service/context_group_unittest.cc +++ b/chromium/gpu/command_buffer/service/context_group_unittest.cc @@ -39,7 +39,7 @@ class ContextGroupTest : public testing::Test { ::gfx::GLInterface::SetGLInterface(gl_.get()); decoder_.reset(new MockGLES2Decoder()); group_ = scoped_refptr<ContextGroup>( - new ContextGroup(NULL, NULL, NULL, NULL, true)); + new ContextGroup(NULL, NULL, NULL, NULL, NULL, true)); } virtual void TearDown() { diff --git a/chromium/gpu/command_buffer/service/context_state.h b/chromium/gpu/command_buffer/service/context_state.h index 4e5b2da6f05..8d5edcaea61 100644 --- a/chromium/gpu/command_buffer/service/context_state.h +++ b/chromium/gpu/command_buffer/service/context_state.h @@ -145,10 +145,6 @@ struct GPU_EXPORT ContextState { // The program in use by glUseProgram scoped_refptr<Program> current_program; - // The currently bound framebuffers - scoped_refptr<Framebuffer> bound_read_framebuffer; - scoped_refptr<Framebuffer> bound_draw_framebuffer; - // The currently bound renderbuffer scoped_refptr<Renderbuffer> bound_renderbuffer; diff --git a/chromium/gpu/command_buffer/service/context_state_impl_autogen.h b/chromium/gpu/command_buffer/service/context_state_impl_autogen.h index 65bc1181508..100199c6b49 100644 --- a/chromium/gpu/command_buffer/service/context_state_impl_autogen.h +++ b/chromium/gpu/command_buffer/service/context_state_impl_autogen.h @@ -157,7 +157,7 @@ bool ContextState::GetEnabled(GLenum cap) const { case GL_STENCIL_TEST: return enable_flags.stencil_test; default: - GPU_NOTREACHED(); + NOTREACHED(); return false; } } diff --git a/chromium/gpu/command_buffer/service/feature_info.cc b/chromium/gpu/command_buffer/service/feature_info.cc index cddf0a5c963..cbcf968adc2 100644 --- a/chromium/gpu/command_buffer/service/feature_info.cc +++ b/chromium/gpu/command_buffer/service/feature_info.cc @@ -100,11 +100,14 @@ void StringToWorkarounds( FeatureInfo::FeatureFlags::FeatureFlags() : chromium_framebuffer_multisample(false), + use_core_framebuffer_multisample(false), multisampled_render_to_texture(false), use_img_for_multisampled_render_to_texture(false), oes_standard_derivatives(false), oes_egl_image_external(false), oes_depth24(false), + oes_compressed_etc1_rgb8_texture(false), + packed_depth24_stencil8(false), npot_ok(false), enable_texture_float_linear(false), enable_texture_half_float_linear(false), @@ -117,12 +120,19 @@ FeatureInfo::FeatureFlags::FeatureFlags() use_arb_occlusion_query2_for_occlusion_query_boolean(false), use_arb_occlusion_query_for_occlusion_query_boolean(false), native_vertex_array_object(false), + ext_texture_format_bgra8888(false), enable_shader_name_hashing(false), enable_samplers(false), ext_draw_buffers(false), ext_frag_depth(false), use_async_readpixels(false), - map_buffer_range(false) { + map_buffer_range(false), + ext_discard_framebuffer(false), + angle_depth_texture(false), + is_angle(false), + is_swiftshader(false), + angle_texture_usage(false), + ext_texture_storage(false) { } FeatureInfo::Workarounds::Workarounds() : @@ -150,6 +160,9 @@ void FeatureInfo::InitializeBasicState(const CommandLine& command_line) { feature_flags_.enable_shader_name_hashing = !command_line.HasSwitch(switches::kDisableShaderNameHashing); + feature_flags_.is_swiftshader = + (command_line.GetSwitchValueASCII(switches::kUseGL) == "swiftshader"); + static const GLenum kAlphaTypes[] = { GL_UNSIGNED_BYTE, }; @@ -204,20 +217,32 @@ void FeatureInfo::InitializeFeatures() { bool npot_ok = false; + const char* renderer_str = + reinterpret_cast<const char*>(glGetString(GL_RENDERER)); + if (renderer_str) { + feature_flags_.is_angle = StartsWithASCII(renderer_str, "ANGLE", true); + } + + bool is_es3 = false; + const char* version_str = + reinterpret_cast<const char*>(glGetString(GL_VERSION)); + if (version_str) { + std::string lstr(StringToLowerASCII(std::string(version_str))); + is_es3 = (lstr.substr(0, 12) == "opengl es 3."); + } + AddExtensionString("GL_ANGLE_translated_shader_source"); AddExtensionString("GL_CHROMIUM_async_pixel_transfers"); AddExtensionString("GL_CHROMIUM_bind_uniform_location"); AddExtensionString("GL_CHROMIUM_command_buffer_query"); AddExtensionString("GL_CHROMIUM_command_buffer_latency_query"); AddExtensionString("GL_CHROMIUM_copy_texture"); - AddExtensionString("GL_CHROMIUM_discard_backbuffer"); AddExtensionString("GL_CHROMIUM_get_error_query"); AddExtensionString("GL_CHROMIUM_lose_context"); AddExtensionString("GL_CHROMIUM_pixel_transfer_buffer_object"); AddExtensionString("GL_CHROMIUM_rate_limit_offscreen_context"); AddExtensionString("GL_CHROMIUM_resize"); AddExtensionString("GL_CHROMIUM_resource_safe"); - AddExtensionString("GL_CHROMIUM_set_visibility"); AddExtensionString("GL_CHROMIUM_strict_attribs"); AddExtensionString("GL_CHROMIUM_stream_texture"); AddExtensionString("GL_CHROMIUM_texture_mailbox"); @@ -311,8 +336,10 @@ void FeatureInfo::InitializeFeatures() { if (!workarounds_.disable_depth_texture && (extensions.Contains("GL_ARB_depth_texture") || extensions.Contains("GL_OES_depth_texture") || - extensions.Contains("GL_ANGLE_depth_texture"))) { + extensions.Contains("GL_ANGLE_depth_texture") || is_es3)) { enable_depth_texture = true; + feature_flags_.angle_depth_texture = + extensions.Contains("GL_ANGLE_depth_texture"); } if (enable_depth_texture) { @@ -327,11 +354,12 @@ void FeatureInfo::InitializeFeatures() { } if (extensions.Contains("GL_EXT_packed_depth_stencil") || - extensions.Contains("GL_OES_packed_depth_stencil")) { + extensions.Contains("GL_OES_packed_depth_stencil") || is_es3) { AddExtensionString("GL_OES_packed_depth_stencil"); + feature_flags_.packed_depth24_stencil8 = true; if (enable_depth_texture) { - texture_format_validators_[GL_DEPTH_STENCIL].AddValue( - GL_UNSIGNED_INT_24_8); + texture_format_validators_[GL_DEPTH_STENCIL] + .AddValue(GL_UNSIGNED_INT_24_8); validators_.texture_internal_format.AddValue(GL_DEPTH_STENCIL); validators_.texture_format.AddValue(GL_DEPTH_STENCIL); validators_.pixel_type.AddValue(GL_UNSIGNED_INT_24_8); @@ -360,6 +388,8 @@ void FeatureInfo::InitializeFeatures() { bool enable_texture_format_bgra8888 = false; bool enable_read_format_bgra = false; + bool enable_render_buffer_bgra = false; + // Check if we should allow GL_EXT_texture_format_BGRA8888 if (extensions.Contains("GL_EXT_texture_format_BGRA8888") || extensions.Contains("GL_APPLE_texture_format_BGRA8888") || @@ -368,8 +398,7 @@ void FeatureInfo::InitializeFeatures() { } if (extensions.Contains("GL_EXT_bgra")) { - enable_texture_format_bgra8888 = true; - enable_read_format_bgra = true; + enable_render_buffer_bgra = true; } if (extensions.Contains("GL_EXT_read_format_bgra") || @@ -378,6 +407,7 @@ void FeatureInfo::InitializeFeatures() { } if (enable_texture_format_bgra8888) { + feature_flags_.ext_texture_format_bgra8888 = true; AddExtensionString("GL_EXT_texture_format_BGRA8888"); texture_format_validators_[GL_BGRA_EXT].AddValue(GL_UNSIGNED_BYTE); validators_.texture_internal_format.AddValue(GL_BGRA_EXT); @@ -389,6 +419,11 @@ void FeatureInfo::InitializeFeatures() { validators_.read_pixel_format.AddValue(GL_BGRA_EXT); } + if (enable_render_buffer_bgra) { + AddExtensionString("GL_CHROMIUM_renderbuffer_format_BGRA8888"); + validators_.render_buffer_format.AddValue(GL_BGRA8_EXT); + } + if (extensions.Contains("GL_OES_rgb8_rgba8") || gfx::HasDesktopGLFeatures()) { AddExtensionString("GL_OES_rgb8_rgba8"); validators_.render_buffer_format.AddValue(GL_RGB8_OES); @@ -463,13 +498,15 @@ void FeatureInfo::InitializeFeatures() { } // Check for multisample support - if (!disallowed_features_.multisampling) { + if (!disallowed_features_.multisampling && + !workarounds_.disable_framebuffer_multisample) { bool ext_has_multisample = - extensions.Contains("GL_EXT_framebuffer_multisample"); - if (!workarounds_.disable_angle_framebuffer_multisample) { + extensions.Contains("GL_EXT_framebuffer_multisample") || is_es3; + if (feature_flags_.is_angle) { ext_has_multisample |= - extensions.Contains("GL_ANGLE_framebuffer_multisample"); + extensions.Contains("GL_ANGLE_framebuffer_multisample"); } + feature_flags_.use_core_framebuffer_multisample = is_es3; if (ext_has_multisample) { feature_flags_.chromium_framebuffer_multisample = true; validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT); @@ -496,7 +533,8 @@ void FeatureInfo::InitializeFeatures() { } } - if (extensions.Contains("GL_OES_depth24") || gfx::HasDesktopGLFeatures()) { + if (extensions.Contains("GL_OES_depth24") || gfx::HasDesktopGLFeatures() || + is_es3) { AddExtensionString("GL_OES_depth24"); feature_flags_.oes_depth24 = true; validators_.render_buffer_format.AddValue(GL_DEPTH_COMPONENT24); @@ -522,6 +560,7 @@ void FeatureInfo::InitializeFeatures() { if (extensions.Contains("GL_OES_compressed_ETC1_RGB8_texture")) { AddExtensionString("GL_OES_compressed_ETC1_RGB8_texture"); + feature_flags_.oes_compressed_etc1_rgb8_texture = true; validators_.compressed_texture_format.AddValue(GL_ETC1_RGB8_OES); } @@ -565,11 +604,13 @@ void FeatureInfo::InitializeFeatures() { } if (extensions.Contains("GL_ANGLE_texture_usage")) { + feature_flags_.angle_texture_usage = true; AddExtensionString("GL_ANGLE_texture_usage"); validators_.texture_parameter.AddValue(GL_TEXTURE_USAGE_ANGLE); } if (extensions.Contains("GL_EXT_texture_storage")) { + feature_flags_.ext_texture_storage = true; AddExtensionString("GL_EXT_texture_storage"); validators_.texture_parameter.AddValue(GL_TEXTURE_IMMUTABLE_FORMAT_EXT); if (enable_texture_format_bgra8888) @@ -653,16 +694,6 @@ void FeatureInfo::InitializeFeatures() { feature_flags_.ext_frag_depth = true; } - if (!disallowed_features_.swap_buffer_complete_callback) - AddExtensionString("GL_CHROMIUM_swapbuffers_complete_callback"); - - bool is_es3 = false; - const char* str = reinterpret_cast<const char*>(glGetString(GL_VERSION)); - if (str) { - std::string lstr(StringToLowerASCII(std::string(str))); - is_es3 = (lstr.substr(0, 12) == "opengl es 3."); - } - bool ui_gl_fence_works = extensions.Contains("GL_NV_fence") || extensions.Contains("GL_ARB_sync") || extensions.Contains("EGL_KHR_fence_sync"); @@ -691,6 +722,7 @@ void FeatureInfo::InitializeFeatures() { !workarounds_.disable_ext_discard_framebuffer) { // DiscardFramebufferEXT is automatically bound to InvalidateFramebuffer. AddExtensionString("GL_EXT_discard_framebuffer"); + feature_flags_.ext_discard_framebuffer = true; } } diff --git a/chromium/gpu/command_buffer/service/feature_info.h b/chromium/gpu/command_buffer/service/feature_info.h index 7d5041f26b2..ca8c03c7328 100644 --- a/chromium/gpu/command_buffer/service/feature_info.h +++ b/chromium/gpu/command_buffer/service/feature_info.h @@ -27,12 +27,18 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { FeatureFlags(); bool chromium_framebuffer_multisample; + // Use glBlitFramebuffer() and glRenderbufferStorageMultisample() with + // GL_EXT_framebuffer_multisample-style semantics, since they are exposed + // as core GL functions on this implementation. + bool use_core_framebuffer_multisample; bool multisampled_render_to_texture; // Use the IMG GLenum values and functions rather than EXT. bool use_img_for_multisampled_render_to_texture; bool oes_standard_derivatives; bool oes_egl_image_external; bool oes_depth24; + bool oes_compressed_etc1_rgb8_texture; + bool packed_depth24_stencil8; bool npot_ok; bool enable_texture_float_linear; bool enable_texture_half_float_linear; @@ -45,12 +51,19 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { bool use_arb_occlusion_query2_for_occlusion_query_boolean; bool use_arb_occlusion_query_for_occlusion_query_boolean; bool native_vertex_array_object; + bool ext_texture_format_bgra8888; bool enable_shader_name_hashing; bool enable_samplers; bool ext_draw_buffers; bool ext_frag_depth; bool use_async_readpixels; bool map_buffer_range; + bool ext_discard_framebuffer; + bool angle_depth_texture; + bool is_angle; + bool is_swiftshader; + bool angle_texture_usage; + bool ext_texture_storage; }; struct Workarounds { diff --git a/chromium/gpu/command_buffer/service/feature_info_unittest.cc b/chromium/gpu/command_buffer/service/feature_info_unittest.cc index 97cc76b50e0..8164b3580ac 100644 --- a/chromium/gpu/command_buffer/service/feature_info_unittest.cc +++ b/chromium/gpu/command_buffer/service/feature_info_unittest.cc @@ -32,19 +32,23 @@ using ::testing::StrictMock; namespace gpu { namespace gles2 { +namespace { +const char kGLRendererStringANGLE[] = "ANGLE (some renderer)"; +} // anonymous namespace + class FeatureInfoTest : public testing::Test { public: FeatureInfoTest() { } void SetupInitExpectations(const char* extensions) { - SetupInitExpectationsWithGLVersion(extensions, ""); + SetupInitExpectationsWithGLVersion(extensions, "", ""); } void SetupInitExpectationsWithGLVersion( - const char* extensions, const char* version) { + const char* extensions, const char* renderer, const char* version) { TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( - gl_.get(), extensions, version); + gl_.get(), extensions, renderer, version); info_ = new FeatureInfo(); info_->Initialize(); } @@ -56,7 +60,7 @@ class FeatureInfoTest : public testing::Test { void SetupInitExpectationsWithCommandLine( const char* extensions, const CommandLine& command_line) { TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( - gl_.get(), extensions, ""); + gl_.get(), extensions, "", ""); info_ = new FeatureInfo(command_line); info_->Initialize(); } @@ -95,6 +99,7 @@ TEST_F(FeatureInfoTest, Basic) { SetupWithoutInit(); // Test it starts off uninitialized. EXPECT_FALSE(info_->feature_flags().chromium_framebuffer_multisample); + EXPECT_FALSE(info_->feature_flags().use_core_framebuffer_multisample); EXPECT_FALSE(info_->feature_flags().multisampled_render_to_texture); EXPECT_FALSE(info_->feature_flags( ).use_img_for_multisampled_render_to_texture); @@ -103,6 +108,8 @@ TEST_F(FeatureInfoTest, Basic) { EXPECT_FALSE(info_->feature_flags().enable_texture_float_linear); EXPECT_FALSE(info_->feature_flags().enable_texture_half_float_linear); EXPECT_FALSE(info_->feature_flags().oes_egl_image_external); + EXPECT_FALSE(info_->feature_flags().oes_depth24); + EXPECT_FALSE(info_->feature_flags().packed_depth24_stencil8); EXPECT_FALSE(info_->feature_flags().chromium_stream_texture); EXPECT_FALSE(info_->feature_flags().angle_translated_shader_source); EXPECT_FALSE(info_->feature_flags().angle_pack_reverse_row_order); @@ -116,6 +123,9 @@ TEST_F(FeatureInfoTest, Basic) { EXPECT_FALSE(info_->feature_flags().native_vertex_array_object); EXPECT_FALSE(info_->feature_flags().map_buffer_range); EXPECT_FALSE(info_->feature_flags().use_async_readpixels); + EXPECT_FALSE(info_->feature_flags().ext_discard_framebuffer); + EXPECT_FALSE(info_->feature_flags().angle_depth_texture); + EXPECT_FALSE(info_->feature_flags().is_angle); #define GPU_OP(type, name) EXPECT_FALSE(info_->workarounds().name); GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP) @@ -287,6 +297,11 @@ TEST_F(FeatureInfoTest, InitializeNoExtensions) { GL_DEPTH24_STENCIL8_OES)); } +TEST_F(FeatureInfoTest, InitializeWithANGLE) { + SetupInitExpectationsWithGLVersion("", kGLRendererStringANGLE, ""); + EXPECT_TRUE(info_->feature_flags().is_angle); +} + TEST_F(FeatureInfoTest, InitializeNPOTExtensionGLES) { SetupInitExpectations("GL_OES_texture_npot"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_npot")); @@ -341,6 +356,8 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GLES2) { GL_BGRA_EXT)); EXPECT_TRUE(info_->GetTextureFormatValidator(GL_BGRA_EXT).IsValid( GL_UNSIGNED_BYTE)); + EXPECT_FALSE(info_->validators()->render_buffer_format.IsValid( + GL_BGRA8_EXT)); } TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GL) { @@ -349,6 +366,8 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GL) { HasSubstr("GL_EXT_texture_format_BGRA8888")); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_read_format_bgra")); + EXPECT_THAT(info_->extensions(), + HasSubstr("GL_CHROMIUM_renderbuffer_format_BGRA8888")); EXPECT_TRUE(info_->validators()->texture_format.IsValid( GL_BGRA_EXT)); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( @@ -357,6 +376,8 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GL) { GL_BGRA_EXT)); EXPECT_TRUE(info_->GetTextureFormatValidator(GL_BGRA_EXT).IsValid( GL_UNSIGNED_BYTE)); + EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid( + GL_BGRA8_EXT)); } TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888Apple) { @@ -369,6 +390,8 @@ TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888Apple) { GL_BGRA_EXT)); EXPECT_TRUE(info_->GetTextureFormatValidator(GL_BGRA_EXT).IsValid( GL_UNSIGNED_BYTE)); + EXPECT_FALSE(info_->validators()->render_buffer_format.IsValid( + GL_BGRA8_EXT)); } TEST_F(FeatureInfoTest, InitializeEXT_read_format_bgra) { @@ -381,6 +404,8 @@ TEST_F(FeatureInfoTest, InitializeEXT_read_format_bgra) { GL_BGRA_EXT)); EXPECT_TRUE(info_->validators()->read_pixel_format.IsValid( GL_BGRA_EXT)); + EXPECT_FALSE(info_->validators()->render_buffer_format.IsValid( + GL_BGRA8_EXT)); } TEST_F(FeatureInfoTest, InitializeOES_texture_floatGLES2) { @@ -536,6 +561,44 @@ TEST_F(FeatureInfoTest, InitializeEXT_framebuffer_multisample) { GL_RENDERBUFFER_SAMPLES_EXT)); } +TEST_F(FeatureInfoTest, InitializeANGLE_framebuffer_multisample) { + SetupInitExpectationsWithGLVersion( + "GL_ANGLE_framebuffer_multisample", kGLRendererStringANGLE, ""); + EXPECT_TRUE(info_->feature_flags().chromium_framebuffer_multisample); + EXPECT_THAT(info_->extensions(), + HasSubstr("GL_CHROMIUM_framebuffer_multisample")); + EXPECT_TRUE(info_->validators()->frame_buffer_target.IsValid( + GL_READ_FRAMEBUFFER_EXT)); + EXPECT_TRUE(info_->validators()->frame_buffer_target.IsValid( + GL_DRAW_FRAMEBUFFER_EXT)); + EXPECT_TRUE(info_->validators()->g_l_state.IsValid( + GL_READ_FRAMEBUFFER_BINDING_EXT)); + EXPECT_TRUE(info_->validators()->g_l_state.IsValid( + GL_MAX_SAMPLES_EXT)); + EXPECT_TRUE(info_->validators()->render_buffer_parameter.IsValid( + GL_RENDERBUFFER_SAMPLES_EXT)); +} + +// We don't allow ANGLE_framebuffer_multisample on non-ANGLE implementations, +// because we wouldn't be choosing the right driver entry point and because the +// extension was falsely advertised on some Android devices (crbug.com/165736). +TEST_F(FeatureInfoTest, InitializeANGLE_framebuffer_multisampleWithoutANGLE) { + SetupInitExpectations("GL_ANGLE_framebuffer_multisample"); + EXPECT_FALSE(info_->feature_flags().chromium_framebuffer_multisample); + EXPECT_THAT(info_->extensions(), + Not(HasSubstr("GL_CHROMIUM_framebuffer_multisample"))); + EXPECT_FALSE(info_->validators()->frame_buffer_target.IsValid( + GL_READ_FRAMEBUFFER_EXT)); + EXPECT_FALSE(info_->validators()->frame_buffer_target.IsValid( + GL_DRAW_FRAMEBUFFER_EXT)); + EXPECT_FALSE(info_->validators()->g_l_state.IsValid( + GL_READ_FRAMEBUFFER_BINDING_EXT)); + EXPECT_FALSE(info_->validators()->g_l_state.IsValid( + GL_MAX_SAMPLES_EXT)); + EXPECT_FALSE(info_->validators()->render_buffer_parameter.IsValid( + GL_RENDERBUFFER_SAMPLES_EXT)); +} + TEST_F(FeatureInfoTest, InitializeEXT_multisampled_render_to_texture) { SetupInitExpectations("GL_EXT_multisampled_render_to_texture"); EXPECT_TRUE(info_->feature_flags( @@ -626,6 +689,7 @@ TEST_F(FeatureInfoTest, InitializeANGLE_depth_texture) { HasSubstr("GL_CHROMIUM_depth_texture")); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_ANGLE_depth_texture"))); + EXPECT_TRUE(info_->feature_flags().angle_depth_texture); EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid( GL_DEPTH_COMPONENT)); EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_DEPTH_COMPONENT)); @@ -695,6 +759,7 @@ TEST_F(FeatureInfoTest, TEST_F(FeatureInfoTest, InitializeOES_depth24) { SetupInitExpectations("GL_OES_depth24"); + EXPECT_TRUE(info_->feature_flags().oes_depth24); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_depth24")); EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid( GL_DEPTH_COMPONENT24)); @@ -840,25 +905,57 @@ TEST_F(FeatureInfoTest, InitializeEXT_frag_depth) { EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_frag_depth")); } +TEST_F(FeatureInfoTest, InitializeEXT_discard_framebuffer) { + SetupInitExpectations("GL_EXT_discard_framebuffer"); + EXPECT_TRUE(info_->feature_flags().ext_discard_framebuffer); + EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_discard_framebuffer")); +} + TEST_F(FeatureInfoTest, InitializeSamplersWithARBSamplerObjects) { - SetupInitExpectationsWithGLVersion("GL_ARB_sampler_objects", "OpenGL 3.0"); + SetupInitExpectationsWithGLVersion( + "GL_ARB_sampler_objects", "", "OpenGL 3.0"); EXPECT_TRUE(info_->feature_flags().enable_samplers); } TEST_F(FeatureInfoTest, InitializeWithES3) { - SetupInitExpectationsWithGLVersion("", "OpenGL ES 3.0"); + SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); EXPECT_TRUE(info_->feature_flags().enable_samplers); EXPECT_TRUE(info_->feature_flags().map_buffer_range); + EXPECT_TRUE(info_->feature_flags().ext_discard_framebuffer); + EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_discard_framebuffer")); + EXPECT_TRUE(info_->feature_flags().chromium_framebuffer_multisample); + EXPECT_TRUE(info_->feature_flags().use_core_framebuffer_multisample); + EXPECT_THAT(info_->extensions(), + HasSubstr("GL_CHROMIUM_framebuffer_multisample")); EXPECT_FALSE(info_->feature_flags().use_async_readpixels); + EXPECT_TRUE(info_->feature_flags().oes_depth24); + EXPECT_THAT(info_->extensions(), HasSubstr("GL_GOOGLE_depth_texture")); + EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_depth_texture")); + EXPECT_TRUE(info_->validators()->pixel_type.IsValid(GL_UNSIGNED_INT_24_8)); + EXPECT_TRUE(info_->GetTextureFormatValidator(GL_DEPTH_COMPONENT) + .IsValid(GL_UNSIGNED_SHORT)); + EXPECT_TRUE(info_->GetTextureFormatValidator(GL_DEPTH_COMPONENT) + .IsValid(GL_UNSIGNED_INT)); + EXPECT_TRUE(info_->GetTextureFormatValidator(GL_DEPTH_STENCIL) + .IsValid(GL_UNSIGNED_INT_24_8)); + EXPECT_TRUE(info_->feature_flags().packed_depth24_stencil8); + EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_depth24")); + EXPECT_TRUE( + info_->validators()->render_buffer_format.IsValid(GL_DEPTH_COMPONENT24)); + EXPECT_TRUE( + info_->validators()->render_buffer_format.IsValid(GL_DEPTH24_STENCIL8)); + EXPECT_TRUE( + info_->validators()->texture_internal_format.IsValid(GL_DEPTH_STENCIL)); + EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_DEPTH_STENCIL)); } TEST_F(FeatureInfoTest, InitializeWithoutSamplers) { - SetupInitExpectationsWithGLVersion("", "OpenGL GL 3.0"); + SetupInitExpectationsWithGLVersion("", "", "OpenGL GL 3.0"); EXPECT_FALSE(info_->feature_flags().enable_samplers); } TEST_F(FeatureInfoTest, InitializeWithES3AndFences) { - SetupInitExpectationsWithGLVersion("EGL_KHR_fence_sync", "OpenGL ES 3.0"); + SetupInitExpectationsWithGLVersion("EGL_KHR_fence_sync", "", "OpenGL ES 3.0"); EXPECT_TRUE(info_->feature_flags().use_async_readpixels); } diff --git a/chromium/gpu/command_buffer/service/framebuffer_manager.cc b/chromium/gpu/command_buffer/service/framebuffer_manager.cc index b4c6b090f0f..48e503cb45b 100644 --- a/chromium/gpu/command_buffer/service/framebuffer_manager.cc +++ b/chromium/gpu/command_buffer/service/framebuffer_manager.cc @@ -13,6 +13,15 @@ namespace gpu { namespace gles2 { +DecoderFramebufferState::DecoderFramebufferState() + : clear_state_dirty(false), + bound_read_framebuffer(NULL), + bound_draw_framebuffer(NULL) { +} + +DecoderFramebufferState::~DecoderFramebufferState() { +} + Framebuffer::FramebufferComboCompleteMap* Framebuffer::framebuffer_combo_complete_map_; @@ -51,6 +60,10 @@ class RenderbufferAttachment return renderbuffer_->internal_format(); } + virtual GLenum texture_type() const OVERRIDE { + return 0; + } + virtual GLsizei samples() const OVERRIDE { return renderbuffer_->samples(); } @@ -84,7 +97,7 @@ class RenderbufferAttachment return true; } - virtual void DetachFromFramebuffer() const OVERRIDE { + virtual void DetachFromFramebuffer(Framebuffer* framebuffer) const OVERRIDE { // Nothing to do for renderbuffers. } @@ -150,6 +163,14 @@ class TextureAttachment return temp_internal_format; } + virtual GLenum texture_type() const OVERRIDE { + GLenum temp_type = 0; + GLenum temp_internal_format = 0; + texture_ref_->texture()->GetLevelType( + target_, level_, &temp_type, &temp_internal_format); + return temp_type; + } + virtual GLsizei samples() const OVERRIDE { return samples_; } @@ -188,8 +209,10 @@ class TextureAttachment return texture_ref_->texture()->CanRenderTo(); } - virtual void DetachFromFramebuffer() const OVERRIDE { + virtual void DetachFromFramebuffer(Framebuffer* framebuffer) + const OVERRIDE { texture_ref_->texture()->DetachFromFramebuffer(); + framebuffer->OnTextureRefDetached(texture_ref_.get()); } virtual bool ValidForAttachmentType( @@ -232,6 +255,10 @@ class TextureAttachment DISALLOW_COPY_AND_ASSIGN(TextureAttachment); }; +FramebufferManager::TextureDetachObserver::TextureDetachObserver() {} + +FramebufferManager::TextureDetachObserver::~TextureDetachObserver() {} + FramebufferManager::FramebufferManager( uint32 max_draw_buffers, uint32 max_color_attachments) : framebuffer_state_change_count_(1), @@ -254,7 +281,7 @@ void Framebuffer::MarkAsDeleted() { deleted_ = true; while (!attachments_.empty()) { Attachment* attachment = attachments_.begin()->second.get(); - attachment->DetachFromFramebuffer(); + attachment->DetachFromFramebuffer(this); attachments_.erase(attachments_.begin()); } } @@ -370,6 +397,15 @@ GLenum Framebuffer::GetColorAttachmentFormat() const { return attachment->internal_format(); } +GLenum Framebuffer::GetColorAttachmentTextureType() const { + AttachmentMap::const_iterator it = attachments_.find(GL_COLOR_ATTACHMENT0); + if (it == attachments_.end()) { + return 0; + } + const Attachment* attachment = it->second.get(); + return attachment->texture_type(); +} + GLenum Framebuffer::IsPossiblyComplete() const { if (attachments_.empty()) { return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; @@ -539,7 +575,7 @@ void Framebuffer::AttachRenderbuffer( GLenum attachment, Renderbuffer* renderbuffer) { const Attachment* a = GetAttachment(attachment); if (a) - a->DetachFromFramebuffer(); + a->DetachFromFramebuffer(this); if (renderbuffer) { attachments_[attachment] = scoped_refptr<Attachment>( new RenderbufferAttachment(renderbuffer)); @@ -554,7 +590,7 @@ void Framebuffer::AttachTexture( GLint level, GLsizei samples) { const Attachment* a = GetAttachment(attachment); if (a) - a->DetachFromFramebuffer(); + a->DetachFromFramebuffer(this); if (texture_ref) { attachments_[attachment] = scoped_refptr<Attachment>( new TextureAttachment(texture_ref, target, level, samples)); @@ -575,6 +611,10 @@ const Framebuffer::Attachment* return NULL; } +void Framebuffer::OnTextureRefDetached(TextureRef* texture) { + manager_->OnTextureRefDetached(texture); +} + bool FramebufferManager::GetClientId( GLuint service_id, GLuint* client_id) const { // This doesn't need to be fast. It's only used during slow queries. @@ -612,6 +652,16 @@ bool FramebufferManager::IsComplete( framebuffer_state_change_count_; } +void FramebufferManager::OnTextureRefDetached(TextureRef* texture) { + for (TextureDetachObserverVector::iterator it = + texture_detach_observers_.begin(); + it != texture_detach_observers_.end(); + ++it) { + TextureDetachObserver* observer = *it; + observer->OnTextureRefDetachedFromFramebuffer(texture); + } +} + } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/framebuffer_manager.h b/chromium/gpu/command_buffer/service/framebuffer_manager.h index aa1111813e1..c469bf87435 100644 --- a/chromium/gpu/command_buffer/service/framebuffer_manager.h +++ b/chromium/gpu/command_buffer/service/framebuffer_manager.h @@ -5,6 +5,8 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_ #define GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_ +#include <vector> + #include "base/basictypes.h" #include "base/containers/hash_tables.h" #include "base/memory/ref_counted.h" @@ -30,6 +32,7 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { virtual GLsizei width() const = 0; virtual GLsizei height() const = 0; virtual GLenum internal_format() const = 0; + virtual GLenum texture_type() const = 0; virtual GLsizei samples() const = 0; virtual GLuint object_name() const = 0; virtual bool cleared() const = 0; @@ -41,7 +44,7 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { virtual bool IsRenderbuffer( Renderbuffer* renderbuffer) const = 0; virtual bool CanRenderTo() const = 0; - virtual void DetachFromFramebuffer() const = 0; + virtual void DetachFromFramebuffer(Framebuffer* framebuffer) const = 0; virtual bool ValidForAttachmentType( GLenum attachment_type, uint32 max_color_attachments) = 0; virtual void AddToSignature( @@ -101,6 +104,9 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { bool HasDepthAttachment() const; bool HasStencilAttachment() const; GLenum GetColorAttachmentFormat() const; + // If the color attachment is a texture, returns its type; otherwise, + // returns 0. + GLenum GetColorAttachmentTextureType() const; // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed. // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't @@ -130,6 +136,8 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { return allow_framebuffer_combo_complete_map_; } + void OnTextureRefDetached(TextureRef* texture); + private: friend class FramebufferManager; friend class base::RefCounted<Framebuffer>; @@ -181,18 +189,33 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { }; struct DecoderFramebufferState { - DecoderFramebufferState(): - clear_state_dirty(true) {} + DecoderFramebufferState(); + ~DecoderFramebufferState(); // State saved for clearing so we can clear render buffers and then // restore to these values. bool clear_state_dirty; + + // The currently bound framebuffers + scoped_refptr<Framebuffer> bound_read_framebuffer; + scoped_refptr<Framebuffer> bound_draw_framebuffer; }; // This class keeps track of the frambebuffers and their attached renderbuffers // so we can correctly clear them. class GPU_EXPORT FramebufferManager { public: + class GPU_EXPORT TextureDetachObserver { + public: + TextureDetachObserver(); + virtual ~TextureDetachObserver(); + + virtual void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureDetachObserver); + }; + FramebufferManager(uint32 max_draw_buffers, uint32 max_color_attachments); ~FramebufferManager(); @@ -226,12 +249,26 @@ class GPU_EXPORT FramebufferManager { (framebuffer_state_change_count_ + 1) | 0x80000000U; } + void AddObserver(TextureDetachObserver* observer) { + texture_detach_observers_.push_back(observer); + } + + void RemoveObserver(TextureDetachObserver* observer) { + texture_detach_observers_.erase( + std::remove(texture_detach_observers_.begin(), + texture_detach_observers_.end(), + observer), + texture_detach_observers_.end()); + } + private: friend class Framebuffer; void StartTracking(Framebuffer* framebuffer); void StopTracking(Framebuffer* framebuffer); + void OnTextureRefDetached(TextureRef* texture); + // Info for each framebuffer in the system. typedef base::hash_map<GLuint, scoped_refptr<Framebuffer> > FramebufferMap; @@ -250,6 +287,9 @@ class GPU_EXPORT FramebufferManager { uint32 max_draw_buffers_; uint32 max_color_attachments_; + typedef std::vector<TextureDetachObserver*> TextureDetachObserverVector; + TextureDetachObserverVector texture_detach_observers_; + DISALLOW_COPY_AND_ASSIGN(FramebufferManager); }; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc index 120359ceae8..c2fcee2933a 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -14,15 +14,12 @@ #include <vector> #include "base/at_exit.h" -#include "base/atomicops.h" #include "base/bind.h" #include "base/command_line.h" #include "base/debug/trace_event.h" -#if defined(OS_MACOSX) -#include "base/mac/scoped_cftyperef.h" -#endif #include "base/memory/scoped_ptr.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" #include "build/build_config.h" #define GLES2_GPU_SERVICE 1 #include "gpu/command_buffer/common/debug_marker_manager.h" @@ -292,11 +289,11 @@ static void EnableDisable(GLenum pname, bool enable) { class ScopedGLErrorSuppressor { public: explicit ScopedGLErrorSuppressor( - const char* function_name, GLES2DecoderImpl* decoder); + const char* function_name, ErrorState* error_state); ~ScopedGLErrorSuppressor(); private: const char* function_name_; - GLES2DecoderImpl* decoder_; + ErrorState* error_state_; DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor); }; @@ -305,11 +302,11 @@ class ScopedGLErrorSuppressor { // unit zero in case the client has changed that to something invalid. class ScopedTexture2DBinder { public: - ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id); + ScopedTexture2DBinder(ContextState* state, GLuint id); ~ScopedTexture2DBinder(); private: - GLES2DecoderImpl* decoder_; + ContextState* state_; DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder); }; @@ -317,11 +314,11 @@ class ScopedTexture2DBinder { // object goes out of scope. class ScopedRenderBufferBinder { public: - ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id); + ScopedRenderBufferBinder(ContextState* state, GLuint id); ~ScopedRenderBufferBinder(); private: - GLES2DecoderImpl* decoder_; + ContextState* state_; DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder); }; @@ -357,7 +354,7 @@ class ScopedResolvedFrameBufferBinder { // Encapsulates an OpenGL texture. class BackTexture { public: - explicit BackTexture(GLES2DecoderImpl* decoder); + explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state); ~BackTexture(); // Create a new render texture. @@ -390,8 +387,8 @@ class BackTexture { } private: - GLES2DecoderImpl* decoder_; MemoryTypeTracker memory_tracker_; + ContextState* state_; size_t bytes_allocated_; GLuint id_; gfx::Size size_; @@ -401,14 +398,20 @@ class BackTexture { // Encapsulates an OpenGL render buffer of any format. class BackRenderbuffer { public: - explicit BackRenderbuffer(GLES2DecoderImpl* decoder); + explicit BackRenderbuffer( + RenderbufferManager* renderbuffer_manager, + MemoryTracker* memory_tracker, + ContextState* state); ~BackRenderbuffer(); // Create a new render buffer. void Create(); // Set the initial size and format of a render buffer or resize it. - bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples); + bool AllocateStorage(const FeatureInfo* feature_info, + const gfx::Size& size, + GLenum format, + GLsizei samples); // Destroy the render buffer. This must be explicitly called before destroying // this object. @@ -427,8 +430,9 @@ class BackRenderbuffer { } private: - GLES2DecoderImpl* decoder_; + RenderbufferManager* renderbuffer_manager_; MemoryTypeTracker memory_tracker_; + ContextState* state_; size_t bytes_allocated_; GLuint id_; DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer); @@ -500,24 +504,10 @@ GLES2Decoder::GLES2Decoder() GLES2Decoder::~GLES2Decoder() { } -bool GLES2Decoder::testing_force_is_angle_; - -void GLES2Decoder::set_testing_force_is_angle(bool force) { - testing_force_is_angle_ = force; -} - -bool GLES2Decoder::IsAngle() { -#if defined(OS_WIN) - return testing_force_is_angle_ || - gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; -#else - return testing_force_is_angle_; -#endif -} - // This class implements GLES2Decoder so we don't have to expose all the GLES2 // cmd stuff to outside this class. -class GLES2DecoderImpl : public GLES2Decoder { +class GLES2DecoderImpl : public GLES2Decoder, + public FramebufferManager::TextureDetachObserver { public: // Used by PrepForSetUniformByLocation to validate types. struct BaseUniformInfo { @@ -554,6 +544,7 @@ class GLES2DecoderImpl : public GLES2Decoder { virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; } virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); } virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); } + virtual Capabilities GetCapabilities() OVERRIDE; virtual void RestoreState() const OVERRIDE; virtual void RestoreActiveTexture() const OVERRIDE { @@ -623,8 +614,6 @@ class GLES2DecoderImpl : public GLES2Decoder { // Restores the current state to the user's settings. void RestoreCurrentFramebufferBindings(); - void RestoreCurrentRenderbufferBindings(); - void RestoreCurrentTexture2DBindings(); // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer. void ApplyDirtyState(); @@ -639,12 +628,33 @@ class GLES2DecoderImpl : public GLES2Decoder { virtual error::ContextLostReason GetContextLostReason() OVERRIDE; + // Overridden from FramebufferManager::TextureDetachObserver: + virtual void OnTextureRefDetachedFromFramebuffer( + TextureRef* texture) OVERRIDE; + + // Helpers to facilitate calling into compatible extensions. + static void RenderbufferStorageMultisampleHelper( + const FeatureInfo* feature_info, + GLenum target, + GLsizei samples, + GLenum internal_format, + GLsizei width, + GLsizei height); + + void BlitFramebufferHelper(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); + private: friend class ScopedFrameBufferBinder; - friend class ScopedGLErrorSuppressor; friend class ScopedResolvedFrameBufferBinder; - friend class BackTexture; - friend class BackRenderbuffer; friend class BackFramebuffer; // Initialize or re-initialize the shader translator. @@ -753,6 +763,7 @@ class GLES2DecoderImpl : public GLES2Decoder { // Get the format of the currently bound frame buffer (either FBO or regular // back buffer) + GLenum GetBoundReadFrameBufferTextureType(); GLenum GetBoundReadFrameBufferInternalFormat(); GLenum GetBoundDrawFrameBufferInternalFormat(); @@ -901,9 +912,9 @@ class GLES2DecoderImpl : public GLES2Decoder { void LogClientServiceMapping( const char* function_name, GLuint client_id, GLuint service_id) { if (service_logging_) { - DLOG(INFO) << "[" << logger_.GetLogPrefix() << "] " << function_name - << ": client_id = " << client_id - << ", service_id = " << service_id; + VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name + << ": client_id = " << client_id + << ", service_id = " << service_id; } } template<typename T> @@ -1143,8 +1154,8 @@ class GLES2DecoderImpl : public GLES2Decoder { void DoBindVertexArrayOES(GLuint array); void EmulateVertexArrayState(); - // Wrapper for glBlitFramebufferEXT. - void DoBlitFramebufferEXT( + // Wrapper for glBlitFramebufferCHROMIUM. + void DoBlitFramebufferCHROMIUM( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); @@ -1286,11 +1297,23 @@ class GLES2DecoderImpl : public GLES2Decoder { void DoRenderbufferStorage( GLenum target, GLenum internalformat, GLsizei width, GLsizei height); - // Wrapper for glRenderbufferStorageMultisampleEXT. - void DoRenderbufferStorageMultisample( + // Handler for glRenderbufferStorageMultisampleCHROMIUM. + void DoRenderbufferStorageMultisampleCHROMIUM( + GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height); + + // Handler for glRenderbufferStorageMultisampleEXT + // (multisampled_render_to_texture). + void DoRenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + // Common validation for multisample extensions. + bool ValidateRenderbufferStorageMultisample(GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); + // Verifies that the currently bound multisample renderbuffer is valid // Very slow! Only done on platforms with driver bugs that return invalid // buffers under memory pressure @@ -1376,9 +1399,14 @@ class GLES2DecoderImpl : public GLES2Decoder { // buffer and bind the texture implicitly. void UpdateStreamTextureIfNeeded(Texture* texture, GLuint texture_unit_index); - // Returns false if unrenderable textures were replaced. + // If an image is bound to texture, this will call Will/DidUseTexImage + // if needed. + void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget); + void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget); + + // Returns false if textures were replaced. bool PrepareTexturesForRender(); - void RestoreStateForNonRenderableTextures(); + void RestoreStateForTextures(); // Returns true if GL_FIXED attribs were simulated. bool SimulateFixedAttribs( @@ -1421,10 +1449,10 @@ class GLES2DecoderImpl : public GLES2Decoder { switch (target) { case GL_FRAMEBUFFER: case GL_DRAW_FRAMEBUFFER_EXT: - framebuffer = state_.bound_draw_framebuffer.get(); + framebuffer = framebuffer_state_.bound_draw_framebuffer.get(); break; case GL_READ_FRAMEBUFFER_EXT: - framebuffer = state_.bound_read_framebuffer.get(); + framebuffer = framebuffer_state_.bound_read_framebuffer.get(); break; default: NOTREACHED(); @@ -1501,16 +1529,36 @@ class GLES2DecoderImpl : public GLES2Decoder { bool ShouldDeferDraws() { return !offscreen_target_frame_buffer_.get() && - state_.bound_draw_framebuffer.get() == NULL && + framebuffer_state_.bound_draw_framebuffer.get() == NULL && surface_->DeferDraws(); } bool ShouldDeferReads() { return !offscreen_target_frame_buffer_.get() && - state_.bound_read_framebuffer.get() == NULL && + framebuffer_state_.bound_read_framebuffer.get() == NULL && surface_->DeferDraws(); } + error::Error WillAccessBoundFramebufferForDraw() { + if (ShouldDeferDraws()) + return error::kDeferCommandUntilLater; + if (!offscreen_target_frame_buffer_.get() && + !framebuffer_state_.bound_draw_framebuffer.get() && + !surface_->SetBackbufferAllocation(true)) + return error::kLostContext; + return error::kNoError; + } + + error::Error WillAccessBoundFramebufferForRead() { + if (ShouldDeferReads()) + return error::kDeferCommandUntilLater; + if (!offscreen_target_frame_buffer_.get() && + !framebuffer_state_.bound_read_framebuffer.get() && + !surface_->SetBackbufferAllocation(true)) + return error::kLostContext; + return error::kNoError; + } + void ProcessPendingReadPixels(); void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer); @@ -1684,22 +1732,34 @@ class GLES2DecoderImpl : public GLES2Decoder { }; ScopedGLErrorSuppressor::ScopedGLErrorSuppressor( - const char* function_name, GLES2DecoderImpl* decoder) + const char* function_name, ErrorState* error_state) : function_name_(function_name), - decoder_(decoder) { - ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(), - function_name_); + error_state_(error_state) { + ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_); } ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() { - ERRORSTATE_CLEAR_REAL_GL_ERRORS(decoder_->GetErrorState(), function_name_); + ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_); +} + +static void RestoreCurrentTexture2DBindings(ContextState* state) { + TextureUnit& info = state->texture_units[0]; + GLuint last_id; + if (info.bound_texture_2d.get()) { + last_id = info.bound_texture_2d->service_id(); + } else { + last_id = 0; + } + + glBindTexture(GL_TEXTURE_2D, last_id); + glActiveTexture(GL_TEXTURE0 + state->active_texture_unit); } -ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder, +ScopedTexture2DBinder::ScopedTexture2DBinder(ContextState* state, GLuint id) - : decoder_(decoder) { + : state_(state) { ScopedGLErrorSuppressor suppressor( - "ScopedTexture2DBinder::ctor", decoder_); + "ScopedTexture2DBinder::ctor", state_->GetErrorState()); // TODO(apatrick): Check if there are any other states that need to be reset // before binding a new texture. @@ -1709,51 +1769,52 @@ ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder, ScopedTexture2DBinder::~ScopedTexture2DBinder() { ScopedGLErrorSuppressor suppressor( - "ScopedTexture2DBinder::dtor", decoder_); - decoder_->RestoreCurrentTexture2DBindings(); + "ScopedTexture2DBinder::dtor", state_->GetErrorState()); + RestoreCurrentTexture2DBindings(state_); } -ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, +ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state, GLuint id) - : decoder_(decoder) { + : state_(state) { ScopedGLErrorSuppressor suppressor( - "ScopedRenderBufferBinder::ctor", decoder_); + "ScopedRenderBufferBinder::ctor", state_->GetErrorState()); glBindRenderbufferEXT(GL_RENDERBUFFER, id); } ScopedRenderBufferBinder::~ScopedRenderBufferBinder() { ScopedGLErrorSuppressor suppressor( - "ScopedRenderBufferBinder::dtor", decoder_); - decoder_->RestoreCurrentRenderbufferBindings(); + "ScopedRenderBufferBinder::dtor", state_->GetErrorState()); + state_->RestoreRenderbufferBindings(); } ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id) : decoder_(decoder) { ScopedGLErrorSuppressor suppressor( - "ScopedFrameBufferBinder::ctor", decoder_); + "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState()); glBindFramebufferEXT(GL_FRAMEBUFFER, id); decoder->OnFboChanged(); } ScopedFrameBufferBinder::~ScopedFrameBufferBinder() { ScopedGLErrorSuppressor suppressor( - "ScopedFrameBufferBinder::dtor", decoder_); + "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState()); decoder_->RestoreCurrentFramebufferBindings(); } ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal) : decoder_(decoder) { - resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() && - decoder_->IsOffscreenBufferMultisampled() && - (!decoder_->state_.bound_read_framebuffer.get() || - enforce_internal_framebuffer)); + resolve_and_bind_ = ( + decoder_->offscreen_target_frame_buffer_.get() && + decoder_->IsOffscreenBufferMultisampled() && + (!decoder_->framebuffer_state_.bound_read_framebuffer.get() || + enforce_internal_framebuffer)); if (!resolve_and_bind_) return; ScopedGLErrorSuppressor suppressor( - "ScopedResolvedFrameBufferBinder::ctor", decoder_); + "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState()); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, decoder_->offscreen_target_frame_buffer_->id()); GLuint targetid; @@ -1763,7 +1824,7 @@ ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( new BackFramebuffer(decoder_)); decoder_->offscreen_resolved_frame_buffer_->Create(); decoder_->offscreen_resolved_color_texture_.reset( - new BackTexture(decoder_)); + new BackTexture(decoder->memory_tracker(), &decoder->state_)); decoder_->offscreen_resolved_color_texture_->Create(); DCHECK(decoder_->offscreen_saved_color_format_); @@ -1787,13 +1848,16 @@ ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( const int width = decoder_->offscreen_size_.width(); const int height = decoder_->offscreen_size_.height(); glDisable(GL_SCISSOR_TEST); - if (GLES2Decoder::IsAngle()) { - glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } else { - glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } + decoder->BlitFramebufferHelper(0, + 0, + width, + height, + 0, + 0, + width, + height, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); glBindFramebufferEXT(GL_FRAMEBUFFER, targetid); } @@ -1802,16 +1866,18 @@ ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() { return; ScopedGLErrorSuppressor suppressor( - "ScopedResolvedFrameBufferBinder::dtor", decoder_); + "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState()); decoder_->RestoreCurrentFramebufferBindings(); if (decoder_->state_.enable_flags.scissor_test) { glEnable(GL_SCISSOR_TEST); } } -BackTexture::BackTexture(GLES2DecoderImpl* decoder) - : decoder_(decoder), - memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged), +BackTexture::BackTexture( + MemoryTracker* memory_tracker, + ContextState* state) + : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged), + state_(state), bytes_allocated_(0), id_(0) { } @@ -1824,10 +1890,11 @@ BackTexture::~BackTexture() { } void BackTexture::Create() { - ScopedGLErrorSuppressor suppressor("BackTexture::Create", decoder_); + ScopedGLErrorSuppressor suppressor("BackTexture::Create", + state_->GetErrorState()); Destroy(); glGenTextures(1, &id_); - ScopedTexture2DBinder binder(decoder_, id_); + ScopedTexture2DBinder binder(state_, id_); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -1849,8 +1916,9 @@ void BackTexture::Create() { bool BackTexture::AllocateStorage( const gfx::Size& size, GLenum format, bool zero) { DCHECK_NE(id_, 0u); - ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", decoder_); - ScopedTexture2DBinder binder(decoder_, id_); + ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", + state_->GetErrorState()); + ScopedTexture2DBinder binder(state_, id_); uint32 image_size = 0; GLES2Util::ComputeImageDataSizes( size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size, @@ -1889,8 +1957,9 @@ bool BackTexture::AllocateStorage( void BackTexture::Copy(const gfx::Size& size, GLenum format) { DCHECK_NE(id_, 0u); - ScopedGLErrorSuppressor suppressor("BackTexture::Copy", decoder_); - ScopedTexture2DBinder binder(decoder_, id_); + ScopedGLErrorSuppressor suppressor("BackTexture::Copy", + state_->GetErrorState()); + ScopedTexture2DBinder binder(state_, id_); glCopyTexImage2D(GL_TEXTURE_2D, 0, // level format, @@ -1902,7 +1971,8 @@ void BackTexture::Copy(const gfx::Size& size, GLenum format) { void BackTexture::Destroy() { if (id_ != 0) { - ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", decoder_); + ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", + state_->GetErrorState()); glDeleteTextures(1, &id_); id_ = 0; } @@ -1914,9 +1984,13 @@ void BackTexture::Invalidate() { id_ = 0; } -BackRenderbuffer::BackRenderbuffer(GLES2DecoderImpl* decoder) - : decoder_(decoder), - memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged), +BackRenderbuffer::BackRenderbuffer( + RenderbufferManager* renderbuffer_manager, + MemoryTracker* memory_tracker, + ContextState* state) + : renderbuffer_manager_(renderbuffer_manager), + memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged), + state_(state), bytes_allocated_(0), id_(0) { } @@ -1929,19 +2003,22 @@ BackRenderbuffer::~BackRenderbuffer() { } void BackRenderbuffer::Create() { - ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", decoder_); + ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", + state_->GetErrorState()); Destroy(); glGenRenderbuffersEXT(1, &id_); } -bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format, +bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info, + const gfx::Size& size, + GLenum format, GLsizei samples) { ScopedGLErrorSuppressor suppressor( - "BackRenderbuffer::AllocateStorage", decoder_); - ScopedRenderBufferBinder binder(decoder_, id_); + "BackRenderbuffer::AllocateStorage", state_->GetErrorState()); + ScopedRenderBufferBinder binder(state_, id_); uint32 estimated_size = 0; - if (!decoder_->renderbuffer_manager()->ComputeEstimatedRenderbufferSize( + if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize( size.width(), size.height(), samples, format, &estimated_size)) { return false; } @@ -1956,24 +2033,19 @@ bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format, size.width(), size.height()); } else { - if (GLES2Decoder::IsAngle()) { - glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, - samples, - format, - size.width(), - size.height()); - } else { - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, - samples, - format, - size.width(), - size.height()); - } + GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info, + GL_RENDERBUFFER, + samples, + format, + size.width(), + size.height()); } bool success = glGetError() == GL_NO_ERROR; if (success) { + // Mark the previously allocated bytes as free. memory_tracker_.TrackMemFree(bytes_allocated_); bytes_allocated_ = estimated_size; + // Track the newly allocated bytes. memory_tracker_.TrackMemAlloc(bytes_allocated_); } return success; @@ -1981,7 +2053,8 @@ bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format, void BackRenderbuffer::Destroy() { if (id_ != 0) { - ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", decoder_); + ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", + state_->GetErrorState()); glDeleteRenderbuffersEXT(1, &id_); id_ = 0; } @@ -2006,7 +2079,8 @@ BackFramebuffer::~BackFramebuffer() { } void BackFramebuffer::Create() { - ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", decoder_); + ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", + decoder_->GetErrorState()); Destroy(); glGenFramebuffersEXT(1, &id_); } @@ -2014,7 +2088,7 @@ void BackFramebuffer::Create() { void BackFramebuffer::AttachRenderTexture(BackTexture* texture) { DCHECK_NE(id_, 0u); ScopedGLErrorSuppressor suppressor( - "BackFramebuffer::AttachRenderTexture", decoder_); + "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState()); ScopedFrameBufferBinder binder(decoder_, id_); GLuint attach_id = texture ? texture->id() : 0; glFramebufferTexture2DEXT(GL_FRAMEBUFFER, @@ -2028,7 +2102,7 @@ void BackFramebuffer::AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer) { DCHECK_NE(id_, 0u); ScopedGLErrorSuppressor suppressor( - "BackFramebuffer::AttachRenderBuffer", decoder_); + "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState()); ScopedFrameBufferBinder binder(decoder_, id_); GLuint attach_id = render_buffer ? render_buffer->id() : 0; glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, @@ -2039,7 +2113,8 @@ void BackFramebuffer::AttachRenderBuffer(GLenum target, void BackFramebuffer::Destroy() { if (id_ != 0) { - ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", decoder_); + ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", + decoder_->GetErrorState()); glDeleteFramebuffersEXT(1, &id_); id_ = 0; } @@ -2051,7 +2126,8 @@ void BackFramebuffer::Invalidate() { GLenum BackFramebuffer::CheckStatus() { DCHECK_NE(id_, 0u); - ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", decoder_); + ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", + decoder_->GetErrorState()); ScopedFrameBufferBinder binder(decoder_, id_); return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); } @@ -2100,6 +2176,9 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) switches::kEnableGPUServiceLoggingGPU)), viewport_max_width_(0), viewport_max_height_(0), + texture_state_(group_->feature_info() + ->workarounds() + .texsubimage2d_faster_than_teximage2d), validation_texture_(0), validation_fbo_multisample_(0), validation_fbo_(0) { @@ -2120,11 +2199,6 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) switches::kDisableGLSLTranslator)) { use_shader_translator_ = false; } - - // TODO(gman): Consider setting this based on GPU and/or driver. - if (IsAngle()) { - texture_state_.teximage2d_faster_than_texsubimage2d = false; - } } GLES2DecoderImpl::~GLES2DecoderImpl() { @@ -2164,6 +2238,19 @@ bool GLES2DecoderImpl::Initialize( context_ = context; surface_ = surface; + ContextCreationAttribHelper attrib_parser; + if (!attrib_parser.Parse(attribs)) + return false; + + // If the failIfMajorPerformanceCaveat context creation attribute was true + // and we are using a software renderer, fail. + if (attrib_parser.fail_if_major_perf_caveat_ && + feature_info_->feature_flags().is_swiftshader) { + group_ = NULL; // Must not destroy ContextGroup if it is not initialized. + Destroy(true); + return false; + } + if (!group_->Initialize(this, disallowed_features)) { LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group " << "failed to initialize."; @@ -2226,10 +2313,6 @@ bool GLES2DecoderImpl::Initialize( glActiveTexture(GL_TEXTURE0); CHECK_GL_ERROR(); - ContextCreationAttribHelper attrib_parser; - if (!attrib_parser.Parse(attribs)) - return false; - if (offscreen) { if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 && features().chromium_framebuffer_multisample) { @@ -2263,7 +2346,7 @@ bool GLES2DecoderImpl::Initialize( // ANGLE only supports packed depth/stencil formats, so use it if it is // available. const bool depth24_stencil8_supported = - context_->HasExtension("GL_OES_packed_depth_stencil"); + feature_info_->feature_flags().packed_depth24_stencil8; VLOG(1) << "GL_OES_packed_depth_stencil " << (depth24_stencil8_supported ? "" : "not ") << "supported."; if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) && @@ -2286,7 +2369,7 @@ bool GLES2DecoderImpl::Initialize( // it's available, as some desktop GL drivers don't support any non-packed // formats for depth attachments. const bool depth24_stencil8_supported = - context_->HasExtension("GL_EXT_packed_depth_stencil"); + feature_info_->feature_flags().packed_depth24_stencil8; VLOG(1) << "GL_EXT_packed_depth_stencil " << (depth24_stencil8_supported ? "" : "not ") << "supported."; @@ -2314,15 +2397,19 @@ bool GLES2DecoderImpl::Initialize( // attached to the offscreen frame buffer. The render buffer has more // limited formats available to it, but the texture can't do multisampling. if (IsOffscreenBufferMultisampled()) { - offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(this)); + offscreen_target_color_render_buffer_.reset(new BackRenderbuffer( + renderbuffer_manager(), memory_tracker(), &state_)); offscreen_target_color_render_buffer_->Create(); } else { - offscreen_target_color_texture_.reset(new BackTexture(this)); + offscreen_target_color_texture_.reset(new BackTexture( + memory_tracker(), &state_)); offscreen_target_color_texture_->Create(); } - offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(this)); + offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer( + renderbuffer_manager(), memory_tracker(), &state_)); offscreen_target_depth_render_buffer_->Create(); - offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(this)); + offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer( + renderbuffer_manager(), memory_tracker(), &state_)); offscreen_target_stencil_render_buffer_->Create(); // Create the saved offscreen texture. The target frame buffer is copied @@ -2330,7 +2417,8 @@ bool GLES2DecoderImpl::Initialize( offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this)); offscreen_saved_frame_buffer_->Create(); // - offscreen_saved_color_texture_.reset(new BackTexture(this)); + offscreen_saved_color_texture_.reset(new BackTexture( + memory_tracker(), &state_)); offscreen_saved_color_texture_->Create(); // Allocate the render buffers at their initial size and check the status @@ -2442,6 +2530,10 @@ bool GLES2DecoderImpl::Initialize( context_->SetUnbindFboOnMakeCurrent(); } + if (feature_info_->workarounds().release_image_after_use) { + image_manager()->SetReleaseAfterUse(); + } + // Only compositor contexts are known to use only the subset of GL // that can be safely migrated between the iGPU and the dGPU. Mark // those contexts as safe to forcibly transition between the GPUs. @@ -2453,9 +2545,46 @@ bool GLES2DecoderImpl::Initialize( AsyncPixelTransferManager::Create(context.get())); async_pixel_transfer_manager_->Initialize(texture_manager()); + framebuffer_manager()->AddObserver(this); + return true; } +Capabilities GLES2DecoderImpl::GetCapabilities() { + DCHECK(initialized()); + + Capabilities caps; + + caps.fast_npot_mo8_textures = + feature_info_->workarounds().enable_chromium_fast_npot_mo8_textures; + caps.egl_image_external = + feature_info_->feature_flags().oes_egl_image_external; + caps.texture_format_bgra8888 = + feature_info_->feature_flags().ext_texture_format_bgra8888; + caps.texture_format_etc1 = + feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture; + caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle; + caps.texture_usage = feature_info_->feature_flags().angle_texture_usage; + caps.texture_storage = feature_info_->feature_flags().ext_texture_storage; + caps.discard_framebuffer = + feature_info_->feature_flags().ext_discard_framebuffer; + +#if defined(OS_MACOSX) + // This is unconditionally true on mac, no need to test for it at runtime. + caps.iosurface = true; +#endif + + // TODO(boliu): Expose this directly from GLSurface. + std::vector<std::string> extension_list; + base::SplitString(surface_->GetExtensions(), ' ', &extension_list); + std::set<std::string> extension_set(extension_list.begin(), + extension_list.end()); + caps.post_sub_buffer = + extension_set.count("GL_CHROMIUM_post_sub_buffer") > 0; + + return caps; +} + void GLES2DecoderImpl::UpdateCapabilities() { util_.set_num_compressed_texture_formats( validators_->compressed_texture_format.GetValues().size()); @@ -2531,6 +2660,8 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() { driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS; if (workarounds().init_gl_position_in_vertex_shader) driver_bug_workarounds |= SH_INIT_GL_POSITION; + if (workarounds().unfold_short_circuit_as_ternary_operation) + driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT; ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance(); vertex_translator_ = cache->GetTranslator( @@ -2636,15 +2767,15 @@ void GLES2DecoderImpl::DeleteFramebuffersHelper( Framebuffer* framebuffer = GetFramebuffer(client_ids[ii]); if (framebuffer && !framebuffer->IsDeleted()) { - if (framebuffer == state_.bound_draw_framebuffer.get()) { - state_.bound_draw_framebuffer = NULL; + if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { + framebuffer_state_.bound_draw_framebuffer = NULL; framebuffer_state_.clear_state_dirty = true; GLenum target = supports_separate_framebuffer_binds ? GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; glBindFramebufferEXT(target, GetBackbufferServiceId()); } - if (framebuffer == state_.bound_read_framebuffer.get()) { - state_.bound_read_framebuffer = NULL; + if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) { + framebuffer_state_.bound_read_framebuffer = NULL; GLenum target = supports_separate_framebuffer_binds ? GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; glBindFramebufferEXT(target, GetBackbufferServiceId()); @@ -2668,17 +2799,17 @@ void GLES2DecoderImpl::DeleteRenderbuffersHelper( } // Unbind from current framebuffers. if (supports_separate_framebuffer_binds) { - if (state_.bound_read_framebuffer.get()) { - state_.bound_read_framebuffer + if (framebuffer_state_.bound_read_framebuffer.get()) { + framebuffer_state_.bound_read_framebuffer ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer); } - if (state_.bound_draw_framebuffer.get()) { - state_.bound_draw_framebuffer + if (framebuffer_state_.bound_draw_framebuffer.get()) { + framebuffer_state_.bound_draw_framebuffer ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer); } } else { - if (state_.bound_draw_framebuffer.get()) { - state_.bound_draw_framebuffer + if (framebuffer_state_.bound_draw_framebuffer.get()) { + framebuffer_state_.bound_draw_framebuffer ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer); } } @@ -2705,17 +2836,17 @@ void GLES2DecoderImpl::DeleteTexturesHelper( } // Unbind from current framebuffers. if (supports_separate_framebuffer_binds) { - if (state_.bound_read_framebuffer.get()) { - state_.bound_read_framebuffer + if (framebuffer_state_.bound_read_framebuffer.get()) { + framebuffer_state_.bound_read_framebuffer ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref); } - if (state_.bound_draw_framebuffer.get()) { - state_.bound_draw_framebuffer + if (framebuffer_state_.bound_draw_framebuffer.get()) { + framebuffer_state_.bound_draw_framebuffer ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref); } } else { - if (state_.bound_draw_framebuffer.get()) { - state_.bound_draw_framebuffer + if (framebuffer_state_.bound_draw_framebuffer.get()) { + framebuffer_state_.bound_draw_framebuffer ->UnbindTexture(GL_FRAMEBUFFER, texture_ref); } } @@ -2733,10 +2864,10 @@ void GLES2DecoderImpl::DeleteTexturesHelper( // } // anonymous namespace bool GLES2DecoderImpl::MakeCurrent() { - if (!context_.get() || !context_->MakeCurrent(surface_.get())) + if (!context_.get()) return false; - if (WasContextLost()) { + if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) { LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent."; // Some D3D drivers cannot recover from device lost in the GPU process @@ -2782,13 +2913,6 @@ void GLES2DecoderImpl::ReleaseCurrent() { context_->ReleaseCurrent(surface_.get()); } -void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() { - Renderbuffer* renderbuffer = - GetRenderbufferInfoForTarget(GL_RENDERBUFFER); - glBindRenderbufferEXT( - GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0); -} - static void RebindCurrentFramebuffer( GLenum target, Framebuffer* framebuffer, @@ -2808,34 +2932,21 @@ void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() { if (!features().chromium_framebuffer_multisample) { RebindCurrentFramebuffer( GL_FRAMEBUFFER, - state_.bound_draw_framebuffer.get(), + framebuffer_state_.bound_draw_framebuffer.get(), GetBackbufferServiceId()); } else { RebindCurrentFramebuffer( GL_READ_FRAMEBUFFER_EXT, - state_.bound_read_framebuffer.get(), + framebuffer_state_.bound_read_framebuffer.get(), GetBackbufferServiceId()); RebindCurrentFramebuffer( GL_DRAW_FRAMEBUFFER_EXT, - state_.bound_draw_framebuffer.get(), + framebuffer_state_.bound_draw_framebuffer.get(), GetBackbufferServiceId()); } OnFboChanged(); } -void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() { - TextureUnit& info = state_.texture_units[0]; - GLuint last_id; - if (info.bound_texture_2d.get()) { - last_id = info.bound_texture_2d->service_id(); - } else { - last_id = 0; - } - - glBindTexture(GL_TEXTURE_2D, last_id); - glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); -} - bool GLES2DecoderImpl::CheckFramebufferValid( Framebuffer* framebuffer, GLenum target, const char* func_name) { @@ -2902,17 +3013,18 @@ bool GLES2DecoderImpl::CheckFramebufferValid( bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) { if (!features().chromium_framebuffer_multisample) { bool valid = CheckFramebufferValid( - state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT, func_name); + framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT, + func_name); if (valid) OnUseFramebuffer(); return valid; } - return CheckFramebufferValid(state_.bound_draw_framebuffer.get(), + return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(), GL_DRAW_FRAMEBUFFER_EXT, func_name) && - CheckFramebufferValid(state_.bound_read_framebuffer.get(), + CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(), GL_READ_FRAMEBUFFER_EXT, func_name); } @@ -2934,6 +3046,16 @@ gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() { } } +GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() { + Framebuffer* framebuffer = + GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); + if (framebuffer != NULL) { + return framebuffer->GetColorAttachmentTextureType(); + } else { + return GL_UNSIGNED_BYTE; + } +} + GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() { Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); @@ -3081,8 +3203,8 @@ void GLES2DecoderImpl::Destroy(bool have_context) { state_.texture_units.clear(); state_.bound_array_buffer = NULL; state_.current_query = NULL; - state_.bound_read_framebuffer = NULL; - state_.bound_draw_framebuffer = NULL; + framebuffer_state_.bound_read_framebuffer = NULL; + framebuffer_state_.bound_draw_framebuffer = NULL; state_.bound_renderbuffer = NULL; if (offscreen_saved_color_texture_info_.get()) { @@ -3189,6 +3311,7 @@ void GLES2DecoderImpl::Destroy(bool have_context) { async_pixel_transfer_manager_.reset(); if (group_.get()) { + framebuffer_manager()->RemoveObserver(this); group_->Destroy(this, have_context); group_ = NULL; } @@ -3285,7 +3408,7 @@ bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { DCHECK(offscreen_target_color_format_); if (IsOffscreenBufferMultisampled()) { if (!offscreen_target_color_render_buffer_->AllocateStorage( - offscreen_size_, offscreen_target_color_format_, + feature_info_, offscreen_size_, offscreen_target_color_format_, offscreen_target_samples_)) { LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " << "to allocate storage for offscreen target color buffer."; @@ -3301,7 +3424,7 @@ bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { } if (offscreen_target_depth_format_ && !offscreen_target_depth_render_buffer_->AllocateStorage( - offscreen_size_, offscreen_target_depth_format_, + feature_info_, offscreen_size_, offscreen_target_depth_format_, offscreen_target_samples_)) { LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " << "to allocate storage for offscreen target depth buffer."; @@ -3309,7 +3432,7 @@ bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { } if (offscreen_target_stencil_format_ && !offscreen_target_stencil_render_buffer_->AllocateStorage( - offscreen_size_, offscreen_target_stencil_format_, + feature_info_, offscreen_size_, offscreen_target_stencil_format_, offscreen_target_samples_)) { LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " << "to allocate storage for offscreen target stencil buffer."; @@ -3434,7 +3557,7 @@ error::Error GLES2DecoderImpl::DoCommand( error::Error result = error::kNoError; if (log_commands()) { // TODO(notme): Change this to a LOG/VLOG that works in release. Tried - // LOG(INFO), tried VLOG(1), no luck. + // VLOG(1), no luck. LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: " << GetCommandName(command); } @@ -3648,15 +3771,16 @@ void GLES2DecoderImpl::RestoreState() const { } void GLES2DecoderImpl::RestoreFramebufferBindings() const { - GLuint service_id = state_.bound_draw_framebuffer.get() - ? state_.bound_draw_framebuffer->service_id() - : GetBackbufferServiceId(); + GLuint service_id = + framebuffer_state_.bound_draw_framebuffer.get() + ? framebuffer_state_.bound_draw_framebuffer->service_id() + : GetBackbufferServiceId(); if (!features().chromium_framebuffer_multisample) { glBindFramebufferEXT(GL_FRAMEBUFFER, service_id); } else { glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id); - service_id = state_.bound_read_framebuffer.get() - ? state_.bound_read_framebuffer->service_id() + service_id = framebuffer_state_.bound_read_framebuffer.get() + ? framebuffer_state_.bound_read_framebuffer->service_id() : GetBackbufferServiceId(); glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id); } @@ -3729,10 +3853,10 @@ void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) { LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer"); if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) { - state_.bound_draw_framebuffer = framebuffer; + framebuffer_state_.bound_draw_framebuffer = framebuffer; } if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) { - state_.bound_read_framebuffer = framebuffer; + framebuffer_state_.bound_read_framebuffer = framebuffer; } framebuffer_state_.clear_state_dirty = true; @@ -3860,6 +3984,13 @@ void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) { void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum* attachments) { + if (!features().ext_discard_framebuffer) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glDiscardFramebufferEXT", + "function not available"); + return; + } + Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER); @@ -3993,13 +4124,16 @@ bool GLES2DecoderImpl::GetHelper( case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *num_written = 1; if (params) { - *params = GL_RGBA; // We don't support other formats. + *params = GLES2Util::GetPreferredGLReadPixelsFormat( + GetBoundReadFrameBufferInternalFormat()); } return true; case GL_IMPLEMENTATION_COLOR_READ_TYPE: *num_written = 1; if (params) { - *params = GL_UNSIGNED_BYTE; // We don't support other types. + *params = GLES2Util::GetPreferredGLReadPixelsType( + GetBoundReadFrameBufferInternalFormat(), + GetBoundReadFrameBufferTextureType()); } return true; case GL_MAX_FRAGMENT_UNIFORM_VECTORS: @@ -4426,21 +4560,6 @@ error::Error GLES2DecoderImpl::HandleBindAttribLocation( return error::kNoError; } -error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate( - uint32 immediate_data_size, const cmds::BindAttribLocationImmediate& c) { - GLuint program = static_cast<GLuint>(c.program); - GLuint index = static_cast<GLuint>(c.index); - uint32 name_size = c.data_size; - const char* name = GetImmediateDataAs<const char*>( - c, name_size, immediate_data_size); - if (name == NULL) { - return error::kOutOfBounds; - } - String name_str(name, name_size); - DoBindAttribLocation(program, index, name_str.c_str()); - return error::kNoError; -} - error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket( uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) { GLuint program = static_cast<GLuint>(c.program); @@ -4506,22 +4625,6 @@ error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM( return error::kNoError; } -error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate( - uint32 immediate_data_size, - const cmds::BindUniformLocationCHROMIUMImmediate& c) { - GLuint program = static_cast<GLuint>(c.program); - GLint location = static_cast<GLint>(c.location); - uint32 name_size = c.data_size; - const char* name = GetImmediateDataAs<const char*>( - c, name_size, immediate_data_size); - if (name == NULL) { - return error::kOutOfBounds; - } - String name_str(name, name_size); - DoBindUniformLocationCHROMIUM(program, location, name_str.c_str()); - return error::kNoError; -} - error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket( uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUMBucket& c) { @@ -4714,7 +4817,7 @@ void GLES2DecoderImpl::DoFramebufferRenderbuffer( if (error == GL_NO_ERROR) { framebuffer->AttachRenderbuffer(attachment, renderbuffer); } - if (framebuffer == state_.bound_draw_framebuffer.get()) { + if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { framebuffer_state_.clear_state_dirty = true; } OnFboChanged(); @@ -4881,6 +4984,9 @@ void GLES2DecoderImpl::DoFramebufferTexture2DCommon( return; } + if (texture_ref) + DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget); + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name); if (0 == samples) { glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level); @@ -4898,9 +5004,13 @@ void GLES2DecoderImpl::DoFramebufferTexture2DCommon( framebuffer->AttachTexture(attachment, texture_ref, textarget, level, samples); } - if (framebuffer == state_.bound_draw_framebuffer.get()) { + if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { framebuffer_state_.clear_state_dirty = true; } + + if (texture_ref) + DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget); + OnFboChanged(); } @@ -4960,7 +5070,7 @@ void GLES2DecoderImpl::DoGetRenderbufferParameteriv( } } -void GLES2DecoderImpl::DoBlitFramebufferEXT( +void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { @@ -4968,49 +5078,75 @@ void GLES2DecoderImpl::DoBlitFramebufferEXT( if (!features().chromium_framebuffer_multisample) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, - "glBlitFramebufferEXT", "function not available"); + "glBlitFramebufferCHROMIUM", "function not available"); + return; } - if (!CheckBoundFramebuffersValid("glBlitFramebufferEXT")) { + if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) { return; } glDisable(GL_SCISSOR_TEST); - if (IsAngle()) { + BlitFramebufferHelper( + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test); +} + +void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper( + const FeatureInfo* feature_info, + GLenum target, + GLsizei samples, + GLenum internal_format, + GLsizei width, + GLsizei height) { + // TODO(sievers): This could be resolved at the GL binding level, but the + // binding process is currently a bit too 'brute force'. + if (feature_info->feature_flags().is_angle) { + glRenderbufferStorageMultisampleANGLE( + target, samples, internal_format, width, height); + } else if (feature_info->feature_flags().use_core_framebuffer_multisample) { + glRenderbufferStorageMultisample( + target, samples, internal_format, width, height); + } else { + glRenderbufferStorageMultisampleEXT( + target, samples, internal_format, width, height); + } +} + +void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) { + // TODO(sievers): This could be resolved at the GL binding level, but the + // binding process is currently a bit too 'brute force'. + if (feature_info_->feature_flags().is_angle) { glBlitFramebufferANGLE( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) { + glBlitFramebuffer( + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } else { glBlitFramebufferEXT( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } - EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test); } -void GLES2DecoderImpl::DoRenderbufferStorageMultisample( - GLenum target, GLsizei samples, GLenum internalformat, - GLsizei width, GLsizei height) { - if (!features().chromium_framebuffer_multisample && - !features().multisampled_render_to_texture) { - LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glRenderbufferStorageMultisample", "function not available"); - return; - } - - Renderbuffer* renderbuffer = - GetRenderbufferInfoForTarget(GL_RENDERBUFFER); - if (!renderbuffer) { - LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glRenderbufferStorageMultisample", "no renderbuffer bound"); - return; - } - +bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample( + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) { if (samples > renderbuffer_manager()->max_samples()) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glRenderbufferStorageMultisample", "samples too large"); - return; + return false; } if (width > renderbuffer_manager()->max_renderbuffer_size() || @@ -5018,7 +5154,7 @@ void GLES2DecoderImpl::DoRenderbufferStorageMultisample( LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glRenderbufferStorageMultisample", "dimensions too large"); - return; + return false; } uint32 estimated_size = 0; @@ -5027,31 +5163,51 @@ void GLES2DecoderImpl::DoRenderbufferStorageMultisample( LOCAL_SET_GL_ERROR( GL_OUT_OF_MEMORY, "glRenderbufferStorageMultsample", "dimensions too large"); - return; + return false; } if (!EnsureGPUMemoryAvailable(estimated_size)) { LOCAL_SET_GL_ERROR( GL_OUT_OF_MEMORY, "glRenderbufferStorageMultsample", "out of memory"); + return false; + } + + return true; +} + +void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM( + GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height) { + if (!features().chromium_framebuffer_multisample) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glRenderbufferStorageMultisampleCHROMIUM", + "function not available"); + return; + } + + Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER); + if (!renderbuffer) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glRenderbufferStorageMultisampleCHROMIUM", + "no renderbuffer bound"); + return; + } + + if (!ValidateRenderbufferStorageMultisample( + samples, internalformat, width, height)) { return; } GLenum impl_format = renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( internalformat); - LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisample"); - if (IsAngle()) { - glRenderbufferStorageMultisampleANGLE( - target, samples, impl_format, width, height); - } else if (features().use_img_for_multisampled_render_to_texture) { - glRenderbufferStorageMultisampleIMG( - target, samples, impl_format, width, height); - } else { - glRenderbufferStorageMultisampleEXT( - target, samples, impl_format, width, height); - } - GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisample"); + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER( + "glRenderbufferStorageMultisampleCHROMIUM"); + RenderbufferStorageMultisampleHelper( + feature_info_, target, samples, impl_format, width, height); + GLenum error = + LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM"); if (error == GL_NO_ERROR) { if (workarounds().validate_multisample_buffer_allocation) { @@ -5059,7 +5215,7 @@ void GLES2DecoderImpl::DoRenderbufferStorageMultisample( renderbuffer->service_id(), impl_format)) { LOCAL_SET_GL_ERROR( GL_OUT_OF_MEMORY, - "glRenderbufferStorageMultisample", "out of memory"); + "glRenderbufferStorageMultisampleCHROMIUM", "out of memory"); return; } } @@ -5072,6 +5228,51 @@ void GLES2DecoderImpl::DoRenderbufferStorageMultisample( } } +// This is the handler for multisampled_render_to_texture extensions. +void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT( + GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height) { + if (!features().multisampled_render_to_texture) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, + "glRenderbufferStorageMultisampleEXT", "function not available"); + return; + } + + Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER); + if (!renderbuffer) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, + "glRenderbufferStorageMultisampleEXT", + "no renderbuffer bound"); + return; + } + + if (!ValidateRenderbufferStorageMultisample( + samples, internalformat, width, height)) { + return; + } + + GLenum impl_format = + renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( + internalformat); + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT"); + if (features().use_img_for_multisampled_render_to_texture) { + glRenderbufferStorageMultisampleIMG( + target, samples, impl_format, width, height); + } else { + glRenderbufferStorageMultisampleEXT( + target, samples, impl_format, width, height); + } + GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT"); + if (error == GL_NO_ERROR) { + // TODO(gman): If renderbuffers tracked which framebuffers they were + // attached to we could just mark those framebuffers as not complete. + framebuffer_manager()->IncFramebufferStateChangeCount(); + renderbuffer_manager()->SetInfo( + renderbuffer, samples, internalformat, width, height); + } +} + // This function validates the allocation of a multisampled renderbuffer // by clearing it to a key color, blitting the contents to a texture, and // reading back the color to ensure it matches the key. @@ -5144,7 +5345,8 @@ bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity( glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_); - glBlitFramebufferEXT(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST); + BlitFramebufferHelper( + 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST); // Read a pixel from the buffer. glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_); @@ -5239,13 +5441,14 @@ void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) { if (program->Link(shader_manager(), vertex_translator, fragment_translator, - feature_info_.get(), + workarounds().count_all_in_varyings_packing ? + Program::kCountAll : Program::kCountOnlyStaticallyUsed, shader_cache_callback_)) { if (program == state_.current_program.get()) { - if (workarounds().use_current_program_after_successful_link) { + if (workarounds().use_current_program_after_successful_link) glUseProgram(program->service_id()); - } - program_manager()->ClearUniforms(program); + if (workarounds().clear_uniforms_before_first_program_use) + program_manager()->ClearUniforms(program); } } }; @@ -5711,6 +5914,8 @@ void GLES2DecoderImpl::DoUseProgram(GLuint program_id) { glUseProgram(service_id); if (state_.current_program.get()) { program_manager()->UseProgram(state_.current_program.get()); + if (workarounds().clear_uniforms_before_first_program_use) + program_manager()->ClearUniforms(program); } } @@ -5738,11 +5943,49 @@ void GLES2DecoderImpl::UpdateStreamTextureIfNeeded(Texture* texture, } } +void GLES2DecoderImpl::DoWillUseTexImageIfNeeded( + Texture* texture, GLenum textarget) { + // This might be supported in the future. + if (textarget != GL_TEXTURE_2D) + return; + // Image is already in use if texture is attached to a framebuffer. + if (texture && !texture->IsAttachedToFramebuffer()) { + gfx::GLImage* image = texture->GetLevelImage(textarget, 0); + if (image) { + ScopedGLErrorSuppressor suppressor( + "GLES2DecoderImpl::DoWillUseTexImageIfNeeded", + GetErrorState()); + glBindTexture(textarget, texture->service_id()); + image->WillUseTexImage(); + RestoreCurrentTexture2DBindings(&state_); + } + } +} + +void GLES2DecoderImpl::DoDidUseTexImageIfNeeded( + Texture* texture, GLenum textarget) { + // This might be supported in the future. + if (textarget != GL_TEXTURE_2D) + return; + // Image is still in use if texture is attached to a framebuffer. + if (texture && !texture->IsAttachedToFramebuffer()) { + gfx::GLImage* image = texture->GetLevelImage(textarget, 0); + if (image) { + ScopedGLErrorSuppressor suppressor( + "GLES2DecoderImpl::DoDidUseTexImageIfNeeded", + GetErrorState()); + glBindTexture(textarget, texture->service_id()); + image->DidUseTexImage(); + RestoreCurrentTexture2DBindings(&state_); + } + } +} + bool GLES2DecoderImpl::PrepareTexturesForRender() { DCHECK(state_.current_program.get()); - bool have_unrenderable_textures = - texture_manager()->HaveUnrenderableTextures(); - if (!have_unrenderable_textures && !features().oes_egl_image_external) { + if (!texture_manager()->HaveUnrenderableTextures() && + !texture_manager()->HaveImages() && + !features().oes_egl_image_external) { return true; } @@ -5757,16 +6000,14 @@ bool GLES2DecoderImpl::PrepareTexturesForRender() { GLuint texture_unit_index = uniform_info->texture_units[jj]; if (texture_unit_index < state_.texture_units.size()) { TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; - TextureRef* texture = + TextureRef* texture_ref = texture_unit.GetInfoForSamplerType(uniform_info->type).get(); - if (texture) - UpdateStreamTextureIfNeeded(texture->texture(), texture_unit_index); - if (have_unrenderable_textures && - (!texture || !texture_manager()->CanRender(texture))) { + GLenum textarget = GetBindTargetForSamplerType(uniform_info->type); + if (!texture_ref || !texture_manager()->CanRender(texture_ref)) { textures_set = true; glActiveTexture(GL_TEXTURE0 + texture_unit_index); glBindTexture( - GetBindTargetForSamplerType(uniform_info->type), + textarget, texture_manager()->black_texture_id(uniform_info->type)); LOCAL_RENDER_WARNING( std::string("texture bound to texture unit ") + @@ -5774,7 +6015,23 @@ bool GLES2DecoderImpl::PrepareTexturesForRender() { " is not renderable. It maybe non-power-of-2 and have" " incompatible texture filtering or is not" " 'texture complete'"); + continue; } + + Texture* texture = texture_ref->texture(); + if (textarget == GL_TEXTURE_2D) { + gfx::GLImage* image = texture->GetLevelImage(textarget, 0); + if (image && !texture->IsAttachedToFramebuffer()) { + ScopedGLErrorSuppressor suppressor( + "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState()); + textures_set = true; + glActiveTexture(GL_TEXTURE0 + texture_unit_index); + image->WillUseTexImage(); + continue; + } + } + + UpdateStreamTextureIfNeeded(texture, texture_unit_index); } // else: should this be an error? } @@ -5782,7 +6039,7 @@ bool GLES2DecoderImpl::PrepareTexturesForRender() { return !textures_set; } -void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() { +void GLES2DecoderImpl::RestoreStateForTextures() { DCHECK(state_.current_program.get()); const Program::SamplerIndices& sampler_indices = state_.current_program->sampler_indices(); @@ -5795,9 +6052,7 @@ void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() { if (texture_unit_index < state_.texture_units.size()) { TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; TextureRef* texture_ref = - uniform_info->type == GL_SAMPLER_2D - ? texture_unit.bound_texture_2d.get() - : texture_unit.bound_texture_cube_map.get(); + texture_unit.GetInfoForSamplerType(uniform_info->type).get(); if (!texture_ref || !texture_manager()->CanRender(texture_ref)) { glActiveTexture(GL_TEXTURE0 + texture_unit_index); // Get the texture_ref info that was previously bound here. @@ -5806,6 +6061,20 @@ void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() { : texture_unit.bound_texture_cube_map.get(); glBindTexture(texture_unit.bind_target, texture_ref ? texture_ref->service_id() : 0); + continue; + } + + Texture* texture = texture_ref->texture(); + if (texture_unit.bind_target == GL_TEXTURE_2D) { + gfx::GLImage* image = texture->GetLevelImage( + texture_unit.bind_target, 0); + if (image && !texture->IsAttachedToFramebuffer()) { + ScopedGLErrorSuppressor suppressor( + "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState()); + glActiveTexture(GL_TEXTURE0 + texture_unit_index); + image->DidUseTexImage(); + continue; + } } } } @@ -6095,8 +6364,9 @@ error::Error GLES2DecoderImpl::DoDrawArrays( GLint first, GLsizei count, GLsizei primcount) { - if (ShouldDeferDraws()) - return error::kDeferCommandUntilLater; + error::Error error = WillAccessBoundFramebufferForDraw(); + if (error != error::kNoError) + return error; if (!validators_->draw_mode.IsValid(mode)) { LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode"); return error::kNoError; @@ -6148,7 +6418,7 @@ error::Error GLES2DecoderImpl::DoDrawArrays( } ProcessPendingQueries(); if (textures_set) { - RestoreStateForNonRenderableTextures(); + RestoreStateForTextures(); } if (simulated_fixed_attribs) { RestoreStateForSimulatedFixedAttribs(); @@ -6195,8 +6465,9 @@ error::Error GLES2DecoderImpl::DoDrawElements( GLenum type, int32 offset, GLsizei primcount) { - if (ShouldDeferDraws()) - return error::kDeferCommandUntilLater; + error::Error error = WillAccessBoundFramebufferForDraw(); + if (error != error::kNoError) + return error; if (!state_.vertex_attrib_manager->element_array_buffer()) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, function_name, "No element array buffer bound"); @@ -6282,7 +6553,7 @@ error::Error GLES2DecoderImpl::DoDrawElements( ProcessPendingQueries(); if (textures_set) { - RestoreStateForNonRenderableTextures(); + RestoreStateForTextures(); } if (simulated_fixed_attribs) { RestoreStateForSimulatedFixedAttribs(); @@ -6371,17 +6642,6 @@ error::Error GLES2DecoderImpl::HandleShaderSource( return ShaderSourceHelper(c.shader, data, data_size); } -error::Error GLES2DecoderImpl::HandleShaderSourceImmediate( - uint32 immediate_data_size, const cmds::ShaderSourceImmediate& c) { - uint32 data_size = c.data_size; - const char* data = GetImmediateDataAs<const char*>( - c, data_size, immediate_data_size); - if (!data) { - return error::kOutOfBounds; - } - return ShaderSourceHelper(c.shader, data, data_size); -} - error::Error GLES2DecoderImpl::HandleShaderSourceBucket( uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) { Bucket* bucket = GetBucket(c.data_bucket_id); @@ -6405,7 +6665,11 @@ void GLES2DecoderImpl::DoCompileShader(GLuint client_id) { vertex_translator_.get() : fragment_translator_.get(); } - program_manager()->DoCompileShader(shader, translator, feature_info_.get()); + program_manager()->DoCompileShader( + shader, + translator, + feature_info_->feature_flags().angle_translated_shader_source ? + ProgramManager::kANGLE : ProgramManager::kGL); }; void GLES2DecoderImpl::DoGetShaderiv( @@ -6856,6 +7120,29 @@ error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE( return error::kNoError; } +template <typename pixel_data_type> +static void WriteAlphaData( + void *pixels, uint32 row_count, uint32 channel_count, + uint32 alpha_channel_index, uint32 unpadded_row_size, + uint32 padded_row_size, pixel_data_type alpha_value) { + DCHECK_GT(channel_count, 0U); + DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U); + uint32 unpadded_row_size_in_elements = + unpadded_row_size / sizeof(pixel_data_type); + DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U); + uint32 padded_row_size_in_elements = + padded_row_size / sizeof(pixel_data_type); + pixel_data_type* dst = + static_cast<pixel_data_type*>(pixels) + alpha_channel_index; + for (uint32 yy = 0; yy < row_count; ++yy) { + pixel_data_type* end = dst + unpadded_row_size_in_elements; + for (pixel_data_type* d = dst; d < end; d += channel_count) { + *d = alpha_value; + } + dst += padded_row_size_in_elements; + } +} + void GLES2DecoderImpl::FinishReadPixels( const cmds::ReadPixels& c, GLuint buffer) { @@ -6924,38 +7211,49 @@ void GLES2DecoderImpl::FinishReadPixels( &unpadded_row_size, &padded_row_size)) { return; } - // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time - // of this implementation. - if (type != GL_UNSIGNED_BYTE) { - return; - } + + uint32 channel_count = 0; + uint32 alpha_channel = 0; switch (format) { case GL_RGBA: case GL_BGRA_EXT: - case GL_ALPHA: { - int offset = (format == GL_ALPHA) ? 0 : 3; - int step = (format == GL_ALPHA) ? 1 : 4; - uint8* dst = static_cast<uint8*>(pixels) + offset; - for (GLint yy = 0; yy < height; ++yy) { - uint8* end = dst + unpadded_row_size; - for (uint8* d = dst; d < end; d += step) { - *d = 255; - } - dst += padded_row_size; - } + channel_count = 4; + alpha_channel = 3; break; - } - default: + case GL_ALPHA: + channel_count = 1; + alpha_channel = 0; break; } + + if (channel_count > 0) { + switch (type) { + case GL_UNSIGNED_BYTE: + WriteAlphaData<uint8>( + pixels, height, channel_count, alpha_channel, unpadded_row_size, + padded_row_size, 0xFF); + break; + case GL_FLOAT: + WriteAlphaData<float>( + pixels, height, channel_count, alpha_channel, unpadded_row_size, + padded_row_size, 1.0f); + break; + case GL_HALF_FLOAT: + WriteAlphaData<uint16>( + pixels, height, channel_count, alpha_channel, unpadded_row_size, + padded_row_size, 0x3C00); + break; + } + } } } error::Error GLES2DecoderImpl::HandleReadPixels( uint32 immediate_data_size, const cmds::ReadPixels& c) { - if (ShouldDeferReads()) - return error::kDeferCommandUntilLater; + error::Error fbo_error = WillAccessBoundFramebufferForRead(); + if (fbo_error != error::kNoError) + return fbo_error; GLint x = c.x; GLint y = c.y; GLsizei width = c.width; @@ -6992,10 +7290,26 @@ error::Error GLES2DecoderImpl::HandleReadPixels( LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format"); return error::kNoError; } - if (!validators_->pixel_type.IsValid(type)) { + if (!validators_->read_pixel_type.IsValid(type)) { LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type"); return error::kNoError; } + if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB && + format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) { + // format and type are acceptable enums but not guaranteed to be supported + // for this framebuffer. Have to ask gl if they are valid. + GLint preferred_format = 0; + DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format); + GLint preferred_type = 0; + DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type); + if (format != static_cast<GLenum>(preferred_format) || + type != static_cast<GLenum>(preferred_type)) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible " + "with the current read framebuffer"); + return error::kNoError; + } + } if (width == 0 || height == 0) { return error::kNoError; } @@ -7213,19 +7527,6 @@ error::Error GLES2DecoderImpl::HandleGetAttribLocation( c.program, c.location_shm_id, c.location_shm_offset, name_str); } -error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate( - uint32 immediate_data_size, const cmds::GetAttribLocationImmediate& c) { - uint32 name_size = c.data_size; - const char* name = GetImmediateDataAs<const char*>( - c, name_size, immediate_data_size); - if (!name) { - return error::kOutOfBounds; - } - String name_str(name, name_size); - return GetAttribLocationHelper( - c.program, c.location_shm_id, c.location_shm_offset, name_str); -} - error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket( uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) { Bucket* bucket = GetBucket(c.name_bucket_id); @@ -7285,19 +7586,6 @@ error::Error GLES2DecoderImpl::HandleGetUniformLocation( c.program, c.location_shm_id, c.location_shm_offset, name_str); } -error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate( - uint32 immediate_data_size, const cmds::GetUniformLocationImmediate& c) { - uint32 name_size = c.data_size; - const char* name = GetImmediateDataAs<const char*>( - c, name_size, immediate_data_size); - if (!name) { - return error::kOutOfBounds; - } - String name_str(name, name_size); - return GetUniformLocationHelper( - c.program, c.location_shm_id, c.location_shm_offset, name_str); -} - error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket( uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) { Bucket* bucket = GetBucket(c.name_bucket_id); @@ -7397,20 +7685,6 @@ error::Error GLES2DecoderImpl::HandleBufferData( return error::kNoError; } -error::Error GLES2DecoderImpl::HandleBufferDataImmediate( - uint32 immediate_data_size, const cmds::BufferDataImmediate& c) { - GLenum target = static_cast<GLenum>(c.target); - GLsizeiptr size = static_cast<GLsizeiptr>(c.size); - const void* data = GetImmediateDataAs<const void*>( - c, size, immediate_data_size); - if (!data) { - return error::kOutOfBounds; - } - GLenum usage = static_cast<GLenum>(c.usage); - buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage); - return error::kNoError; -} - void GLES2DecoderImpl::DoBufferSubData( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { // Just delegate it. Some validation is actually done before this. @@ -7429,7 +7703,8 @@ bool GLES2DecoderImpl::ClearLevel( int height, bool is_texture_immutable) { uint32 channels = GLES2Util::GetChannelsForFormat(format); - if (IsAngle() && (channels & GLES2Util::kDepth) != 0) { + if (feature_info_->feature_flags().angle_depth_texture && + (channels & GLES2Util::kDepth) != 0) { // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D // on depth formats. GLuint fb = 0; @@ -7762,24 +8037,6 @@ error::Error GLES2DecoderImpl::HandleCompressedTexImage2D( target, level, internal_format, width, height, border, image_size, data); } -error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate( - uint32 immediate_data_size, const cmds::CompressedTexImage2DImmediate& c) { - GLenum target = static_cast<GLenum>(c.target); - GLint level = static_cast<GLint>(c.level); - GLenum internal_format = static_cast<GLenum>(c.internalformat); - GLsizei width = static_cast<GLsizei>(c.width); - GLsizei height = static_cast<GLsizei>(c.height); - GLint border = static_cast<GLint>(c.border); - GLsizei image_size = static_cast<GLsizei>(c.imageSize); - const void* data = GetImmediateDataAs<const void*>( - c, image_size, immediate_data_size); - if (!data) { - return error::kOutOfBounds; - } - return DoCompressedTexImage2D( - target, level, internal_format, width, height, border, image_size, data); -} - error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket( uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) { GLenum target = static_cast<GLenum>(c.target); @@ -7893,38 +8150,6 @@ error::Error GLES2DecoderImpl::HandleTexImage2D( return error::kNoError; } -error::Error GLES2DecoderImpl::HandleTexImage2DImmediate( - uint32 immediate_data_size, const cmds::TexImage2DImmediate& c) { - GLenum target = static_cast<GLenum>(c.target); - GLint level = static_cast<GLint>(c.level); - // TODO(kloveless): Change TexImage2DImmediate command to use unsigned - // integer for internalformat. - GLenum internal_format = static_cast<GLenum>(c.internalformat); - GLsizei width = static_cast<GLsizei>(c.width); - GLsizei height = static_cast<GLsizei>(c.height); - GLint border = static_cast<GLint>(c.border); - GLenum format = static_cast<GLenum>(c.format); - GLenum type = static_cast<GLenum>(c.type); - uint32 size; - if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, state_.unpack_alignment, &size, - NULL, NULL)) { - return error::kOutOfBounds; - } - const void* pixels = GetImmediateDataAs<const void*>( - c, size, immediate_data_size); - if (!pixels) { - return error::kOutOfBounds; - } - - TextureManager::DoTextImage2DArguments args = { - target, level, internal_format, width, height, border, format, type, - pixels, size}; - texture_manager()->ValidateAndDoTexImage2D( - &texture_state_, &state_, &framebuffer_state_, args); - return error::kNoError; -} - void GLES2DecoderImpl::DoCompressedTexSubImage2D( GLenum target, GLint level, @@ -8346,7 +8571,7 @@ error::Error GLES2DecoderImpl::DoTexSubImage2D( return error::kNoError; } - if (texture_state_.teximage2d_faster_than_texsubimage2d && + if (!texture_state_.texsubimage2d_faster_than_teximage2d && !texture->IsImmutable()) { ScopedTextureUploadTimer timer(&texture_state_); // NOTE: In OpenGL ES 2.0 border is always zero and format is always the @@ -8389,32 +8614,6 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels); } -error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate( - uint32 immediate_data_size, const cmds::TexSubImage2DImmediate& c) { - GLboolean internal = static_cast<GLboolean>(c.internal); - if (internal == GL_TRUE && texture_state_.tex_image_2d_failed) - return error::kNoError; - - GLenum target = static_cast<GLenum>(c.target); - GLint level = static_cast<GLint>(c.level); - GLint xoffset = static_cast<GLint>(c.xoffset); - GLint yoffset = static_cast<GLint>(c.yoffset); - GLsizei width = static_cast<GLsizei>(c.width); - GLsizei height = static_cast<GLsizei>(c.height); - GLenum format = static_cast<GLenum>(c.format); - GLenum type = static_cast<GLenum>(c.type); - uint32 data_size; - if (!GLES2Util::ComputeImageDataSizes( - width, height, format, type, state_.unpack_alignment, &data_size, - NULL, NULL)) { - return error::kOutOfBounds; - } - const void* pixels = GetImmediateDataAs<const void*>( - c, data_size, immediate_data_size); - return DoTexSubImage2D( - target, level, xoffset, yoffset, width, height, format, type, pixels); -} - error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv( uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) { GLuint index = static_cast<GLuint>(c.index); @@ -8809,7 +9008,7 @@ void GLES2DecoderImpl::DoSwapBuffers() { if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0) return; ScopedGLErrorSuppressor suppressor( - "GLES2DecoderImpl::DoSwapBuffers", this); + "GLES2DecoderImpl::DoSwapBuffers", GetErrorState()); if (IsOffscreenBufferMultisampled()) { // For multisampled buffers, resolve the frame buffer. @@ -8837,7 +9036,7 @@ void GLES2DecoderImpl::DoSwapBuffers() { // Ensure the side effects of the copy are visible to the parent // context. There is no need to do this for ANGLE because it uses a // single D3D device for all contexts. - if (!IsAngle()) + if (!feature_info_->feature_flags().is_angle) glFlush(); } } else { @@ -9128,6 +9327,18 @@ error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM( error::kNoError : error::kDeferCommandUntilLater; } +error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM( + uint32 immediate_data_size, const cmds::DiscardBackbufferCHROMIUM& c) { + if (surface_->DeferDraws()) + return error::kDeferCommandUntilLater; + if (!surface_->SetBackbufferAllocation(false)) + return error::kLostContext; + backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT; + backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT; + backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT; + return error::kNoError; +} + bool GLES2DecoderImpl::GenQueriesEXTHelper( GLsizei n, const GLuint* client_ids) { for (GLsizei ii = 0; ii < n; ++ii) { @@ -9649,34 +9860,17 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( if (dest_texture->target() != GL_TEXTURE_2D || (source_texture->target() != GL_TEXTURE_2D && source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, - "glCopyTextureCHROMIUM", "invalid texture target binding"); + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, + "glCopyTextureCHROMIUM", + "invalid texture target binding"); return; } int source_width, source_height, dest_width, dest_height; - if (source_texture->target() == GL_TEXTURE_2D) { - if (!source_texture->GetLevelSize(GL_TEXTURE_2D, 0, &source_width, - &source_height)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, - "glCopyTextureChromium", "source texture has no level 0"); - return; - } - - // Check that this type of texture is allowed. - if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width, - source_height, 1)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, - "glCopyTextureCHROMIUM", "Bad dimensions"); - return; - } - } - - if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { + if (source_texture->IsStreamTexture()) { + DCHECK_EQ(source_texture->target(), + static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES)); DCHECK(stream_texture_manager()); StreamTexture* stream_tex = stream_texture_manager()->LookupStreamTexture( @@ -9696,6 +9890,30 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( "glCopyTextureChromium", "invalid streamtexture size"); return; } + } else { + if (!source_texture->GetLevelSize( + source_texture->target(), 0, &source_width, &source_height)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, + "glCopyTextureChromium", + "source texture has no level 0"); + return; + } + + // Check that this type of texture is allowed. + if (!texture_manager()->ValidForTarget( + source_texture->target(), level, source_width, source_height, 1)) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions"); + return; + } + } + + // Clear the source texture if necessary. + if (!texture_manager()->ClearTextureLevel( + this, source_texture_ref, source_texture->target(), 0)) { + LOCAL_SET_GL_ERROR( + GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big"); + return; } // Defer initializing the CopyTextureCHROMIUMResourceManager until it is @@ -9732,7 +9950,7 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( 0, internal_format, dest_type, NULL); GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM"); if (error != GL_NO_ERROR) { - RestoreCurrentTexture2DBindings(); + RestoreCurrentTexture2DBindings(&state_); return; } @@ -9744,6 +9962,8 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( dest_texture_ref, GL_TEXTURE_2D, level, true); } + DoWillUseTexImageIfNeeded(source_texture, source_texture->target()); + // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix // before presenting. if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { @@ -9776,6 +9996,8 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( unpack_premultiply_alpha_, unpack_unpremultiply_alpha_); } + + DoDidUseTexImageIfNeeded(source_texture, source_texture->target()); } static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { @@ -9831,7 +10053,7 @@ void GLES2DecoderImpl::DoTexStorage2DEXT( GLsizei height) { TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT"); if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) || - TextureManager::ComputeMipMapCount(width, height, 1) < levels) { + TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range"); return; @@ -9901,15 +10123,7 @@ void GLES2DecoderImpl::DoTexStorage2DEXT( error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM( uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) { - MailboxName name; - mailbox_manager()->GenerateMailboxName(&name); - uint32 bucket_id = static_cast<uint32>(c.bucket_id); - Bucket* bucket = CreateBucket(bucket_id); - - bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM); - bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM); - - return error::kNoError; + return error::kUnknownCommand; } void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target, @@ -10034,13 +10248,6 @@ void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) { void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM( GLenum target, GLint image_id) { TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM"); - if (target != GL_TEXTURE_2D) { - // This might be supported in the future. - LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target"); - return; - } // Default target might be conceptually valid, but disallow it to avoid // accidents. @@ -10063,8 +10270,8 @@ void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM( { ScopedGLErrorSuppressor suppressor( - "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", this); - if (!gl_image->BindTexImage()) { + "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState()); + if (!gl_image->BindTexImage(target)) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID"); @@ -10082,13 +10289,6 @@ void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM( void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM( GLenum target, GLint image_id) { TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM"); - if (target != GL_TEXTURE_2D) { - // This might be supported in the future. - LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target"); - return; - } // Default target might be conceptually valid, but disallow it to avoid // accidents. @@ -10115,8 +10315,8 @@ void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM( { ScopedGLErrorSuppressor suppressor( - "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", this); - gl_image->ReleaseTexImage(); + "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState()); + gl_image->ReleaseTexImage(target); } texture_manager()->SetLevelInfo( @@ -10449,6 +10649,12 @@ error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM( return error::kNoError; } +void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer( + TextureRef* texture_ref) { + Texture* texture = texture_ref->texture(); + DoDidUseTexImageIfNeeded(texture, texture->target()); +} + // Include the auto-generated part of this file. We split this because it means // we can easily edit the non-auto generated parts right here in this file // instead of having to edit some template or the code generator. diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h index e518702bccc..87c93350415 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "build/build_config.h" +#include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/service/common_decoder.h" #include "gpu/command_buffer/service/logger.h" #include "ui/gfx/size.h" @@ -42,12 +43,10 @@ class VertexArrayManager; struct DisallowedFeatures { DisallowedFeatures() : multisampling(false), - swap_buffer_complete_callback(false), gpu_memory_manager(false) { } bool multisampling; - bool swap_buffer_complete_callback; bool gpu_memory_manager; }; @@ -138,6 +137,8 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, // Gets the associated ContextGroup virtual ContextGroup* GetContextGroup() = 0; + virtual Capabilities GetCapabilities() = 0; + // Restores all of the decoder GL state. virtual void RestoreState() const = 0; @@ -225,11 +226,6 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, // Lose this context. virtual void LoseContext(uint32 reset_status) = 0; - static bool IsAngle(); - - // Used for testing only - static void set_testing_force_is_angle(bool force); - virtual Logger* GetLogger() = 0; protected: @@ -239,7 +235,6 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, bool initialized_; bool debug_; bool log_commands_; - static bool testing_force_is_angle_; DISALLOW_COPY_AND_ASSIGN(GLES2Decoder); }; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 393c90292c8..ddc00fcc4fb 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -216,29 +216,6 @@ error::Error GLES2DecoderImpl::HandleBufferSubData( return error::kNoError; } -error::Error GLES2DecoderImpl::HandleBufferSubDataImmediate( - uint32 immediate_data_size, const gles2::cmds::BufferSubDataImmediate& c) { - GLenum target = static_cast<GLenum>(c.target); - GLintptr offset = static_cast<GLintptr>(c.offset); - GLsizeiptr size = static_cast<GLsizeiptr>(c.size); - uint32 data_size = size; - const void* data = GetImmediateDataAs<const void*>( - c, data_size, immediate_data_size); - if (!validators_->buffer_target.IsValid(target)) { - LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferSubData", target, "target"); - return error::kNoError; - } - if (size < 0) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferSubData", "size < 0"); - return error::kNoError; - } - if (data == NULL) { - return error::kOutOfBounds; - } - DoBufferSubData(target, offset, size, data); - return error::kNoError; -} - error::Error GLES2DecoderImpl::HandleCheckFramebufferStatus( uint32 immediate_data_size, const gles2::cmds::CheckFramebufferStatus& c) { GLenum target = static_cast<GLenum>(c.target); @@ -259,8 +236,10 @@ error::Error GLES2DecoderImpl::HandleCheckFramebufferStatus( error::Error GLES2DecoderImpl::HandleClear( uint32 immediate_data_size, const gles2::cmds::Clear& c) { - if (ShouldDeferDraws()) - return error::kDeferCommandUntilLater; + error::Error error; + error = WillAccessBoundFramebufferForDraw(); + if (error != error::kNoError) + return error; GLbitfield mask = static_cast<GLbitfield>(c.mask); DoClear(mask); return error::kNoError; @@ -378,57 +357,12 @@ error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2D( return error::kNoError; } -error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DImmediate( - uint32 immediate_data_size, - const gles2::cmds::CompressedTexSubImage2DImmediate& c) { - GLenum target = static_cast<GLenum>(c.target); - GLint level = static_cast<GLint>(c.level); - GLint xoffset = static_cast<GLint>(c.xoffset); - GLint yoffset = static_cast<GLint>(c.yoffset); - GLsizei width = static_cast<GLsizei>(c.width); - GLsizei height = static_cast<GLsizei>(c.height); - GLenum format = static_cast<GLenum>(c.format); - GLsizei imageSize = static_cast<GLsizei>(c.imageSize); - uint32 data_size = imageSize; - const void* data = GetImmediateDataAs<const void*>( - c, data_size, immediate_data_size); - if (!validators_->texture_target.IsValid(target)) { - LOCAL_SET_GL_ERROR_INVALID_ENUM("glCompressedTexSubImage2D", target, - "target"); - return error::kNoError; - } - if (width < 0) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0"); - return error::kNoError; - } - if (height < 0) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0"); - return error::kNoError; - } - if (!validators_->compressed_texture_format.IsValid(format)) { - LOCAL_SET_GL_ERROR_INVALID_ENUM("glCompressedTexSubImage2D", format, - "format"); - return error::kNoError; - } - if (imageSize < 0) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0"); - return error::kNoError; - } - if (data == NULL) { - return error::kOutOfBounds; - } - DoCompressedTexSubImage2D( - target, level, xoffset, yoffset, width, height, format, imageSize, data); - return error::kNoError; -} - error::Error GLES2DecoderImpl::HandleCopyTexImage2D( uint32 immediate_data_size, const gles2::cmds::CopyTexImage2D& c) { - if (ShouldDeferReads()) - return error::kDeferCommandUntilLater; + error::Error error; + error = WillAccessBoundFramebufferForRead(); + if (error != error::kNoError) + return error; GLenum target = static_cast<GLenum>(c.target); GLint level = static_cast<GLint>(c.level); GLenum internalformat = static_cast<GLenum>(c.internalformat); @@ -465,8 +399,10 @@ error::Error GLES2DecoderImpl::HandleCopyTexImage2D( error::Error GLES2DecoderImpl::HandleCopyTexSubImage2D( uint32 immediate_data_size, const gles2::cmds::CopyTexSubImage2D& c) { - if (ShouldDeferReads()) - return error::kDeferCommandUntilLater; + error::Error error; + error = WillAccessBoundFramebufferForRead(); + if (error != error::kNoError) + return error; GLenum target = static_cast<GLenum>(c.target); GLint level = static_cast<GLint>(c.level); GLint xoffset = static_cast<GLint>(c.xoffset); @@ -739,8 +675,10 @@ error::Error GLES2DecoderImpl::HandleEnableVertexAttribArray( error::Error GLES2DecoderImpl::HandleFinish( uint32 immediate_data_size, const gles2::cmds::Finish& c) { - if (ShouldDeferReads()) - return error::kDeferCommandUntilLater; + error::Error error; + error = WillAccessBoundFramebufferForRead(); + if (error != error::kNoError) + return error; DoFinish(); return error::kNoError; } @@ -2698,10 +2636,16 @@ error::Error GLES2DecoderImpl::HandleViewport( return error::kNoError; } -error::Error GLES2DecoderImpl::HandleBlitFramebufferEXT( - uint32 immediate_data_size, const gles2::cmds::BlitFramebufferEXT& c) { - if (ShouldDeferDraws() || ShouldDeferReads()) - return error::kDeferCommandUntilLater; +error::Error GLES2DecoderImpl::HandleBlitFramebufferCHROMIUM( + uint32 immediate_data_size, + const gles2::cmds::BlitFramebufferCHROMIUM& c) { + error::Error error; + error = WillAccessBoundFramebufferForDraw(); + if (error != error::kNoError) + return error; + error = WillAccessBoundFramebufferForRead(); + if (error != error::kNoError) + return error; GLint srcX0 = static_cast<GLint>(c.srcX0); GLint srcY0 = static_cast<GLint>(c.srcY0); GLint srcX1 = static_cast<GLint>(c.srcX1); @@ -2713,14 +2657,51 @@ error::Error GLES2DecoderImpl::HandleBlitFramebufferEXT( GLbitfield mask = static_cast<GLbitfield>(c.mask); GLenum filter = static_cast<GLenum>(c.filter); if (!validators_->blit_filter.IsValid(filter)) { - LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlitFramebufferEXT", filter, "filter"); + LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlitFramebufferCHROMIUM", filter, + "filter"); return error::kNoError; } - DoBlitFramebufferEXT( + DoBlitFramebufferCHROMIUM( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); return error::kNoError; } +error::Error GLES2DecoderImpl::HandleRenderbufferStorageMultisampleCHROMIUM( + uint32 immediate_data_size, + const gles2::cmds::RenderbufferStorageMultisampleCHROMIUM& c) { + GLenum target = static_cast<GLenum>(c.target); + GLsizei samples = static_cast<GLsizei>(c.samples); + GLenum internalformat = static_cast<GLenum>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + if (!validators_->render_buffer_target.IsValid(target)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM("glRenderbufferStorageMultisampleCHROMIUM", target, "target"); // NOLINT + return error::kNoError; + } + if (samples < 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glRenderbufferStorageMultisampleCHROMIUM", "samples < 0"); // NOLINT + return error::kNoError; + } + if (!validators_->render_buffer_format.IsValid(internalformat)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM("glRenderbufferStorageMultisampleCHROMIUM", internalformat, "internalformat"); // NOLINT + return error::kNoError; + } + if (width < 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glRenderbufferStorageMultisampleCHROMIUM", "width < 0"); // NOLINT + return error::kNoError; + } + if (height < 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glRenderbufferStorageMultisampleCHROMIUM", "height < 0"); // NOLINT + return error::kNoError; + } + DoRenderbufferStorageMultisampleCHROMIUM( + target, samples, internalformat, width, height); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleRenderbufferStorageMultisampleEXT( uint32 immediate_data_size, const gles2::cmds::RenderbufferStorageMultisampleEXT& c) { @@ -2752,7 +2733,7 @@ error::Error GLES2DecoderImpl::HandleRenderbufferStorageMultisampleEXT( GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "height < 0"); return error::kNoError; } - DoRenderbufferStorageMultisample( + DoRenderbufferStorageMultisampleEXT( target, samples, internalformat, width, height); return error::kNoError; } diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index e993a5e6982..f52c2217040 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h @@ -52,6 +52,7 @@ class MockGLES2Decoder : public GLES2Decoder { MOCK_METHOD0(GetGLSurface, gfx::GLSurface*()); MOCK_METHOD0(GetGLContext, gfx::GLContext*()); MOCK_METHOD0(GetContextGroup, ContextGroup*()); + MOCK_METHOD0(GetCapabilities, Capabilities()); MOCK_METHOD0(ProcessPendingQueries, bool()); MOCK_METHOD0(HasMoreIdleWork, bool()); MOCK_METHOD0(PerformIdleWork, void()); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 14acb4061cf..ec8ff6ccb2f 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -4,7 +4,8 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder.h" -#include "base/atomicops.h" +#include "base/command_line.h" +#include "base/strings/string_number_conversions.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/common/id_allocator.h" @@ -15,6 +16,7 @@ #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/gl_surface_mock.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h" +#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mocks.h" @@ -63,15 +65,21 @@ class GLES2DecoderTest : public GLES2DecoderTestBase { bool init); }; -class GLES2DecoderANGLETest : public GLES2DecoderTestBase { +class GLES2DecoderTestWithExtensions + : public GLES2DecoderTest, + public ::testing::WithParamInterface<const char*> { public: - GLES2DecoderANGLETest() - : GLES2DecoderTestBase() { - GLES2Decoder::set_testing_force_is_angle(true); - } + GLES2DecoderTestWithExtensions() {} - virtual ~GLES2DecoderANGLETest() { - GLES2Decoder::set_testing_force_is_angle(false); + virtual void SetUp() { + InitDecoder(GetParam(), // extensions + true, // has alpha + true, // has depth + false, // has stencil + true, // request alpha + true, // request depth + false, // request stencil + false); // bind generates resource } }; @@ -132,13 +140,6 @@ class GLES2DecoderManualInitTest : public GLES2DecoderWithShaderTest { } }; -class GLES2DecoderANGLEManualInitTest : public GLES2DecoderANGLETest { - public: - // Override default setup so nothing gets setup. - virtual void SetUp() { - } -}; - TEST_F(GLES2DecoderWithShaderTest, DrawArraysNoAttributesSucceeds) { SetupTexture(); AddExpectationsForSimulatedAttrib0(kNumVertices, 0); @@ -1731,41 +1732,6 @@ TEST_F(GLES2DecoderTest, ShaderSourceInvalidArgs) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } -TEST_F(GLES2DecoderTest, ShaderSourceImmediateAndGetShaderSourceValidArgs) { - const uint32 kBucketId = 123; - const char kSource[] = "hello"; - const uint32 kSourceSize = sizeof(kSource) - 1; - ShaderSourceImmediate& cmd = *GetImmediateAs<ShaderSourceImmediate>(); - cmd.Init(client_shader_id_, kSourceSize); - memcpy(GetImmediateDataAs<void*>(&cmd), kSource, kSourceSize); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kSourceSize)); - memset(shared_memory_address_, 0, kSourceSize); - // TODO(gman): GetShaderSource has to change format so result is always set. - GetShaderSource get_cmd; - get_cmd.Init(client_shader_id_, kBucketId); - EXPECT_EQ(error::kNoError, ExecuteCmd(get_cmd)); - CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); - ASSERT_TRUE(bucket != NULL); - EXPECT_EQ(kSourceSize + 1, bucket->size()); - EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kSource, - bucket->size())); -} - -TEST_F(GLES2DecoderTest, ShaderSourceImmediateInvalidArgs) { - const char kSource[] = "hello"; - const uint32 kSourceSize = sizeof(kSource) - 1; - ShaderSourceImmediate& cmd = *GetImmediateAs<ShaderSourceImmediate>(); - cmd.Init(kInvalidClientId, kSourceSize); - memcpy(GetImmediateDataAs<void*>(&cmd), kSource, kSourceSize); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kSourceSize)); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); -#if GLES2_TEST_SHADER_VS_PROGRAM_IDS - cmd.Init(client_program_id_, kSourceSize); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kSourceSize)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); -#endif // GLES2_TEST_SHADER_VS_PROGRAM_IDS -} - TEST_F(GLES2DecoderTest, ShaderSourceBucketAndGetShaderSourceValidArgs) { const uint32 kInBucketId = 123; const uint32 kOutBucketId = 125; @@ -2565,31 +2531,6 @@ TEST_F(GLES2DecoderTest, BindAttribLocationInvalidArgs) { EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); } -TEST_F(GLES2DecoderTest, BindAttribLocationImmediate) { - const GLint kLocation = 2; - const char* kName = "testing"; - const uint32 kNameSize = strlen(kName); - EXPECT_CALL( - *gl_, BindAttribLocation(kServiceProgramId, kLocation, StrEq(kName))) - .Times(1); - BindAttribLocationImmediate& cmd = - *GetImmediateAs<BindAttribLocationImmediate>(); - cmd.Init(client_program_id_, kLocation, kName, kNameSize); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kNameSize)); -} - -TEST_F(GLES2DecoderTest, BindAttribLocationImmediateInvalidArgs) { - const GLint kLocation = 2; - const char* kName = "testing"; - const uint32 kNameSize = strlen(kName); - EXPECT_CALL(*gl_, BindAttribLocation(_, _, _)).Times(0); - BindAttribLocationImmediate& cmd = - *GetImmediateAs<BindAttribLocationImmediate>(); - cmd.Init(kInvalidClientId, kLocation, kName, kNameSize); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kNameSize)); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); -} - TEST_F(GLES2DecoderTest, BindAttribLocationBucket) { const uint32 kBucketId = 123; const GLint kLocation = 2; @@ -2708,49 +2649,6 @@ TEST_F(GLES2DecoderWithShaderTest, GetAttribLocationInvalidArgs) { EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); } -TEST_F(GLES2DecoderWithShaderTest, GetAttribLocationImmediate) { - const uint32 kNameSize = strlen(kAttrib2Name); - const char* kNonExistentName = "foobar"; - const uint32 kNonExistentNameSize = strlen(kNonExistentName); - typedef GetAttribLocationImmediate::Result Result; - Result* result = GetSharedMemoryAs<Result*>(); - *result = -1; - GetAttribLocationImmediate& cmd = - *GetImmediateAs<GetAttribLocationImmediate>(); - cmd.Init(client_program_id_, kAttrib2Name, - kSharedMemoryId, kSharedMemoryOffset); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kNameSize)); - EXPECT_EQ(kAttrib2Location, *result); - *result = -1; - cmd.Init(client_program_id_, kNonExistentName, - kSharedMemoryId, kSharedMemoryOffset); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kNonExistentNameSize)); - EXPECT_EQ(-1, *result); -} - -TEST_F(GLES2DecoderWithShaderTest, GetAttribLocationImmediateInvalidArgs) { - const uint32 kNameSize = strlen(kAttrib2Name); - typedef GetAttribLocationImmediate::Result Result; - Result* result = GetSharedMemoryAs<Result*>(); - *result = -1; - GetAttribLocationImmediate& cmd = - *GetImmediateAs<GetAttribLocationImmediate>(); - cmd.Init(kInvalidClientId, kAttrib2Name, - kSharedMemoryId, kSharedMemoryOffset); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kNameSize)); - EXPECT_EQ(-1, *result); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); - *result = -1; - cmd.Init(client_program_id_, kAttrib2Name, - kInvalidSharedMemoryId, kSharedMemoryOffset); - EXPECT_NE(error::kNoError, ExecuteImmediateCmd(cmd, kNameSize)); - EXPECT_EQ(-1, *result); - cmd.Init(client_program_id_, kAttrib2Name, - kSharedMemoryId, kInvalidSharedMemoryOffset); - EXPECT_NE(error::kNoError, ExecuteImmediateCmd(cmd, kNameSize)); - EXPECT_EQ(-1, *result); -} - TEST_F(GLES2DecoderWithShaderTest, GetAttribLocationBucket) { const uint32 kBucketId = 123; const char* kNonExistentName = "foobar"; @@ -2884,49 +2782,6 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformLocationInvalidArgs) { EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); } -TEST_F(GLES2DecoderWithShaderTest, GetUniformLocationImmediate) { - const uint32 kNameSize = strlen(kUniform2Name); - const char* kNonExistentName = "foobar"; - const uint32 kNonExistentNameSize = strlen(kNonExistentName); - typedef GetUniformLocationImmediate::Result Result; - Result* result = GetSharedMemoryAs<Result*>(); - *result = -1; - GetUniformLocationImmediate& cmd = - *GetImmediateAs<GetUniformLocationImmediate>(); - cmd.Init(client_program_id_, kUniform2Name, - kSharedMemoryId, kSharedMemoryOffset); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kNameSize)); - EXPECT_EQ(kUniform2FakeLocation, *result); - *result = -1; - cmd.Init(client_program_id_, kNonExistentName, - kSharedMemoryId, kSharedMemoryOffset); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kNonExistentNameSize)); - EXPECT_EQ(-1, *result); -} - -TEST_F(GLES2DecoderWithShaderTest, GetUniformLocationImmediateInvalidArgs) { - const uint32 kNameSize = strlen(kUniform2Name); - typedef GetUniformLocationImmediate::Result Result; - Result* result = GetSharedMemoryAs<Result*>(); - *result = -1; - GetUniformLocationImmediate& cmd = - *GetImmediateAs<GetUniformLocationImmediate>(); - cmd.Init(kInvalidClientId, kUniform2Name, - kSharedMemoryId, kSharedMemoryOffset); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kNameSize)); - EXPECT_EQ(-1, *result); - EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); - *result = -1; - cmd.Init(client_program_id_, kUniform2Name, - kInvalidSharedMemoryId, kSharedMemoryOffset); - EXPECT_NE(error::kNoError, ExecuteImmediateCmd(cmd, kNameSize)); - EXPECT_EQ(-1, *result); - cmd.Init(client_program_id_, kUniform2Name, - kSharedMemoryId, kInvalidSharedMemoryOffset); - EXPECT_NE(error::kNoError, ExecuteImmediateCmd(cmd, kNameSize)); - EXPECT_EQ(-1, *result); -} - TEST_F(GLES2DecoderWithShaderTest, GetUniformLocationBucket) { const uint32 kBucketId = 123; const char* kNonExistentName = "foobar"; @@ -4867,7 +4722,8 @@ TEST_F(GLES2DecoderTest, RenderbufferStorageBadArgs) { EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); } -TEST_F(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleGLError) { +TEST_F(GLES2DecoderManualInitTest, + RenderbufferStorageMultisampleCHROMIUMGLError) { InitDecoder( "GL_EXT_framebuffer_multisample", // extensions false, // has alpha @@ -4887,13 +4743,14 @@ TEST_F(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleGLError) { GL_RENDERBUFFER, 1, GL_RGBA, 100, 50)) .Times(1) .RetiresOnSaturation(); - RenderbufferStorageMultisampleEXT cmd; + RenderbufferStorageMultisampleCHROMIUM cmd; cmd.Init(GL_RENDERBUFFER, 1, GL_RGBA4, 100, 50); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); } -TEST_F(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleBadArgs) { +TEST_F(GLES2DecoderManualInitTest, + RenderbufferStorageMultisampleCHROMIUMBadArgs) { InitDecoder( "GL_EXT_framebuffer_multisample", // extensions false, // has alpha @@ -4908,7 +4765,7 @@ TEST_F(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleBadArgs) { EXPECT_CALL(*gl_, RenderbufferStorageMultisampleEXT(_, _, _, _, _)) .Times(0) .RetiresOnSaturation(); - RenderbufferStorageMultisampleEXT cmd; + RenderbufferStorageMultisampleCHROMIUM cmd; cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples + 1, GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -4923,6 +4780,122 @@ TEST_F(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleBadArgs) { EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); } +TEST_F(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleCHROMIUM) { + InitDecoder( + "GL_EXT_framebuffer_multisample", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + false); // bind generates resource + DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_, + kServiceRenderbufferId); + InSequence sequence; + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL( + *gl_, + RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, + TestHelper::kMaxSamples, + GL_RGBA, + TestHelper::kMaxRenderbufferSize, + 1)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + RenderbufferStorageMultisampleCHROMIUM cmd; + cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples, + GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderManualInitTest, + RenderbufferStorageMultisampleEXTNotSupported) { + InitDecoder( + "GL_EXT_framebuffer_multisample", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + false); // bind generates resource + DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_, + kServiceRenderbufferId); + InSequence sequence; + // GL_EXT_framebuffer_multisample uses RenderbufferStorageMultisampleCHROMIUM. + RenderbufferStorageMultisampleEXT cmd; + cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples, + GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +class GLES2DecoderMultisampledRenderToTextureTest + : public GLES2DecoderTestWithExtensions {}; + +TEST_P(GLES2DecoderMultisampledRenderToTextureTest, + NotCompatibleWithRenderbufferStorageMultisampleCHROMIUM) { + DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_, + kServiceRenderbufferId); + RenderbufferStorageMultisampleCHROMIUM cmd; + cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples, + GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderMultisampledRenderToTextureTest, + RenderbufferStorageMultisampleEXT) { + DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_, + kServiceRenderbufferId); + InSequence sequence; + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + if (strstr(GetParam(), "GL_IMG_multisampled_render_to_texture")) { + EXPECT_CALL( + *gl_, + RenderbufferStorageMultisampleIMG(GL_RENDERBUFFER, + TestHelper::kMaxSamples, + GL_RGBA, + TestHelper::kMaxRenderbufferSize, + 1)) + .Times(1) + .RetiresOnSaturation(); + } else { + EXPECT_CALL( + *gl_, + RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, + TestHelper::kMaxSamples, + GL_RGBA, + TestHelper::kMaxRenderbufferSize, + 1)) + .Times(1) + .RetiresOnSaturation(); + } + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + RenderbufferStorageMultisampleEXT cmd; + cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples, + GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +INSTANTIATE_TEST_CASE_P( + GLES2DecoderMultisampledRenderToTextureTests, + GLES2DecoderMultisampledRenderToTextureTest, + ::testing::Values("GL_EXT_multisampled_render_to_texture", + "GL_IMG_multisampled_render_to_texture")); + TEST_F(GLES2DecoderTest, ReadPixelsGLError) { GLenum kFormat = GL_RGBA; GLint x = 0; @@ -6253,7 +6226,7 @@ TEST_F(GLES2DecoderTest, TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); - DoTexImage2DSameSize( + DoTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset); EXPECT_CALL(*gl_, TexSubImage2D( @@ -6275,14 +6248,49 @@ TEST_F(GLES2DecoderTest, TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) { EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } -TEST_F(GLES2DecoderANGLETest, - TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) { +TEST_F( + GLES2DecoderManualInitTest, + TexSubImage2DDoesNotClearAfterTexImage2DNULLThenDataWithTexImage2DIsFaster) { + CommandLine command_line(0, NULL); + command_line.AppendSwitchASCII( + switches::kGpuDriverBugWorkarounds, + base::IntToString(gpu::TEXSUBIMAGE2D_FASTER_THAN_TEXIMAGE2D)); + InitDecoderWithCommandLine( + "", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true, // bind generates resource + &command_line); DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); - DoTexImage2DSameSize( - GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, - kSharedMemoryId, kSharedMemoryOffset); + + { + // Uses texSubimage internally because the above workaround is active and + // the update is for the full size of the texture. + EXPECT_CALL(*gl_, + TexSubImage2D( + GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, _)) + .Times(1) + .RetiresOnSaturation(); + cmds::TexImage2D cmd; + cmd.Init(GL_TEXTURE_2D, + 0, + GL_RGBA, + 2, + 2, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + } + EXPECT_CALL(*gl_, TexSubImage2D( GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, shared_memory_address_)) @@ -7342,25 +7350,6 @@ TEST_F(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) { static_cast<GLenum>(sync->result)); } -TEST_F(GLES2DecoderTest, GenMailboxCHROMIUM) { - const uint32 kBucketId = 123; - - GenMailboxCHROMIUM gen_mailbox_cmd; - gen_mailbox_cmd.Init(kBucketId); - EXPECT_EQ(error::kNoError, ExecuteCmd(gen_mailbox_cmd)); - - CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); - ASSERT_TRUE(bucket != NULL); - ASSERT_EQ(static_cast<uint32>(GL_MAILBOX_SIZE_CHROMIUM), bucket->size()); - - static const GLbyte zero[GL_MAILBOX_SIZE_CHROMIUM] = { - 0 - }; - EXPECT_NE(0, memcmp(zero, - bucket->GetData(0, GL_MAILBOX_SIZE_CHROMIUM), - sizeof(zero))); -} - TEST_F(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) { GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM]; group().mailbox_manager()->GenerateMailboxName( @@ -7554,7 +7543,7 @@ TEST_F(GLES2DecoderManualInitTest, GenerateMipmapDepthTexture) { EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } -TEST_F(GLES2DecoderANGLEManualInitTest, DrawClearsDepthTexture) { +TEST_F(GLES2DecoderManualInitTest, DrawClearsDepthTexture) { InitDecoder( "GL_ANGLE_depth_texture", // extensions true, // has alpha @@ -8051,6 +8040,146 @@ TEST_F(GLES2DecoderTest, ReleaseTexImage2DCHROMIUM) { EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL); } +class MockGLImage : public gfx::GLImage { + public: + MockGLImage() {} + + // Overridden from gfx::GLImage: + MOCK_METHOD0(Destroy, void()); + MOCK_METHOD0(GetSize, gfx::Size()); + MOCK_METHOD1(BindTexImage, bool(unsigned)); + MOCK_METHOD1(ReleaseTexImage, void(unsigned)); + MOCK_METHOD0(WillUseTexImage, void()); + MOCK_METHOD0(DidUseTexImage, void()); + + protected: + virtual ~MockGLImage() {} +}; + +TEST_F(GLES2DecoderWithShaderTest, UseTexImage) { + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + kSharedMemoryId, kSharedMemoryOffset); + + TextureRef* texture_ref = group().texture_manager()->GetTexture( + client_texture_id_); + ASSERT_TRUE(texture_ref != NULL); + Texture* texture = texture_ref->texture(); + EXPECT_EQ(kServiceTextureId, texture->service_id()); + + const int32 kImageId = 1; + scoped_refptr<MockGLImage> image(new MockGLImage); + group().image_manager()->AddImage(image.get(), kImageId); + + // Bind image to texture. + EXPECT_CALL(*image, BindTexImage(GL_TEXTURE_2D)) + .Times(1) + .WillOnce(Return(true)) + .RetiresOnSaturation(); + EXPECT_CALL(*image, GetSize()) + .Times(1) + .WillOnce(Return(gfx::Size(1, 1))) + .RetiresOnSaturation(); + // ScopedGLErrorSuppressor calls GetError on its constructor and destructor. + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + BindTexImage2DCHROMIUM bind_tex_image_2d_cmd; + bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, kImageId); + EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd)); + + AddExpectationsForSimulatedAttrib0(kNumVertices, 0); + SetupExpectationsForApplyingDefaultDirtyState(); + + // ScopedGLErrorSuppressor calls GetError on its constructor and destructor. + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)) + .Times(3) + .RetiresOnSaturation(); + EXPECT_CALL(*image, WillUseTexImage()) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*image, DidUseTexImage()) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) + .Times(1) + .RetiresOnSaturation(); + DrawArrays cmd; + cmd.Init(GL_TRIANGLES, 0, kNumVertices); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_, + kServiceFramebufferId); + // ScopedGLErrorSuppressor calls GetError on its constructor and destructor. + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId)) + .Times(2) + .RetiresOnSaturation(); + // Image will be 'in use' as long as bound to a framebuffer. + EXPECT_CALL(*image, WillUseTexImage()) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, FramebufferTexture2DEXT( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + kServiceTextureId, 0)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + FramebufferTexture2D fbtex_cmd; + fbtex_cmd.Init( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_, + 0); + EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // ScopedGLErrorSuppressor calls GetError on its constructor and destructor. + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, FramebufferRenderbufferEXT( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + kServiceRenderbufferId)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId)) + .Times(2) + .RetiresOnSaturation(); + // Image should no longer be 'in use' after being unbound from framebuffer. + EXPECT_CALL(*image, DidUseTexImage()) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + FramebufferRenderbuffer fbrb_cmd; + fbrb_cmd.Init( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + client_renderbuffer_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd)); +} + TEST_F(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) { InitDecoder( "GL_ARB_texture_rectangle", // extensions @@ -8635,6 +8764,112 @@ TEST_F(GLES2DecoderTest, DrawBuffersEXTImmediateBackbuffer) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +TEST_F(GLES2DecoderManualInitTest, DiscardFramebufferEXT) { + InitDecoder("GL_EXT_discard_framebuffer", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + false); // bind generates resource + + const GLenum target = GL_FRAMEBUFFER; + const GLsizei count = 1; + const GLenum attachments[] = { GL_COLOR_ATTACHMENT0 }; + + SetupTexture(); + DoBindFramebuffer( + GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); + DoFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + client_texture_id_, + kServiceTextureId, + 0, + GL_NO_ERROR); + FramebufferManager* framebuffer_manager = group().framebuffer_manager(); + Framebuffer* framebuffer = + framebuffer_manager->GetFramebuffer(client_framebuffer_id_); + EXPECT_TRUE(framebuffer->IsCleared()); + + EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _)) + .Times(1) + .RetiresOnSaturation(); + DiscardFramebufferEXTImmediate& cmd = + *GetImmediateAs<DiscardFramebufferEXTImmediate>(); + cmd.Init(target, count, attachments); + + EXPECT_EQ(error::kNoError, + ExecuteImmediateCmd(cmd, sizeof(attachments))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_FALSE(framebuffer->IsCleared()); +} + +TEST_F(GLES2DecoderTest, DiscardFramebufferEXTUnsupported) { + const GLenum target = GL_FRAMEBUFFER; + const GLsizei count = 1; + const GLenum attachments[] = { GL_COLOR_EXT }; + DiscardFramebufferEXTImmediate& cmd = + *GetImmediateAs<DiscardFramebufferEXTImmediate>(); + cmd.Init(target, count, attachments); + + // Should not result into a call into GL. + EXPECT_EQ(error::kNoError, + ExecuteImmediateCmd(cmd, sizeof(attachments))); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_F(GLES2DecoderManualInitTest, ClearUniformsBeforeFirstProgramUse) { + CommandLine command_line(0, NULL); + command_line.AppendSwitchASCII( + switches::kGpuDriverBugWorkarounds, + base::IntToString(gpu::CLEAR_UNIFORMS_BEFORE_FIRST_PROGRAM_USE)); + InitDecoderWithCommandLine( + "", // extensions + true, // has alpha + false, // has depth + false, // has stencil + true, // request alpha + false, // request depth + false, // request stencil + true, // bind generates resource + &command_line); + { + static AttribInfo attribs[] = { + { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, }, + { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, }, + { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, }, + }; + static UniformInfo uniforms[] = { + { kUniform1Name, kUniform1Size, kUniform1Type, + kUniform1FakeLocation, kUniform1RealLocation, + kUniform1DesiredLocation }, + { kUniform2Name, kUniform2Size, kUniform2Type, + kUniform2FakeLocation, kUniform2RealLocation, + kUniform2DesiredLocation }, + { kUniform3Name, kUniform3Size, kUniform3Type, + kUniform3FakeLocation, kUniform3RealLocation, + kUniform3DesiredLocation }, + }; + SetupShader(attribs, arraysize(attribs), uniforms, arraysize(uniforms), + client_program_id_, kServiceProgramId, + client_vertex_shader_id_, kServiceVertexShaderId, + client_fragment_shader_id_, kServiceFragmentShaderId); + TestHelper::SetupExpectationsForClearingUniforms( + gl_.get(), uniforms, arraysize(uniforms)); + } + + { + EXPECT_CALL(*gl_, UseProgram(kServiceProgramId)) + .Times(1) + .RetiresOnSaturation(); + cmds::UseProgram cmd; + cmd.Init(client_program_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + } +} + // TODO(gman): Complete this test. // TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) { // } diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc index daa98ae66c7..9c3d7339afe 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc @@ -251,7 +251,8 @@ void GLES2DecoderTestBase::SpecializedSetup<cmds::GetProgramInfoLog, 0>( attach_cmd.Init(client_program_id_, kClientFragmentShaderId); EXPECT_EQ(error::kNoError, ExecuteCmd(attach_cmd)); - program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb)); + program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + base::Bind(&ShaderCacheCb)); }; template <> @@ -267,6 +268,19 @@ void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribfv, 0>( } }; +template <> +void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribiv, 0>( + bool valid) { + DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); + DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0); + if (valid) { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + } +}; + #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h" } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h index bb4b8c86b5c..d89779b1f3e 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h @@ -22,8 +22,6 @@ TEST_F(GLES2DecoderTest1, AttachShaderValidArgs) { } // TODO(gman): BindAttribLocation -// TODO(gman): BindAttribLocationImmediate - // TODO(gman): BindAttribLocationBucket TEST_F(GLES2DecoderTest1, BindBufferValidArgs) { @@ -265,12 +263,8 @@ TEST_F(GLES2DecoderTest1, BlendFuncSeparateValidArgs) { } // TODO(gman): BufferData -// TODO(gman): BufferDataImmediate - // TODO(gman): BufferSubData -// TODO(gman): BufferSubDataImmediate - TEST_F(GLES2DecoderTest1, CheckFramebufferStatusValidArgs) { EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)); @@ -355,13 +349,9 @@ TEST_F(GLES2DecoderTest1, ColorMaskValidArgs) { // TODO(gman): CompileShader // TODO(gman): CompressedTexImage2D -// TODO(gman): CompressedTexImage2DImmediate - // TODO(gman): CompressedTexImage2DBucket // TODO(gman): CompressedTexSubImage2D -// TODO(gman): CompressedTexSubImage2DImmediate - // TODO(gman): CompressedTexSubImage2DBucket // TODO(gman): CopyTexImage2D @@ -1110,8 +1100,6 @@ TEST_F(GLES2DecoderTest1, GenTexturesImmediateInvalidArgs) { // TODO(gman): GetAttribLocation -// TODO(gman): GetAttribLocationImmediate - // TODO(gman): GetAttribLocationBucket @@ -1819,8 +1807,6 @@ TEST_F(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_1) { // TODO(gman): GetUniformLocation -// TODO(gman): GetUniformLocationImmediate - // TODO(gman): GetUniformLocationBucket @@ -1865,5 +1851,155 @@ TEST_F(GLES2DecoderTest1, GetVertexAttribfvInvalidArgs2_1) { EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); EXPECT_EQ(0u, result->size); } + +TEST_F(GLES2DecoderTest1, GetVertexAttribivValidArgs) { + SpecializedSetup<cmds::GetVertexAttribiv, 0>(true); + typedef cmds::GetVertexAttribiv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + result->size = 0; + cmds::GetVertexAttribiv cmd; + cmd.Init( + 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED), + result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderTest1, GetVertexAttribivInvalidArgs2_0) { + EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetVertexAttribiv, 0>(false); + cmds::GetVertexAttribiv::Result* result = + static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetVertexAttribiv cmd; + cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} + +TEST_F(GLES2DecoderTest1, GetVertexAttribivInvalidArgs2_1) { + EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0); + SpecializedSetup<cmds::GetVertexAttribiv, 0>(false); + cmds::GetVertexAttribiv::Result* result = + static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_); + result->size = 0; + cmds::GetVertexAttribiv cmd; + cmd.Init( + 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, + kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(0u, result->size); +} +// TODO(gman): GetVertexAttribPointerv + + +TEST_F(GLES2DecoderTest1, HintValidArgs) { + EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST)); + SpecializedSetup<cmds::Hint, 0>(true); + cmds::Hint cmd; + cmd.Init(GL_GENERATE_MIPMAP_HINT, GL_FASTEST); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderTest1, HintInvalidArgs0_0) { + EXPECT_CALL(*gl_, Hint(_, _)).Times(0); + SpecializedSetup<cmds::Hint, 0>(false); + cmds::Hint cmd; + cmd.Init(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_F(GLES2DecoderTest1, IsBufferValidArgs) { + SpecializedSetup<cmds::IsBuffer, 0>(true); + cmds::IsBuffer cmd; + cmd.Init(client_buffer_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderTest1, IsBufferInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsBuffer, 0>(false); + cmds::IsBuffer cmd; + cmd.Init(client_buffer_id_, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_buffer_id_, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} + +TEST_F(GLES2DecoderTest1, IsEnabledValidArgs) { + SpecializedSetup<cmds::IsEnabled, 0>(true); + cmds::IsEnabled cmd; + cmd.Init(GL_BLEND, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderTest1, IsEnabledInvalidArgs0_0) { + EXPECT_CALL(*gl_, IsEnabled(_)).Times(0); + SpecializedSetup<cmds::IsEnabled, 0>(false); + cmds::IsEnabled cmd; + cmd.Init(GL_CLIP_PLANE0, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_F(GLES2DecoderTest1, IsEnabledInvalidArgs0_1) { + EXPECT_CALL(*gl_, IsEnabled(_)).Times(0); + SpecializedSetup<cmds::IsEnabled, 0>(false); + cmds::IsEnabled cmd; + cmd.Init(GL_POINT_SPRITE, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_F(GLES2DecoderTest1, IsEnabledInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsEnabled, 0>(false); + cmds::IsEnabled cmd; + cmd.Init(GL_BLEND, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(GL_BLEND, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} + +TEST_F(GLES2DecoderTest1, IsFramebufferValidArgs) { + SpecializedSetup<cmds::IsFramebuffer, 0>(true); + cmds::IsFramebuffer cmd; + cmd.Init(client_framebuffer_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderTest1, IsFramebufferInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsFramebuffer, 0>(false); + cmds::IsFramebuffer cmd; + cmd.Init( + client_framebuffer_id_, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init( + client_framebuffer_id_, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} + +TEST_F(GLES2DecoderTest1, IsProgramValidArgs) { + SpecializedSetup<cmds::IsProgram, 0>(true); + cmds::IsProgram cmd; + cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderTest1, IsProgramInvalidArgsBadSharedMemoryId) { + SpecializedSetup<cmds::IsProgram, 0>(false); + cmds::IsProgram cmd; + cmd.Init(client_program_id_, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc index 12d96c28242..8c9c6ecd839 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc @@ -382,19 +382,6 @@ void GLES2DecoderTestBase::SpecializedSetup<cmds::TexParameterivImmediate, 0>( DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); }; -template <> -void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribiv, 0>( - bool valid) { - DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); - DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0); - if (valid) { - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - } -}; - #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h" } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h index caff2eb9807..db72cac7225 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h @@ -11,156 +11,6 @@ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ -TEST_F(GLES2DecoderTest2, GetVertexAttribivValidArgs) { - SpecializedSetup<cmds::GetVertexAttribiv, 0>(true); - typedef cmds::GetVertexAttribiv::Result Result; - Result* result = static_cast<Result*>(shared_memory_address_); - result->size = 0; - cmds::GetVertexAttribiv cmd; - cmd.Init( - 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, - shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned( - GL_VERTEX_ATTRIB_ARRAY_NORMALIZED), - result->GetNumResults()); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_F(GLES2DecoderTest2, GetVertexAttribivInvalidArgs2_0) { - EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetVertexAttribiv, 0>(false); - cmds::GetVertexAttribiv::Result* result = - static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetVertexAttribiv cmd; - cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} - -TEST_F(GLES2DecoderTest2, GetVertexAttribivInvalidArgs2_1) { - EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0); - SpecializedSetup<cmds::GetVertexAttribiv, 0>(false); - cmds::GetVertexAttribiv::Result* result = - static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_); - result->size = 0; - cmds::GetVertexAttribiv cmd; - cmd.Init( - 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_, - kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result->size); -} -// TODO(gman): GetVertexAttribPointerv - - -TEST_F(GLES2DecoderTest2, HintValidArgs) { - EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST)); - SpecializedSetup<cmds::Hint, 0>(true); - cmds::Hint cmd; - cmd.Init(GL_GENERATE_MIPMAP_HINT, GL_FASTEST); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_F(GLES2DecoderTest2, HintInvalidArgs0_0) { - EXPECT_CALL(*gl_, Hint(_, _)).Times(0); - SpecializedSetup<cmds::Hint, 0>(false); - cmds::Hint cmd; - cmd.Init(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_F(GLES2DecoderTest2, IsBufferValidArgs) { - SpecializedSetup<cmds::IsBuffer, 0>(true); - cmds::IsBuffer cmd; - cmd.Init(client_buffer_id_, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_F(GLES2DecoderTest2, IsBufferInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsBuffer, 0>(false); - cmds::IsBuffer cmd; - cmd.Init(client_buffer_id_, kInvalidSharedMemoryId, shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(client_buffer_id_, shared_memory_id_, kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} - -TEST_F(GLES2DecoderTest2, IsEnabledValidArgs) { - SpecializedSetup<cmds::IsEnabled, 0>(true); - cmds::IsEnabled cmd; - cmd.Init(GL_BLEND, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_F(GLES2DecoderTest2, IsEnabledInvalidArgs0_0) { - EXPECT_CALL(*gl_, IsEnabled(_)).Times(0); - SpecializedSetup<cmds::IsEnabled, 0>(false); - cmds::IsEnabled cmd; - cmd.Init(GL_CLIP_PLANE0, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_F(GLES2DecoderTest2, IsEnabledInvalidArgs0_1) { - EXPECT_CALL(*gl_, IsEnabled(_)).Times(0); - SpecializedSetup<cmds::IsEnabled, 0>(false); - cmds::IsEnabled cmd; - cmd.Init(GL_POINT_SPRITE, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); -} - -TEST_F(GLES2DecoderTest2, IsEnabledInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsEnabled, 0>(false); - cmds::IsEnabled cmd; - cmd.Init(GL_BLEND, kInvalidSharedMemoryId, shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(GL_BLEND, shared_memory_id_, kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} - -TEST_F(GLES2DecoderTest2, IsFramebufferValidArgs) { - SpecializedSetup<cmds::IsFramebuffer, 0>(true); - cmds::IsFramebuffer cmd; - cmd.Init(client_framebuffer_id_, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_F(GLES2DecoderTest2, IsFramebufferInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsFramebuffer, 0>(false); - cmds::IsFramebuffer cmd; - cmd.Init( - client_framebuffer_id_, kInvalidSharedMemoryId, shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init( - client_framebuffer_id_, shared_memory_id_, kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} - -TEST_F(GLES2DecoderTest2, IsProgramValidArgs) { - SpecializedSetup<cmds::IsProgram, 0>(true); - cmds::IsProgram cmd; - cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_F(GLES2DecoderTest2, IsProgramInvalidArgsBadSharedMemoryId) { - SpecializedSetup<cmds::IsProgram, 0>(false); - cmds::IsProgram cmd; - cmd.Init(client_program_id_, kInvalidSharedMemoryId, shared_memory_offset_); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(client_program_id_, shared_memory_id_, kInvalidSharedMemoryOffset); - EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); -} - TEST_F(GLES2DecoderTest2, IsRenderbufferValidArgs) { SpecializedSetup<cmds::IsRenderbuffer, 0>(true); cmds::IsRenderbuffer cmd; @@ -328,8 +178,6 @@ TEST_F(GLES2DecoderTest2, ScissorInvalidArgs3_0) { // TODO(gman): ShaderSource -// TODO(gman): ShaderSourceImmediate - // TODO(gman): ShaderSourceBucket TEST_F(GLES2DecoderTest2, StencilFuncValidArgs) { @@ -385,8 +233,6 @@ TEST_F(GLES2DecoderTest2, StencilOpSeparateValidArgs) { } // TODO(gman): TexImage2D -// TODO(gman): TexImage2DImmediate - TEST_F(GLES2DecoderTest2, TexParameterfValidArgs) { EXPECT_CALL( @@ -707,8 +553,6 @@ TEST_F(GLES2DecoderTest2, TexParameterivImmediateInvalidArgs1_0) { } // TODO(gman): TexSubImage2D -// TODO(gman): TexSubImage2DImmediate - TEST_F(GLES2DecoderTest2, Uniform1fValidArgs) { EXPECT_CALL(*gl_, Uniform1fv(1, 1, _)); @@ -1739,7 +1583,8 @@ TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) { EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); } -// TODO(gman): BlitFramebufferEXT +// TODO(gman): BlitFramebufferCHROMIUM +// TODO(gman): RenderbufferStorageMultisampleCHROMIUM // TODO(gman): RenderbufferStorageMultisampleEXT // TODO(gman): FramebufferTexture2DMultisampleEXT // TODO(gman): TexStorage2DEXT @@ -1763,5 +1608,15 @@ TEST_F(GLES2DecoderTest2, PopGroupMarkerEXTValidArgs) { EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +// TODO(gman): GenVertexArraysOES +// TODO(gman): GenVertexArraysOESImmediate +// TODO(gman): DeleteVertexArraysOES +// TODO(gman): DeleteVertexArraysOESImmediate +// TODO(gman): IsVertexArrayOES +// TODO(gman): BindVertexArrayOES +// TODO(gman): SwapBuffers +// TODO(gman): GetMaxValueInBufferCHROMIUM +// TODO(gman): GenSharedIdsCHROMIUM + #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h index 58611bf39d0..ab338e46eff 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h @@ -10,16 +10,6 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ -// TODO(gman): GenVertexArraysOES -// TODO(gman): GenVertexArraysOESImmediate -// TODO(gman): DeleteVertexArraysOES -// TODO(gman): DeleteVertexArraysOESImmediate -// TODO(gman): IsVertexArrayOES -// TODO(gman): BindVertexArrayOES -// TODO(gman): SwapBuffers -// TODO(gman): GetMaxValueInBufferCHROMIUM -// TODO(gman): GenSharedIdsCHROMIUM - // TODO(gman): DeleteSharedIdsCHROMIUM // TODO(gman): RegisterSharedIdsCHROMIUM @@ -47,14 +37,13 @@ // TODO(gman): DrawElementsInstancedANGLE // TODO(gman): VertexAttribDivisorANGLE // TODO(gman): GenMailboxCHROMIUM + // TODO(gman): ProduceTextureCHROMIUM // TODO(gman): ProduceTextureCHROMIUMImmediate // TODO(gman): ConsumeTextureCHROMIUM // TODO(gman): ConsumeTextureCHROMIUMImmediate // TODO(gman): BindUniformLocationCHROMIUM -// TODO(gman): BindUniformLocationCHROMIUMImmediate - // TODO(gman): BindUniformLocationCHROMIUMBucket // TODO(gman): BindTexImage2DCHROMIUM // TODO(gman): ReleaseTexImage2DCHROMIUM diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index 3ce452028f5..9534b627adc 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -88,6 +88,27 @@ void GLES2DecoderTestBase::InitDecoder( bool request_depth, bool request_stencil, bool bind_generates_resource) { + InitDecoderWithCommandLine(extensions, + has_alpha, + has_depth, + has_stencil, + request_alpha, + request_depth, + request_stencil, + bind_generates_resource, + NULL); +} + +void GLES2DecoderTestBase::InitDecoderWithCommandLine( + const char* extensions, + bool has_alpha, + bool has_depth, + bool has_stencil, + bool request_alpha, + bool request_depth, + bool request_stencil, + bool bind_generates_resource, + const CommandLine* command_line) { Framebuffer::ClearFramebufferCompleteComboMap(); gl_.reset(new StrictMock<MockGLInterface>()); ::gfx::GLInterface::SetGLInterface(gl_.get()); @@ -98,11 +119,15 @@ void GLES2DecoderTestBase::InitDecoder( if (std::find(list.begin(), list.end(), "GL_CHROMIUM_stream_texture") != list.end()) stream_texture_manager_.reset(new StrictMock<MockStreamTextureManager>); + scoped_refptr<FeatureInfo> feature_info; + if (command_line) + feature_info = new FeatureInfo(*command_line); group_ = scoped_refptr<ContextGroup>(new ContextGroup( NULL, NULL, memory_tracker_, stream_texture_manager_.get(), + feature_info.get(), bind_generates_resource)); // These two workarounds are always turned on. group_->feature_info( @@ -822,34 +847,6 @@ void GLES2DecoderTestBase::DoCompressedTexImage2D( EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } -void GLES2DecoderTestBase::DoTexImage2DSameSize( - GLenum target, GLint level, GLenum internal_format, - GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, - uint32 shared_memory_id, uint32 shared_memory_offset) { - if (GLES2Decoder::IsAngle()) { - EXPECT_CALL(*gl_, TexSubImage2D( - target, level, 0, 0, width, height, format, type, _)) - .Times(1) - .RetiresOnSaturation(); - } else { - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, TexImage2D(target, level, internal_format, - width, height, border, format, type, _)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - } - cmds::TexImage2D cmd; - cmd.Init(target, level, internal_format, width, height, border, format, - type, shared_memory_id, shared_memory_offset); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); -} - void GLES2DecoderTestBase::DoRenderbufferStorage( GLenum target, GLenum internal_format, GLenum actual_format, GLsizei width, GLsizei height, GLenum error) { @@ -1256,9 +1253,6 @@ void GLES2DecoderTestBase::SetupShader( link_cmd.Init(program_client_id); EXPECT_EQ(error::kNoError, ExecuteCmd(link_cmd)); - - // Assume the next command will be UseProgram. - SetupExpectationsForClearingUniforms(uniforms, num_uniforms); } void GLES2DecoderTestBase::DoEnableVertexAttribArray(GLint index) { diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index c8505c10493..55436192c06 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -25,6 +25,8 @@ #include "ui/gl/gl_surface_stub.h" #include "ui/gl/gl_mock.h" +class CommandLine; + namespace gpu { namespace gles2 { @@ -162,6 +164,17 @@ class GLES2DecoderTestBase : public testing::Test { bool request_stencil, bool bind_generates_resource); + void InitDecoderWithCommandLine( + const char* extensions, + bool has_alpha, + bool has_depth, + bool has_stencil, + bool request_alpha, + bool request_depth, + bool request_stencil, + bool bind_generates_resource, + const CommandLine* command_line); + const ContextGroup& group() const { return *group_.get(); } @@ -184,12 +197,6 @@ class GLES2DecoderTestBase : public testing::Test { GLuint vertex_shader_client_id, GLuint vertex_shader_service_id, GLuint fragment_shader_client_id, GLuint fragment_shader_service_id); - void SetupExpectationsForClearingUniforms( - UniformInfo* uniforms, size_t num_uniforms) { - TestHelper::SetupExpectationsForClearingUniforms( - gl_.get(), uniforms, num_uniforms); - } - void SetupInitCapabilitiesExpectations(); void SetupInitStateExpectations(); void ExpectEnableDisable(GLenum cap, bool enable); @@ -241,11 +248,6 @@ class GLES2DecoderTestBase : public testing::Test { GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, uint32 shared_memory_id, uint32 shared_memory_offset); - void DoTexImage2DSameSize( - GLenum target, GLint level, GLenum internal_format, - GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, - uint32 shared_memory_id, uint32 shared_memory_offset); void DoRenderbufferStorage( GLenum target, GLenum internal_format, GLenum actual_format, GLsizei width, GLsizei height, GLenum error); diff --git a/chromium/gpu/command_buffer/service/gpu_control_service.cc b/chromium/gpu/command_buffer/service/gpu_control_service.cc index d368ff92149..7c0eb8c8044 100644 --- a/chromium/gpu/command_buffer/service/gpu_control_service.cc +++ b/chromium/gpu/command_buffer/service/gpu_control_service.cc @@ -6,19 +6,33 @@ #include "gpu/command_buffer/client/gpu_memory_buffer_factory.h" #include "gpu/command_buffer/service/gpu_memory_buffer_manager.h" +#include "gpu/command_buffer/service/mailbox_manager.h" +#include "gpu/command_buffer/service/query_manager.h" namespace gpu { GpuControlService::GpuControlService( GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager, - GpuMemoryBufferFactory* gpu_memory_buffer_factory) + GpuMemoryBufferFactory* gpu_memory_buffer_factory, + gles2::MailboxManager* mailbox_manager, + gles2::QueryManager* query_manager, + const gpu::Capabilities& decoder_capabilities) : gpu_memory_buffer_manager_(gpu_memory_buffer_manager), - gpu_memory_buffer_factory_(gpu_memory_buffer_factory) { + gpu_memory_buffer_factory_(gpu_memory_buffer_factory), + mailbox_manager_(mailbox_manager), + query_manager_(query_manager), + capabilities_(decoder_capabilities) { + capabilities_.map_image = + gpu_memory_buffer_manager_ && gpu_memory_buffer_factory_; } GpuControlService::~GpuControlService() { } +gpu::Capabilities GpuControlService::GetCapabilities() { + return capabilities_; +} + gfx::GpuMemoryBuffer* GpuControlService::CreateGpuMemoryBuffer( size_t width, size_t height, @@ -58,6 +72,39 @@ void GpuControlService::DestroyGpuMemoryBuffer(int32 id) { gpu_memory_buffer_manager_->DestroyGpuMemoryBuffer(id); } +uint32 GpuControlService::InsertSyncPoint() { + NOTREACHED(); + return 0u; +} + +void GpuControlService::SignalSyncPoint(uint32 sync_point, + const base::Closure& callback) { + NOTREACHED(); +} + +void GpuControlService::SignalQuery(uint32 query_id, + const base::Closure& callback) { + DCHECK(query_manager_); + gles2::QueryManager::Query* query = query_manager_->GetQuery(query_id); + if (!query) + callback.Run(); + else + query->AddCallback(callback); +} + +void GpuControlService::SetSurfaceVisible(bool visible) { + NOTREACHED(); +} + +void GpuControlService::SendManagedMemoryStats( + const ManagedMemoryStats& stats) { + NOTREACHED(); +} + +void GpuControlService::Echo(const base::Closure& callback) { + NOTREACHED(); +} + bool GpuControlService::RegisterGpuMemoryBuffer( int32 id, gfx::GpuMemoryBufferHandle buffer, @@ -71,4 +118,16 @@ bool GpuControlService::RegisterGpuMemoryBuffer( internalformat); } +bool GpuControlService::GenerateMailboxNames( + unsigned num, std::vector<gpu::Mailbox>* names) { + DCHECK(names->empty()); + names->resize(num); + for (unsigned i = 0; i < num; ++i) { + gles2::MailboxName name; + mailbox_manager_->GenerateMailboxName(&name); + (*names)[i].SetName(name.key); + } + return true; +} + } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/gpu_control_service.h b/chromium/gpu/command_buffer/service/gpu_control_service.h index a12fee46532..3764ad42136 100644 --- a/chromium/gpu/command_buffer/service/gpu_control_service.h +++ b/chromium/gpu/command_buffer/service/gpu_control_service.h @@ -15,19 +15,40 @@ namespace gpu { class GpuMemoryBufferFactory; class GpuMemoryBufferManagerInterface; +namespace gles2 { +class MailboxManager; +class QueryManager; +} + class GPU_EXPORT GpuControlService : public GpuControl { public: GpuControlService(GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager, - GpuMemoryBufferFactory* gpu_memory_buffer_factory); + GpuMemoryBufferFactory* gpu_memory_buffer_factory, + gles2::MailboxManager* mailbox_manager, + gles2::QueryManager* query_manager, + const gpu::Capabilities& decoder_capabilities); virtual ~GpuControlService(); - // Overridden from GpuControl: + + // GpuControl implementation. + virtual gpu::Capabilities GetCapabilities() OVERRIDE; virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer( size_t width, size_t height, unsigned internalformat, int32* id) OVERRIDE; virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE; + virtual bool GenerateMailboxNames(unsigned num, + std::vector<gpu::Mailbox>* names) OVERRIDE; + virtual uint32 InsertSyncPoint() OVERRIDE; + virtual void SignalSyncPoint(uint32 sync_point, + const base::Closure& callback) OVERRIDE; + virtual void SignalQuery(uint32 query, + const base::Closure& callback) OVERRIDE; + virtual void SetSurfaceVisible(bool visible) OVERRIDE; + virtual void SendManagedMemoryStats(const ManagedMemoryStats& stats) + OVERRIDE; + virtual void Echo(const base::Closure& callback) OVERRIDE; // Register an existing gpu memory buffer and get an ID that can be used // to identify it in the command buffer. @@ -40,8 +61,11 @@ class GPU_EXPORT GpuControlService : public GpuControl { private: GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager_; GpuMemoryBufferFactory* gpu_memory_buffer_factory_; + gles2::MailboxManager* mailbox_manager_; + gles2::QueryManager* query_manager_; typedef std::map<int32, linked_ptr<gfx::GpuMemoryBuffer> > GpuMemoryBufferMap; GpuMemoryBufferMap gpu_memory_buffers_; + gpu::Capabilities capabilities_; DISALLOW_COPY_AND_ASSIGN(GpuControlService); }; diff --git a/chromium/gpu/command_buffer/service/gpu_scheduler.cc b/chromium/gpu/command_buffer/service/gpu_scheduler.cc index cc86390846e..a40e9899842 100644 --- a/chromium/gpu/command_buffer/service/gpu_scheduler.cc +++ b/chromium/gpu/command_buffer/service/gpu_scheduler.cc @@ -22,10 +22,11 @@ using ::base::SharedMemory; namespace gpu { -namespace { -const int64 kRescheduleTimeOutDelay = 1000; const int64 kUnscheduleFenceTimeOutDelay = 10000; -} + +#if defined(OS_WIN) +const int64 kRescheduleTimeOutDelay = 1000; +#endif GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, AsyncAPIInterface* handler, diff --git a/chromium/gpu/command_buffer/service/gpu_state_tracer.cc b/chromium/gpu/command_buffer/service/gpu_state_tracer.cc index dea05b3879b..6eb5007be9a 100644 --- a/chromium/gpu/command_buffer/service/gpu_state_tracer.cc +++ b/chromium/gpu/command_buffer/service/gpu_state_tracer.cc @@ -18,7 +18,7 @@ const int kBytesPerPixel = 4; class Snapshot : public base::debug::ConvertableToTraceFormat { public: - static scoped_ptr<Snapshot> Create(const ContextState* state); + static scoped_refptr<Snapshot> Create(const ContextState* state); // Save a screenshot of the currently bound framebuffer. bool SaveScreenshot(const gfx::Size& size); @@ -28,6 +28,7 @@ class Snapshot : public base::debug::ConvertableToTraceFormat { private: explicit Snapshot(const ContextState* state); + virtual ~Snapshot() {} const ContextState* state_; @@ -41,8 +42,8 @@ class Snapshot : public base::debug::ConvertableToTraceFormat { Snapshot::Snapshot(const ContextState* state) : state_(state) {} -scoped_ptr<Snapshot> Snapshot::Create(const ContextState* state) { - return scoped_ptr<Snapshot>(new Snapshot(state)); +scoped_refptr<Snapshot> Snapshot::Create(const ContextState* state) { + return scoped_refptr<Snapshot>(new Snapshot(state)); } bool Snapshot::SaveScreenshot(const gfx::Size& size) { @@ -114,7 +115,7 @@ void GPUStateTracer::TakeSnapshotWithCurrentFramebuffer(const gfx::Size& size) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("gpu.debug"), "GPUStateTracer::TakeSnapshotWithCurrentFramebuffer"); - scoped_ptr<Snapshot> snapshot(Snapshot::Create(state_)); + scoped_refptr<Snapshot> snapshot(Snapshot::Create(state_)); // Only save a screenshot for now. if (!snapshot->SaveScreenshot(size)) @@ -124,7 +125,7 @@ void GPUStateTracer::TakeSnapshotWithCurrentFramebuffer(const gfx::Size& size) { TRACE_DISABLED_BY_DEFAULT("gpu.debug"), "gpu::State", state_, - snapshot.PassAs<base::debug::ConvertableToTraceFormat>()); + scoped_refptr<base::debug::ConvertableToTraceFormat>(snapshot)); } } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/gpu_switches.cc b/chromium/gpu/command_buffer/service/gpu_switches.cc index 221dd609756..bff23c31391 100644 --- a/chromium/gpu/command_buffer/service/gpu_switches.cc +++ b/chromium/gpu/command_buffer/service/gpu_switches.cc @@ -57,8 +57,6 @@ const char kGpuDriverBugWorkarounds[] = "gpu-driver-bug-workarounds"; // Sets the maximum size of the in-memory gpu program cache, in kb const char kGpuProgramCacheSizeKb[] = "gpu-program-cache-size-kb"; -const char kTraceGL[] = "trace-gl"; - // Disables the GPU shader on disk cache. const char kDisableGpuShaderDiskCache[] = "disable-gpu-shader-disk-cache"; @@ -82,7 +80,6 @@ const char* kGpuSwitches[] = { kForceSynchronousGLReadPixels, kGpuDriverBugWorkarounds, kGpuProgramCacheSizeKb, - kTraceGL, kDisableGpuShaderDiskCache, kEnableShareGroupAsyncTextureUpload, }; diff --git a/chromium/gpu/command_buffer/service/gpu_switches.h b/chromium/gpu/command_buffer/service/gpu_switches.h index 7634c571174..7916d690142 100644 --- a/chromium/gpu/command_buffer/service/gpu_switches.h +++ b/chromium/gpu/command_buffer/service/gpu_switches.h @@ -26,7 +26,6 @@ GPU_EXPORT extern const char kForceGpuMemAvailableMb[]; GPU_EXPORT extern const char kForceSynchronousGLReadPixels[]; GPU_EXPORT extern const char kGpuDriverBugWorkarounds[]; GPU_EXPORT extern const char kGpuProgramCacheSizeKb[]; -GPU_EXPORT extern const char kTraceGL[]; GPU_EXPORT extern const char kDisableGpuShaderDiskCache[]; GPU_EXPORT extern const char kEnableShareGroupAsyncTextureUpload[]; diff --git a/chromium/gpu/command_buffer/service/gpu_tracer.cc b/chromium/gpu/command_buffer/service/gpu_tracer.cc index 6bb2dfb672f..413dc68739f 100644 --- a/chromium/gpu/command_buffer/service/gpu_tracer.cc +++ b/chromium/gpu/command_buffer/service/gpu_tracer.cc @@ -271,7 +271,7 @@ void GPUTracerImpl::Process() { const std::string& GPUTracerImpl::CurrentName() const { if (!current_trace_.get()) - return EmptyString(); + return base::EmptyString(); return current_trace_->name(); } diff --git a/chromium/gpu/command_buffer/service/image_manager.cc b/chromium/gpu/command_buffer/service/image_manager.cc index a09af1586b0..f39eba21c8a 100644 --- a/chromium/gpu/command_buffer/service/image_manager.cc +++ b/chromium/gpu/command_buffer/service/image_manager.cc @@ -9,7 +9,7 @@ namespace gpu { namespace gles2 { -ImageManager::ImageManager() { +ImageManager::ImageManager() : release_after_use_(false) { } ImageManager::~ImageManager() { @@ -37,6 +37,9 @@ bool ImageManager::RegisterGpuMemoryBuffer(int32 id, if (!gl_image) return false; + if (release_after_use_) + gl_image->SetReleaseAfterUse(); + AddImage(gl_image.get(), id); return true; } @@ -61,5 +64,9 @@ gfx::GLImage* ImageManager::LookupImage(int32 service_id) { return NULL; } +void ImageManager::SetReleaseAfterUse() { + release_after_use_ = true; +} + } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/image_manager.h b/chromium/gpu/command_buffer/service/image_manager.h index a125ae80f05..51e006d7836 100644 --- a/chromium/gpu/command_buffer/service/image_manager.h +++ b/chromium/gpu/command_buffer/service/image_manager.h @@ -37,6 +37,9 @@ class GPU_EXPORT ImageManager void RemoveImage(int32 service_id); gfx::GLImage* LookupImage(int32 service_id); + // For Android specific workaround. + void SetReleaseAfterUse(); + private: friend class base::RefCounted<ImageManager>; @@ -44,6 +47,7 @@ class GPU_EXPORT ImageManager typedef base::hash_map<uint32, scoped_refptr<gfx::GLImage> > GLImageMap; GLImageMap gl_images_; + bool release_after_use_; DISALLOW_COPY_AND_ASSIGN(ImageManager); }; diff --git a/chromium/gpu/command_buffer/service/in_process_command_buffer.cc b/chromium/gpu/command_buffer/service/in_process_command_buffer.cc index 972533cf94d..af14778de27 100644 --- a/chromium/gpu/command_buffer/service/in_process_command_buffer.cc +++ b/chromium/gpu/command_buffer/service/in_process_command_buffer.cc @@ -163,7 +163,7 @@ base::LazyInstance<base::Lock> SchedulerClientBase::all_clients_lock_ = LAZY_INSTANCE_INITIALIZER; SchedulerClientBase::SchedulerClientBase(bool need_thread) { - base::AutoLock(all_clients_lock_.Get()); + base::AutoLock lock(all_clients_lock_.Get()); if (need_thread) { if (!all_clients_.Get().empty()) { SchedulerClientBase* other = *all_clients_.Get().begin(); @@ -177,12 +177,12 @@ SchedulerClientBase::SchedulerClientBase(bool need_thread) { } SchedulerClientBase::~SchedulerClientBase() { - base::AutoLock(all_clients_lock_.Get()); + base::AutoLock lock(all_clients_lock_.Get()); all_clients_.Get().erase(this); } bool SchedulerClientBase::HasClients() { - base::AutoLock(all_clients_lock_.Get()); + base::AutoLock lock(all_clients_lock_.Get()); return !all_clients_.Get().empty(); } @@ -191,6 +191,7 @@ class ThreadClient : public SchedulerClientBase { public: ThreadClient(); virtual void QueueTask(const base::Closure& task) OVERRIDE; + virtual void ScheduleIdleWork(const base::Closure& callback) OVERRIDE; }; ThreadClient::ThreadClient() : SchedulerClientBase(true) { @@ -201,11 +202,17 @@ void ThreadClient::QueueTask(const base::Closure& task) { thread_->message_loop()->PostTask(FROM_HERE, task); } +void ThreadClient::ScheduleIdleWork(const base::Closure& callback) { + thread_->message_loop()->PostDelayedTask( + FROM_HERE, callback, base::TimeDelta::FromMilliseconds(5)); +} + // A client that talks to the GpuCommandQueue class QueueClient : public SchedulerClientBase { public: QueueClient(); virtual void QueueTask(const base::Closure& task) OVERRIDE; + virtual void ScheduleIdleWork(const base::Closure& callback) OVERRIDE; }; QueueClient::QueueClient() : SchedulerClientBase(false) { @@ -216,6 +223,10 @@ void QueueClient::QueueTask(const base::Closure& task) { g_gpu_queue.Get().QueueTask(task); } +void QueueClient::ScheduleIdleWork(const base::Closure& callback) { + // TODO(sievers): Should this do anything? +} + static scoped_ptr<InProcessCommandBuffer::SchedulerClient> CreateSchedulerClient() { scoped_ptr<InProcessCommandBuffer::SchedulerClient> client; @@ -243,7 +254,8 @@ InProcessCommandBuffer::InProcessCommandBuffer() share_group_id_(0), last_put_offset_(-1), flush_event_(false, false), - queue_(CreateSchedulerClient()) {} + queue_(CreateSchedulerClient()), + gpu_thread_weak_ptr_factory_(this) {} InProcessCommandBuffer::~InProcessCommandBuffer() { Destroy(); @@ -315,35 +327,35 @@ bool InProcessCommandBuffer::Initialize( surface_ = surface; } + gpu::Capabilities capabilities; + InitializeOnGpuThreadParams params( + is_offscreen, window, size, attribs, gpu_preference, &capabilities); + base::Callback<bool(void)> init_task = base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread, base::Unretained(this), - is_offscreen, - window, - size, - attribs, - gpu_preference); + params); base::WaitableEvent completion(true, false); bool result = false; QueueTask( base::Bind(&RunTaskWithResult<bool>, init_task, &result, &completion)); completion.Wait(); + + if (result) + capabilities_ = capabilities; return result; } bool InProcessCommandBuffer::InitializeOnGpuThread( - bool is_offscreen, - gfx::AcceleratedWidget window, - const gfx::Size& size, - const std::vector<int32>& attribs, - gfx::GpuPreference gpu_preference) { + const InitializeOnGpuThreadParams& params) { CheckSequencedThread(); + gpu_thread_weak_ptr_ = gpu_thread_weak_ptr_factory_.GetWeakPtr(); // Use one share group for all contexts. CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group, (new gfx::GLShareGroup)); - DCHECK(size.width() >= 0 && size.height() >= 0); + DCHECK(params.size.width() >= 0 && params.size.height() >= 0); TransferBufferManager* manager = new TransferBufferManager(); transfer_buffer_manager_.reset(manager); @@ -352,9 +364,9 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( scoped_ptr<CommandBufferService> command_buffer( new CommandBufferService(transfer_buffer_manager_.get())); command_buffer->SetPutOffsetChangeCallback(base::Bind( - &InProcessCommandBuffer::PumpCommands, base::Unretained(this))); + &InProcessCommandBuffer::PumpCommands, gpu_thread_weak_ptr_)); command_buffer->SetParseErrorCallback(base::Bind( - &InProcessCommandBuffer::OnContextLost, base::Unretained(this))); + &InProcessCommandBuffer::OnContextLost, gpu_thread_weak_ptr_)); if (!command_buffer->Initialize()) { LOG(ERROR) << "Could not initialize command buffer."; @@ -395,6 +407,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( NULL, NULL, stream_texture_manager, + NULL, bind_generates_resource))); gpu_scheduler_.reset( @@ -403,17 +416,13 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( &GpuScheduler::SetGetBuffer, base::Unretained(gpu_scheduler_.get()))); command_buffer_ = command_buffer.Pass(); - gpu_control_.reset( - new GpuControlService(decoder_->GetContextGroup()->image_manager(), - g_gpu_memory_buffer_factory)); - decoder_->set_engine(gpu_scheduler_.get()); if (!surface_) { - if (is_offscreen) - surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size); + if (params.is_offscreen) + surface_ = gfx::GLSurface::CreateOffscreenGLSurface(params.size); else - surface_ = gfx::GLSurface::CreateViewGLSurface(window); + surface_ = gfx::GLSurface::CreateViewGLSurface(params.window); } if (!surface_.get()) { @@ -426,20 +435,20 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( context_ = share_group->GetSharedContext(); if (!context_.get()) { context_ = gfx::GLContext::CreateGLContext( - share_group.get(), surface_.get(), gpu_preference); + share_group.get(), surface_.get(), params.gpu_preference); share_group->SetSharedContext(context_.get()); } context_ = new GLContextVirtual( share_group.get(), context_.get(), decoder_->AsWeakPtr()); - if (context_->Initialize(surface_.get(), gpu_preference)) { + if (context_->Initialize(surface_.get(), params.gpu_preference)) { VLOG(1) << "Created virtual GL context."; } else { context_ = NULL; } } else { context_ = gfx::GLContext::CreateGLContext( - share_group.get(), surface_.get(), gpu_preference); + share_group.get(), surface_.get(), params.gpu_preference); } if (!context_.get()) { @@ -455,22 +464,30 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( } gles2::DisallowedFeatures disallowed_features; - disallowed_features.swap_buffer_complete_callback = true; disallowed_features.gpu_memory_manager = true; if (!decoder_->Initialize(surface_, context_, - is_offscreen, - size, + params.is_offscreen, + params.size, disallowed_features, - attribs)) { + params.attribs)) { LOG(ERROR) << "Could not initialize decoder."; DestroyOnGpuThread(); return false; } - if (!is_offscreen) { + gpu_control_.reset( + new GpuControlService(decoder_->GetContextGroup()->image_manager(), + g_gpu_memory_buffer_factory, + decoder_->GetContextGroup()->mailbox_manager(), + decoder_->GetQueryManager(), + decoder_->GetCapabilities())); + + *params.capabilities = gpu_control_->GetCapabilities(); + + if (!params.is_offscreen) { decoder_->SetResizeCallback(base::Bind( - &InProcessCommandBuffer::OnResizeView, base::Unretained(this))); + &InProcessCommandBuffer::OnResizeView, gpu_thread_weak_ptr_)); } if (share_resources_) { @@ -482,6 +499,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( void InProcessCommandBuffer::Destroy() { CheckSequencedThread(); + base::WaitableEvent completion(true, false); bool result = false; base::Callback<bool(void)> destroy_task = base::Bind( @@ -493,6 +511,7 @@ void InProcessCommandBuffer::Destroy() { bool InProcessCommandBuffer::DestroyOnGpuThread() { CheckSequencedThread(); + gpu_thread_weak_ptr_factory_.InvalidateWeakPtrs(); command_buffer_.reset(); // Clean up GL resources if possible. bool have_context = context_ && context_->MakeCurrent(surface_); @@ -566,6 +585,26 @@ void InProcessCommandBuffer::FlushOnGpuThread(int32 put_offset) { } DCHECK((!error::IsError(state_after_last_flush_.error) && !context_lost_) || (error::IsError(state_after_last_flush_.error) && context_lost_)); + + // If we've processed all pending commands but still have pending queries, + // pump idle work until the query is passed. + if (put_offset == state_after_last_flush_.get_offset && + gpu_scheduler_->HasMoreWork()) { + queue_->ScheduleIdleWork( + base::Bind(&InProcessCommandBuffer::ScheduleMoreIdleWork, + gpu_thread_weak_ptr_)); + } +} + +void InProcessCommandBuffer::ScheduleMoreIdleWork() { + CheckSequencedThread(); + base::AutoLock lock(command_buffer_lock_); + if (gpu_scheduler_->HasMoreWork()) { + gpu_scheduler_->PerformIdleWork(); + queue_->ScheduleIdleWork( + base::Bind(&InProcessCommandBuffer::ScheduleMoreIdleWork, + gpu_thread_weak_ptr_)); + } } void InProcessCommandBuffer::Flush(int32 put_offset) { @@ -578,7 +617,7 @@ void InProcessCommandBuffer::Flush(int32 put_offset) { last_put_offset_ = put_offset; base::Closure task = base::Bind(&InProcessCommandBuffer::FlushOnGpuThread, - base::Unretained(this), + gpu_thread_weak_ptr_, put_offset); QueueTask(task); } @@ -637,14 +676,8 @@ gpu::Buffer InProcessCommandBuffer::GetTransferBuffer(int32 id) { return gpu::Buffer(); } -uint32 InProcessCommandBuffer::InsertSyncPoint() { - NOTREACHED(); - return 0; -} -void InProcessCommandBuffer::SignalSyncPoint(unsigned sync_point, - const base::Closure& callback) { - CheckSequencedThread(); - QueueTask(WrapCallback(callback)); +gpu::Capabilities InProcessCommandBuffer::GetCapabilities() { + return capabilities_; } gfx::GpuMemoryBuffer* InProcessCommandBuffer::CreateGpuMemoryBuffer( @@ -669,6 +702,42 @@ void InProcessCommandBuffer::DestroyGpuMemoryBuffer(int32 id) { QueueTask(task); } +bool InProcessCommandBuffer::GenerateMailboxNames( + unsigned num, std::vector<gpu::Mailbox>* names) { + CheckSequencedThread(); + base::AutoLock lock(command_buffer_lock_); + return gpu_control_->GenerateMailboxNames(num, names); +} + +uint32 InProcessCommandBuffer::InsertSyncPoint() { + return 0; +} + +void InProcessCommandBuffer::SignalSyncPoint(unsigned sync_point, + const base::Closure& callback) { + CheckSequencedThread(); + QueueTask(WrapCallback(callback)); +} + +void InProcessCommandBuffer::SignalQuery(unsigned query, + const base::Closure& callback) { + CheckSequencedThread(); + QueueTask(base::Bind(&GpuControl::SignalQuery, + base::Unretained(gpu_control_.get()), + query, + WrapCallback(callback))); +} + +void InProcessCommandBuffer::SetSurfaceVisible(bool visible) {} + +void InProcessCommandBuffer::SendManagedMemoryStats( + const gpu::ManagedMemoryStats& stats) { +} + +void InProcessCommandBuffer::Echo(const base::Closure& callback) { + QueueTask(WrapCallback(callback)); +} + gpu::error::Error InProcessCommandBuffer::GetLastError() { CheckSequencedThread(); return last_state_.error; diff --git a/chromium/gpu/command_buffer/service/in_process_command_buffer.h b/chromium/gpu/command_buffer/service/in_process_command_buffer.h index e63e11aeac7..b00f25be97e 100644 --- a/chromium/gpu/command_buffer/service/in_process_command_buffer.h +++ b/chromium/gpu/command_buffer/service/in_process_command_buffer.h @@ -11,6 +11,7 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "gpu/command_buffer/common/command_buffer.h" @@ -87,8 +88,6 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, const base::Closure& context_lost_callback, unsigned int share_group_id); void Destroy(); - void SignalSyncPoint(unsigned sync_point, - const base::Closure& callback); // CommandBuffer implementation: virtual bool Initialize() OVERRIDE; @@ -106,22 +105,39 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, virtual void SetParseError(gpu::error::Error error) OVERRIDE; virtual void SetContextLostReason( gpu::error::ContextLostReason reason) OVERRIDE; - virtual uint32 InsertSyncPoint() OVERRIDE; virtual gpu::error::Error GetLastError() OVERRIDE; // GpuControl implementation: + virtual gpu::Capabilities GetCapabilities() OVERRIDE; virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer( size_t width, size_t height, unsigned internalformat, int32* id) OVERRIDE; virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE; + virtual bool GenerateMailboxNames(unsigned num, + std::vector<gpu::Mailbox>* names) OVERRIDE; + virtual uint32 InsertSyncPoint() OVERRIDE; + virtual void SignalSyncPoint(uint32 sync_point, + const base::Closure& callback) OVERRIDE; + virtual void SignalQuery(uint32 query, + const base::Closure& callback) OVERRIDE; + virtual void SetSurfaceVisible(bool visible) OVERRIDE; + virtual void SendManagedMemoryStats(const gpu::ManagedMemoryStats& stats) + OVERRIDE; + virtual void Echo(const base::Closure& callback) OVERRIDE; // The serializer interface to the GPU service (i.e. thread). class SchedulerClient { public: virtual ~SchedulerClient() {} + + // Queues a task to run as soon as possible. virtual void QueueTask(const base::Closure& task) = 0; + + // Schedules |callback| to run at an appropriate time for performing idle + // work. + virtual void ScheduleIdleWork(const base::Closure& task) = 0; }; #if defined(OS_ANDROID) @@ -130,11 +146,29 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, #endif private: - bool InitializeOnGpuThread(bool is_offscreen, - gfx::AcceleratedWidget window, - const gfx::Size& size, - const std::vector<int32>& attribs, - gfx::GpuPreference gpu_preference); + struct InitializeOnGpuThreadParams { + bool is_offscreen; + gfx::AcceleratedWidget window; + const gfx::Size& size; + const std::vector<int32>& attribs; + gfx::GpuPreference gpu_preference; + gpu::Capabilities* capabilities; // Ouptut. + + InitializeOnGpuThreadParams(bool is_offscreen, + gfx::AcceleratedWidget window, + const gfx::Size& size, + const std::vector<int32>& attribs, + gfx::GpuPreference gpu_preference, + gpu::Capabilities* capabilities) + : is_offscreen(is_offscreen), + window(window), + size(size), + attribs(attribs), + gpu_preference(gpu_preference), + capabilities(capabilities) {} + }; + + bool InitializeOnGpuThread(const InitializeOnGpuThreadParams& params); bool DestroyOnGpuThread(); void FlushOnGpuThread(int32 put_offset); bool MakeCurrent(); @@ -149,6 +183,7 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, void OnResizeView(gfx::Size size, float scale_factor); bool GetBufferChanged(int32 transfer_buffer_id); void PumpCommands(); + void ScheduleMoreIdleWork(); // Members accessed on the gpu thread (possibly with the exception of // creation): @@ -165,6 +200,7 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, // Members accessed on the client thread: State last_state_; int32 last_put_offset_; + gpu::Capabilities capabilities_; // Accessed on both threads: scoped_ptr<CommandBuffer> command_buffer_; @@ -183,6 +219,9 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, // the client thread. scoped_ptr<base::SequenceChecker> sequence_checker_; + base::WeakPtr<InProcessCommandBuffer> gpu_thread_weak_ptr_; + base::WeakPtrFactory<InProcessCommandBuffer> gpu_thread_weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(InProcessCommandBuffer); }; diff --git a/chromium/gpu/command_buffer/service/program_manager.cc b/chromium/gpu/command_buffer/service/program_manager.cc index 0fb6ab32045..d6e121a5da6 100644 --- a/chromium/gpu/command_buffer/service/program_manager.cc +++ b/chromium/gpu/command_buffer/service/program_manager.cc @@ -18,7 +18,6 @@ #include "base/time/time.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/program_cache.h" @@ -68,21 +67,6 @@ int ShaderTypeToIndex(GLenum shader_type) { } } -ShaderTranslator* ShaderIndexToTranslator( - int index, - ShaderTranslator* vertex_translator, - ShaderTranslator* fragment_translator) { - switch (index) { - case 0: - return vertex_translator; - case 1: - return fragment_translator; - default: - NOTREACHED(); - return NULL; - } -} - // Given a name like "foo.bar[123].moo[456]" sets new_name to "foo.bar[123].moo" // and sets element_index to 456. returns false if element expression was not a // whole decimal number. For example: "foo[1b2]" @@ -391,7 +375,7 @@ void Program::Update() { name_buffer.reset(new char[max_len]); // Reads all the names. - std::vector<UniformData> uniform_data_; + std::vector<UniformData> uniform_data; for (GLint ii = 0; ii < num_uniforms; ++ii) { GLsizei length = 0; UniformData data; @@ -405,7 +389,7 @@ void Program::Update() { GetCorrectedVariableInfo( true, name_buffer.get(), &data.corrected_name, &data.original_name, &data.size, &data.type); - uniform_data_.push_back(data); + uniform_data.push_back(data); } } @@ -419,8 +403,8 @@ void Program::Update() { // Assigns the uniforms with bindings. size_t next_available_index = 0; - for (size_t ii = 0; ii < uniform_data_.size(); ++ii) { - UniformData& data = uniform_data_[ii]; + for (size_t ii = 0; ii < uniform_data.size(); ++ii) { + UniformData& data = uniform_data[ii]; data.location = glGetUniformLocation( service_id_, data.queried_name.c_str()); // remove "[0]" @@ -439,8 +423,8 @@ void Program::Update() { } // Assigns the uniforms that were not bound. - for (size_t ii = 0; ii < uniform_data_.size(); ++ii) { - const UniformData& data = uniform_data_[ii]; + for (size_t ii = 0; ii < uniform_data.size(); ++ii) { + const UniformData& data = uniform_data[ii]; if (!data.added) { AddUniformInfo( data.size, data.type, data.location, -1, data.corrected_name, @@ -476,9 +460,10 @@ void Program::ExecuteBindAttribLocationCalls() { } } -void ProgramManager::DoCompileShader(Shader* shader, - ShaderTranslator* translator, - FeatureInfo* feature_info) { +void ProgramManager::DoCompileShader( + Shader* shader, + ShaderTranslator* translator, + ProgramManager::TranslatedShaderSourceType translated_shader_source_type) { // Translate GL ES 2.0 shader to Desktop GL shader and pass that to // glShaderSource and then glCompileShader. const std::string* source = shader->source(); @@ -489,13 +474,13 @@ void ProgramManager::DoCompileShader(Shader* shader, return; } shader_src = translator->translated_shader(); - if (!feature_info->feature_flags().angle_translated_shader_source) + if (translated_shader_source_type != kANGLE) shader->UpdateTranslatedSource(shader_src); } glShaderSource(shader->service_id(), 1, &shader_src, NULL); glCompileShader(shader->service_id()); - if (feature_info->feature_flags().angle_translated_shader_source) { + if (translated_shader_source_type == kANGLE) { GLint max_len = 0; glGetShaderiv(shader->service_id(), GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, @@ -537,7 +522,7 @@ void ProgramManager::DoCompileShader(Shader* shader, bool Program::Link(ShaderManager* manager, ShaderTranslator* vertex_translator, ShaderTranslator* fragment_translator, - FeatureInfo* feature_info, + Program::VaryingsPackingOption varyings_packing_option, const ShaderCacheCallback& shader_callback) { ClearLinkStatus(); if (!CanLink()) { @@ -562,7 +547,7 @@ bool Program::Link(ShaderManager* manager, set_log_info("Name conflicts between an uniform and an attribute"); return false; } - if (!CheckVaryingsPacking()) { + if (!CheckVaryingsPacking(varyings_packing_option)) { set_log_info("Varyings over maximum register limit"); return false; } @@ -672,6 +657,9 @@ GLint Program::GetUniformFakeLocation( if (open_pos_2 == open_pos && name.compare(0, open_pos, info.name, 0, open_pos) == 0) { if (index >= 0 && index < info.size) { + DCHECK_GT(static_cast<int>(info.element_locations.size()), index); + if (info.element_locations[index] == -1) + return -1; return ProgramManager::MakeFakeLocation( info.fake_location_base, index); } @@ -1097,7 +1085,8 @@ bool Program::DetectGlobalNameConflicts() const { return false; } -bool Program::CheckVaryingsPacking() const { +bool Program::CheckVaryingsPacking( + Program::VaryingsPackingOption option) const { DCHECK(attached_shaders_[0] && attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER && attached_shaders_[1] && @@ -1112,13 +1101,14 @@ bool Program::CheckVaryingsPacking() const { for (ShaderTranslator::VariableMap::const_iterator iter = fragment_varyings->begin(); iter != fragment_varyings->end(); ++iter) { - if (!iter->second.static_use) + if (!iter->second.static_use && option == kCountOnlyStaticallyUsed) continue; if (!IsBuiltInVarying(iter->first)) { ShaderTranslator::VariableMap::const_iterator vertex_iter = vertex_varyings->find(iter->first); if (vertex_iter == vertex_varyings->end() || - !vertex_iter->second.static_use) + (!vertex_iter->second.static_use && + option == kCountOnlyStaticallyUsed)) continue; } @@ -1221,7 +1211,10 @@ void Program::GetProgramInfo( inputs->name_length = info.name.size(); DCHECK(static_cast<size_t>(info.size) == info.element_locations.size()); for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { - *locations++ = ProgramManager::MakeFakeLocation(ii, jj); + if (info.element_locations[jj] == -1) + *locations++ = -1; + else + *locations++ = ProgramManager::MakeFakeLocation(ii, jj); } memcpy(strings, info.name.c_str(), info.name.size()); strings += info.name.size(); @@ -1247,9 +1240,6 @@ ProgramManager::ProgramManager(ProgramCache* program_cache, uint32 max_varying_vectors) : program_count_(0), have_context_(true), - disable_workarounds_( - CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableGpuDriverBugWorkarounds)), program_cache_(program_cache), max_varying_vectors_(max_varying_vectors) { } @@ -1344,7 +1334,6 @@ void ProgramManager::UseProgram(Program* program) { DCHECK(program); DCHECK(IsOwned(program)); program->IncUseCount(); - ClearUniforms(program); } void ProgramManager::UnuseProgram( @@ -1359,9 +1348,7 @@ void ProgramManager::UnuseProgram( void ProgramManager::ClearUniforms(Program* program) { DCHECK(program); - if (!disable_workarounds_) { - program->ClearUniforms(&zero_); - } + program->ClearUniforms(&zero_); } int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { diff --git a/chromium/gpu/command_buffer/service/program_manager.h b/chromium/gpu/command_buffer/service/program_manager.h index 258a3c3cf5f..50dd0ff1b80 100644 --- a/chromium/gpu/command_buffer/service/program_manager.h +++ b/chromium/gpu/command_buffer/service/program_manager.h @@ -20,7 +20,6 @@ namespace gpu { namespace gles2 { -class FeatureInfo; class ProgramCache; class ProgramManager; class Shader; @@ -34,6 +33,11 @@ class GPU_EXPORT Program : public base::RefCounted<Program> { public: static const int kMaxAttachedShaders = 2; + enum VaryingsPackingOption { + kCountOnlyStaticallyUsed, + kCountAll + }; + struct UniformInfo { UniformInfo(); UniformInfo( @@ -157,7 +161,7 @@ class GPU_EXPORT Program : public base::RefCounted<Program> { bool Link(ShaderManager* manager, ShaderTranslator* vertex_translator, ShaderTranslator* fragment_shader, - FeatureInfo* feature_info, + VaryingsPackingOption varyings_packing_option, const ShaderCacheCallback& shader_callback); // Performs glValidateProgram and related activities. @@ -200,7 +204,7 @@ class GPU_EXPORT Program : public base::RefCounted<Program> { // Return false if varyings can't be packed into the max available // varying registers. - bool CheckVaryingsPacking() const; + bool CheckVaryingsPacking(VaryingsPackingOption option) const; // Visible for testing const LocationMap& bind_attrib_location_map() const { @@ -336,6 +340,11 @@ class GPU_EXPORT Program : public base::RefCounted<Program> { // need to be shared by multiple GLES2Decoders. class GPU_EXPORT ProgramManager { public: + enum TranslatedShaderSourceType { + kANGLE, + kGL, // GL or GLES + }; + explicit ProgramManager(ProgramCache* program_cache, uint32 max_varying_vectors); ~ProgramManager(); @@ -375,9 +384,10 @@ class GPU_EXPORT ProgramManager { static int32 MakeFakeLocation(int32 index, int32 element); - void DoCompileShader(Shader* shader, - ShaderTranslator* translator, - FeatureInfo* feature_info); + void DoCompileShader( + Shader* shader, + ShaderTranslator* translator, + TranslatedShaderSourceType translated_shader_source_type); uint32 max_varying_vectors() const { return max_varying_vectors_; @@ -403,8 +413,6 @@ class GPU_EXPORT ProgramManager { bool have_context_; - bool disable_workarounds_; - // Used to clear uniforms. std::vector<uint8> zero_; diff --git a/chromium/gpu/command_buffer/service/program_manager_unittest.cc b/chromium/gpu/command_buffer/service/program_manager_unittest.cc index 43217f45212..0823d096452 100644 --- a/chromium/gpu/command_buffer/service/program_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/program_manager_unittest.cc @@ -250,7 +250,8 @@ class ProgramManagerWithShaderTest : public testing::Test { program_->AttachShader(&shader_manager_, vertex_shader); program_->AttachShader(&shader_manager_, fragment_shader); - program_->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb)); + program_->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + base::Bind(&ShaderCacheCb)); } void SetupShader(AttribInfo* attribs, size_t num_attribs, @@ -283,7 +284,8 @@ class ProgramManagerWithShaderTest : public testing::Test { SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, service_id); } - program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb)); + program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + base::Bind(&ShaderCacheCb)); GLint link_status; program->GetProgramiv(GL_LINK_STATUS, &link_status); return (static_cast<bool>(link_status) == expected_link_status); @@ -608,12 +610,19 @@ TEST_F(ProgramManagerWithShaderTest, AttachDetachShader) { TEST_F(ProgramManagerWithShaderTest, GetUniformFakeLocation) { const Program* program = manager_.GetProgram(kClientProgramId); ASSERT_TRUE(program != NULL); + // Emulate the situation that uniform3[1] isn't used and optimized out by + // a driver, so it's location is -1. + Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>( + program->GetUniformInfo(2)); + ASSERT_TRUE(uniform != NULL && kUniform3Size == 2); + EXPECT_EQ(kUniform3Size, uniform->size); + uniform->element_locations[1] = -1; EXPECT_EQ(kUniform1FakeLocation, program->GetUniformFakeLocation(kUniform1Name)); EXPECT_EQ(kUniform2FakeLocation, program->GetUniformFakeLocation(kUniform2Name)); EXPECT_EQ(kUniform3FakeLocation, - program->GetUniformFakeLocation(kUniform3BadName)); + program->GetUniformFakeLocation(kUniform3BadName)); // Check we can get uniform2 as "uniform2" even though the name is // "uniform2[0]" EXPECT_EQ(kUniform2FakeLocation, @@ -628,8 +637,7 @@ TEST_F(ProgramManagerWithShaderTest, GetUniformFakeLocation) { EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation, 2), program->GetUniformFakeLocation("uniform2[2]")); EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform2[3]")); - EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform3FakeLocation, 1), - program->GetUniformFakeLocation("uniform3[1]")); + EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform3[1]")); EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform3[2]")); } @@ -714,7 +722,8 @@ TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsGLUnderscoreUniform) { ASSERT_TRUE(program != NULL); EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader)); EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader)); - program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb)); + program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + base::Bind(&ShaderCacheCb)); GLint value = 0; program->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value); EXPECT_EQ(3, value); @@ -782,7 +791,8 @@ TEST_F(ProgramManagerWithShaderTest, SimilarArrayNames) { ASSERT_TRUE(program != NULL); EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader)); EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader)); - program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb)); + program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + base::Bind(&ShaderCacheCb)); // Check that we get the correct locations. EXPECT_EQ(kUniform2FakeLocation, @@ -883,7 +893,8 @@ TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) { ASSERT_TRUE(program!= NULL); EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader)); EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader)); - program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb)); + program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + base::Bind(&ShaderCacheCb)); // Check that we got the good type, not the bad. // Check Attribs for (unsigned index = 0; index < kNumAttribs; ++index) { @@ -1067,6 +1078,50 @@ TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetProgramInfo) { static_cast<uint32>(input - inputs)); } +// Some drivers optimize out unused uniform array elements, so their +// location would be -1. +TEST_F(ProgramManagerWithShaderTest, UnusedUniformArrayElements) { + CommonDecoder::Bucket bucket; + const Program* program = manager_.GetProgram(kClientProgramId); + ASSERT_TRUE(program != NULL); + // Emulate the situation that only the first element has a valid location. + // TODO(zmo): Don't assume these are in order. + for (size_t ii = 0; ii < arraysize(kUniforms); ++ii) { + Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>( + program->GetUniformInfo(ii)); + ASSERT_TRUE(uniform != NULL); + EXPECT_EQ(static_cast<size_t>(kUniforms[ii].size), + uniform->element_locations.size()); + for (GLsizei jj = 1; jj < uniform->size; ++jj) + uniform->element_locations[jj] = -1; + } + program->GetProgramInfo(&manager_, &bucket); + ProgramInfoHeader* header = + bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader)); + ASSERT_TRUE(header != NULL); + EXPECT_EQ(1u, header->link_status); + EXPECT_EQ(arraysize(kAttribs), header->num_attribs); + EXPECT_EQ(arraysize(kUniforms), header->num_uniforms); + const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>( + sizeof(*header), + sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms)); + ASSERT_TRUE(inputs != NULL); + const ProgramInput* input = inputs + header->num_attribs; + for (uint32 ii = 0; ii < header->num_uniforms; ++ii) { + const UniformInfo& expected = kUniforms[ii]; + EXPECT_EQ(expected.size, input->size); + const int32* locations = bucket.GetDataAs<const int32*>( + input->location_offset, sizeof(int32) * input->size); + ASSERT_TRUE(locations != NULL); + EXPECT_EQ( + ProgramManager::MakeFakeLocation(expected.fake_location, 0), + locations[0]); + for (int32 jj = 1; jj < input->size; ++jj) + EXPECT_EQ(-1, locations[jj]); + ++input; + } +} + TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) { // Set up shader const GLuint kVShaderClientId = 1; @@ -1304,7 +1359,8 @@ TEST_F(ProgramManagerWithShaderTest, TooManyVaryings) { Program* program = SetupShaderVariableTest( kVertexVaryings, 2, kFragmentVaryings, 2); - EXPECT_FALSE(program->CheckVaryingsPacking()); + EXPECT_FALSE( + program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed)); EXPECT_TRUE(LinkAsExpected(program, false)); } @@ -1321,10 +1377,28 @@ TEST_F(ProgramManagerWithShaderTest, TooManyInactiveVaryings) { Program* program = SetupShaderVariableTest( kVertexVaryings, 2, kFragmentVaryings, 2); - EXPECT_TRUE(program->CheckVaryingsPacking()); + EXPECT_TRUE( + program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed)); EXPECT_TRUE(LinkAsExpected(program, true)); } +// Varyings go over 8 rows but some are inactive. +// However, we still fail the check if kCountAll option is used. +TEST_F(ProgramManagerWithShaderTest, CountAllVaryingsInPacking) { + const VarInfo kVertexVaryings[] = { + { SH_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying }, + { SH_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying } + }; + const VarInfo kFragmentVaryings[] = { + { SH_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 0, "a", kVarVarying }, + { SH_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying } + }; + Program* program = SetupShaderVariableTest( + kVertexVaryings, 2, kFragmentVaryings, 2); + + EXPECT_FALSE(program->CheckVaryingsPacking(Program::kCountAll)); +} + TEST_F(ProgramManagerWithShaderTest, ClearWithSamplerTypes) { const GLuint kVShaderClientId = 2001; const GLuint kFShaderClientId = 2002; @@ -1390,7 +1464,8 @@ TEST_F(ProgramManagerWithShaderTest, ClearWithSamplerTypes) { const size_t kNumUniforms = arraysize(kUniforms); SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId); - program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb)); + program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + base::Bind(&ShaderCacheCb)); SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms); manager_.ClearUniforms(program); } @@ -1462,7 +1537,8 @@ TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) { const size_t kNumUniforms = arraysize(kUniforms); SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId); - program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb)); + program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed, + base::Bind(&ShaderCacheCb)); EXPECT_EQ(kUniform1DesiredLocation, program->GetUniformFakeLocation(kUniform1Name)); @@ -1685,8 +1761,8 @@ TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) { SetShadersCompiled(); SetExpectationsForProgramLink(); SetExpectationsForProgramCached(); - EXPECT_TRUE(program_->Link(NULL, NULL, NULL, NULL, - base::Bind(&ShaderCacheCb))); + EXPECT_TRUE(program_->Link(NULL, NULL, NULL, + Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb))); } TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) { @@ -1699,8 +1775,8 @@ TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) { SetExpectationsForNotCachingProgram(); SetExpectationsForProgramLoadSuccess(); - EXPECT_TRUE(program_->Link(NULL, NULL, NULL, NULL, - base::Bind(&ShaderCacheCb))); + EXPECT_TRUE(program_->Link(NULL, NULL, NULL, + Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb))); } } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/shader_translator.h b/chromium/gpu/command_buffer/service/shader_translator.h index 322cb6b2896..b9bacf155e6 100644 --- a/chromium/gpu/command_buffer/service/shader_translator.h +++ b/chromium/gpu/command_buffer/service/shader_translator.h @@ -13,7 +13,7 @@ #include "base/memory/scoped_ptr.h" #include "base/observer_list.h" #include "gpu/gpu_export.h" -#include "third_party/angle_dx11/include/GLSLANG/ShaderLang.h" +#include "third_party/angle/include/GLSLANG/ShaderLang.h" namespace gpu { namespace gles2 { diff --git a/chromium/gpu/command_buffer/service/shader_translator_cache.h b/chromium/gpu/command_buffer/service/shader_translator_cache.h index 551522bdbc4..8439d533987 100644 --- a/chromium/gpu/command_buffer/service/shader_translator_cache.h +++ b/chromium/gpu/command_buffer/service/shader_translator_cache.h @@ -12,7 +12,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/singleton.h" #include "gpu/command_buffer/service/shader_translator.h" -#include "third_party/angle_dx11/include/GLSLANG/ShaderLang.h" +#include "third_party/angle/include/GLSLANG/ShaderLang.h" namespace gpu { namespace gles2 { diff --git a/chromium/gpu/command_buffer/service/test_helper.cc b/chromium/gpu/command_buffer/service/test_helper.cc index 074e3019f8a..92c5ec456ef 100644 --- a/chromium/gpu/command_buffer/service/test_helper.cc +++ b/chromium/gpu/command_buffer/service/test_helper.cc @@ -235,10 +235,15 @@ void TestHelper::SetupContextGroupInitExpectations( EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE, _)) .WillOnce(SetArgumentPointee<1>(kMaxRenderbufferSize)) .RetiresOnSaturation(); - if (strstr(extensions, "GL_EXT_framebuffer_multisample")) { + if (strstr(extensions, "GL_EXT_framebuffer_multisample") || + strstr(extensions, "GL_EXT_multisampled_render_to_texture")) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES, _)) .WillOnce(SetArgumentPointee<1>(kMaxSamples)) .RetiresOnSaturation(); + } else if (strstr(extensions, "GL_IMG_multisampled_render_to_texture")) { + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES_IMG, _)) + .WillOnce(SetArgumentPointee<1>(kMaxSamples)) + .RetiresOnSaturation(); } EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _)) .WillOnce(SetArgumentPointee<1>(kNumVertexAttribs)) @@ -273,20 +278,24 @@ void TestHelper::SetupContextGroupInitExpectations( void TestHelper::SetupFeatureInfoInitExpectations( ::gfx::MockGLInterface* gl, const char* extensions) { - SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, ""); + SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", ""); } void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( ::gfx::MockGLInterface* gl, const char* extensions, - const char* version) { + const char* gl_renderer, + const char* gl_version) { InSequence sequence; EXPECT_CALL(*gl, GetString(GL_EXTENSIONS)) .WillOnce(Return(reinterpret_cast<const uint8*>(extensions))) .RetiresOnSaturation(); + EXPECT_CALL(*gl, GetString(GL_RENDERER)) + .WillOnce(Return(reinterpret_cast<const uint8*>(gl_renderer))) + .RetiresOnSaturation(); EXPECT_CALL(*gl, GetString(GL_VERSION)) - .WillOnce(Return(reinterpret_cast<const uint8*>(version))) + .WillOnce(Return(reinterpret_cast<const uint8*>(gl_version))) .RetiresOnSaturation(); } diff --git a/chromium/gpu/command_buffer/service/test_helper.h b/chromium/gpu/command_buffer/service/test_helper.h index 11f7004a768..a619073878f 100644 --- a/chromium/gpu/command_buffer/service/test_helper.h +++ b/chromium/gpu/command_buffer/service/test_helper.h @@ -71,7 +71,8 @@ class TestHelper { static void SetupFeatureInfoInitExpectationsWithGLVersion( ::gfx::MockGLInterface* gl, const char* extensions, - const char* version); + const char* gl_renderer, + const char* gl_version); static void SetupTextureManagerInitExpectations( ::gfx::MockGLInterface* gl, const char* extensions); static void SetupTextureManagerDestructionExpectations( diff --git a/chromium/gpu/command_buffer/service/texture_manager.cc b/chromium/gpu/command_buffer/service/texture_manager.cc index deb8c8e6645..64ead827edd 100644 --- a/chromium/gpu/command_buffer/service/texture_manager.cc +++ b/chromium/gpu/command_buffer/service/texture_manager.cc @@ -80,6 +80,7 @@ TextureManager::~TextureManager() { DCHECK_EQ(0, num_unrenderable_textures_); DCHECK_EQ(0, num_unsafe_textures_); DCHECK_EQ(0, num_uncleared_mips_); + DCHECK_EQ(0, num_images_); } void TextureManager::Destroy(bool have_context) { @@ -118,6 +119,7 @@ Texture::Texture(GLuint service_id) framebuffer_attachment_count_(0), stream_texture_(false), immutable_(false), + has_images_(false), estimated_size_(0), can_render_condition_(CAN_RENDER_ALWAYS) { } @@ -198,11 +200,7 @@ Texture::CanRenderCondition Texture::GetCanRenderCondition() const { if (target_ == 0) return CAN_RENDER_ALWAYS; - if (target_ == GL_TEXTURE_EXTERNAL_OES) { - if (!IsStreamTexture()) { - return CAN_RENDER_NEVER; - } - } else { + if (target_ != GL_TEXTURE_EXTERNAL_OES) { if (level_infos_.empty()) { return CAN_RENDER_NEVER; } @@ -294,7 +292,8 @@ bool Texture::MarkMipmapsGenerated( GLsizei depth = info1.depth; GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D : FaceIndexToGLTarget(ii); - int num_mips = TextureManager::ComputeMipMapCount(width, height, depth); + int num_mips = + TextureManager::ComputeMipMapCount(target_, width, height, depth); for (int level = 1; level < num_mips; ++level) { width = std::max(1, width >> 1); height = std::max(1, height >> 1); @@ -390,7 +389,7 @@ void Texture::UpdateCleared() { const Texture::LevelInfo& first_face = level_infos_[0][0]; int levels_needed = TextureManager::ComputeMipMapCount( - first_face.width, first_face.height, first_face.depth); + target_, first_face.width, first_face.height, first_face.depth); bool cleared = true; for (size_t ii = 0; ii < level_infos_.size(); ++ii) { for (GLint jj = 0; jj < levels_needed; ++jj) { @@ -434,6 +433,29 @@ void Texture::UpdateCanRenderCondition() { can_render_condition_ = can_render_condition; } +void Texture::UpdateHasImages() { + if (level_infos_.empty()) + return; + + bool has_images = false; + for (size_t ii = 0; ii < level_infos_.size(); ++ii) { + for (size_t jj = 0; jj < level_infos_[ii].size(); ++jj) { + const Texture::LevelInfo& info = level_infos_[ii][jj]; + if (info.image.get() != NULL) { + has_images = true; + break; + } + } + } + + if (has_images_ == has_images) + return; + has_images_ = has_images; + int delta = has_images ? +1 : -1; + for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) + (*it)->manager()->UpdateNumImages(delta); +} + void Texture::IncAllFramebufferStateChangeCount() { for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) (*it)->manager()->IncFramebufferStateChangeCount(); @@ -482,6 +504,7 @@ void Texture::SetLevelInfo( Update(feature_info); UpdateCleared(); UpdateCanRenderCondition(); + UpdateHasImages(); if (IsAttachedToFramebuffer()) { // TODO(gman): If textures tracked which framebuffers they were attached to // we could just mark those framebuffers as not complete. @@ -643,7 +666,7 @@ void Texture::Update(const FeatureInfo* feature_info) { // Update texture_complete and cube_complete status. const Texture::LevelInfo& first_face = level_infos_[0][0]; int levels_needed = TextureManager::ComputeMipMapCount( - first_face.width, first_face.height, first_face.depth); + target_, first_face.width, first_face.height, first_face.depth); texture_complete_ = max_level_set_ >= (levels_needed - 1) && max_level_set_ >= 0; cube_complete_ = (level_infos_.size() == 6) && @@ -708,7 +731,7 @@ bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) { const Texture::LevelInfo& first_face = level_infos_[0][0]; int levels_needed = TextureManager::ComputeMipMapCount( - first_face.width, first_face.height, first_face.depth); + target_, first_face.width, first_face.height, first_face.depth); for (size_t ii = 0; ii < level_infos_.size(); ++ii) { for (GLint jj = 0; jj < levels_needed; ++jj) { @@ -783,10 +806,10 @@ void Texture::SetLevelImage( DCHECK_EQ(info.level, level); info.image = image; UpdateCanRenderCondition(); + UpdateHasImages(); } -gfx::GLImage* Texture::GetLevelImage( - GLint target, GLint level) const { +gfx::GLImage* Texture::GetLevelImage(GLint target, GLint level) const { size_t face_index = GLTargetToFaceIndex(target); if (level >= 0 && face_index < level_infos_.size() && static_cast<size_t>(level) < level_infos_[face_index].size()) { @@ -824,13 +847,12 @@ TextureRef::~TextureRef() { manager_ = NULL; } -TextureManager::TextureManager( - MemoryTracker* memory_tracker, - FeatureInfo* feature_info, - GLint max_texture_size, - GLint max_cube_map_texture_size) - : memory_tracker_managed_( - new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)), +TextureManager::TextureManager(MemoryTracker* memory_tracker, + FeatureInfo* feature_info, + GLint max_texture_size, + GLint max_cube_map_texture_size) + : memory_tracker_managed_(new MemoryTypeTracker(memory_tracker, + MemoryTracker::kManaged)), memory_tracker_unmanaged_( new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)), feature_info_(feature_info), @@ -838,15 +860,18 @@ TextureManager::TextureManager( stream_texture_manager_(NULL), max_texture_size_(max_texture_size), max_cube_map_texture_size_(max_cube_map_texture_size), - max_levels_(ComputeMipMapCount(max_texture_size, + max_levels_(ComputeMipMapCount(GL_TEXTURE_2D, + max_texture_size, max_texture_size, max_texture_size)), - max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size, + max_cube_map_levels_(ComputeMipMapCount(GL_TEXTURE_CUBE_MAP, + max_cube_map_texture_size, max_cube_map_texture_size, max_cube_map_texture_size)), num_unrenderable_textures_(0), num_unsafe_textures_(0), num_uncleared_mips_(0), + num_images_(0), texture_count_(0), have_context_(true) { for (int ii = 0; ii < kNumDefaultTextures; ++ii) { @@ -1132,6 +1157,8 @@ void TextureManager::StartTracking(TextureRef* ref) { ++num_unsafe_textures_; if (!texture->CanRender(feature_info_.get())) ++num_unrenderable_textures_; + if (texture->HasImages()) + ++num_images_; } void TextureManager::StopTracking(TextureRef* ref) { @@ -1146,6 +1173,10 @@ void TextureManager::StopTracking(TextureRef* ref) { } --texture_count_; + if (texture->HasImages()) { + DCHECK_NE(0, num_images_); + --num_images_; + } if (!texture->CanRender(feature_info_.get())) { DCHECK_NE(0, num_unrenderable_textures_); --num_unrenderable_textures_; @@ -1184,9 +1215,17 @@ Texture* TextureManager::GetTextureForServiceId(GLuint service_id) const { return NULL; } -GLsizei TextureManager::ComputeMipMapCount( - GLsizei width, GLsizei height, GLsizei depth) { - return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth)); +GLsizei TextureManager::ComputeMipMapCount(GLenum target, + GLsizei width, + GLsizei height, + GLsizei depth) { + switch (target) { + case GL_TEXTURE_EXTERNAL_OES: + return 1; + default: + return 1 + + base::bits::Log2Floor(std::max(std::max(width, height), depth)); + } } void TextureManager::SetLevelImage( @@ -1231,10 +1270,14 @@ void TextureManager::UpdateCanRenderCondition( ++num_unrenderable_textures_; } +void TextureManager::UpdateNumImages(int delta) { + num_images_ += delta; + DCHECK_GE(num_images_, 0); +} + void TextureManager::IncFramebufferStateChangeCount() { if (framebuffer_manager_) framebuffer_manager_->IncFramebufferStateChangeCount(); - } bool TextureManager::ValidateTextureParameters( @@ -1429,7 +1472,7 @@ void TextureManager::DoTexImage2D( framebuffer_state->clear_state_dirty = true; } - if (!texture_state->teximage2d_faster_than_texsubimage2d && + if (texture_state->texsubimage2d_faster_than_teximage2d && level_is_same && args.pixels) { { ScopedTextureUploadTimer timer(texture_state); diff --git a/chromium/gpu/command_buffer/service/texture_manager.h b/chromium/gpu/command_buffer/service/texture_manager.h index db470045751..bd9e3dab410 100644 --- a/chromium/gpu/command_buffer/service/texture_manager.h +++ b/chromium/gpu/command_buffer/service/texture_manager.h @@ -114,6 +114,10 @@ class GPU_EXPORT Texture { // does not exist. gfx::GLImage* GetLevelImage(GLint target, GLint level) const; + bool HasImages() const { + return has_images_; + } + // Returns true of the given dimensions are inside the dimensions of the // level and if the format and type match the level. bool ValidForTexture( @@ -317,6 +321,10 @@ class GPU_EXPORT Texture { // texture. void UpdateCanRenderCondition(); + // Updates the images count in all the managers referencing this + // texture. + void UpdateHasImages(); + // Increment the framebuffer state change count in all the managers // referencing this texture. void IncAllFramebufferStateChangeCount(); @@ -378,6 +386,9 @@ class GPU_EXPORT Texture { // or dimensions of the texture object can be made. bool immutable_; + // Whether or not this texture has images. + bool has_images_; + // Size in bytes this texture is assumed to take in memory. uint32 estimated_size_; @@ -436,10 +447,11 @@ class GPU_EXPORT TextureRef : public base::RefCounted<TextureRef> { struct DecoderTextureState { // total_texture_upload_time automatically initialized to 0 in default // constructor. - DecoderTextureState(): - tex_image_2d_failed(false), - texture_upload_count(0), - teximage2d_faster_than_texsubimage2d(true) {} + DecoderTextureState(bool texsubimage2d_faster_than_teximage2d) + : tex_image_2d_failed(false), + texture_upload_count(0), + texsubimage2d_faster_than_teximage2d( + texsubimage2d_faster_than_teximage2d) {} // This indicates all the following texSubImage2D calls that are part of the // failed texImage2D call should be ignored. @@ -449,9 +461,7 @@ struct DecoderTextureState { int texture_upload_count; base::TimeDelta total_texture_upload_time; - // This is really not per-decoder, but the logic to decide this value is in - // the decoder for now, so it is simpler to leave it there. - bool teximage2d_faster_than_texsubimage2d; + bool texsubimage2d_faster_than_teximage2d; }; // This class keeps track of the textures and their sizes so we can do NPOT and @@ -528,8 +538,10 @@ class GPU_EXPORT TextureManager { } // Returns the maxium number of levels a texture of the given size can have. - static GLsizei ComputeMipMapCount( - GLsizei width, GLsizei height, GLsizei depth); + static GLsizei ComputeMipMapCount(GLenum target, + GLsizei width, + GLsizei height, + GLsizei depth); // Checks if a dimensions are valid for a given target. bool ValidForTarget( @@ -654,6 +666,10 @@ class GPU_EXPORT TextureManager { return num_uncleared_mips_ > 0; } + bool HaveImages() const { + return num_images_ > 0; + } + GLuint black_texture_id(GLenum target) const { switch (target) { case GL_SAMPLER_2D: @@ -756,6 +772,7 @@ class GPU_EXPORT TextureManager { void UpdateUnclearedMips(int delta); void UpdateCanRenderCondition(Texture::CanRenderCondition old_condition, Texture::CanRenderCondition new_condition); + void UpdateNumImages(int delta); void IncFramebufferStateChangeCount(); MemoryTypeTracker* GetMemTracker(GLenum texture_pool); @@ -779,6 +796,7 @@ class GPU_EXPORT TextureManager { int num_unrenderable_textures_; int num_unsafe_textures_; int num_uncleared_mips_; + int num_images_; // Counts the number of Textures allocated with 'this' as its manager. // Allows to check no Texture will outlive this. diff --git a/chromium/gpu/command_buffer/service/texture_manager_unittest.cc b/chromium/gpu/command_buffer/service/texture_manager_unittest.cc index 483aaf20fa6..312adfddbf3 100644 --- a/chromium/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/texture_manager_unittest.cc @@ -466,11 +466,9 @@ TEST_F(TextureTest, SetTargetTextureExternalOES) { EXPECT_FALSE(TextureTestHelper::IsCubeComplete(texture)); EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get())); EXPECT_TRUE(TextureTestHelper::IsNPOT(texture)); - EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); + EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); EXPECT_TRUE(texture->SafeToRenderFrom()); EXPECT_TRUE(texture->IsImmutable()); - manager_->SetStreamTexture(texture_ref_.get(), true); - EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); } TEST_F(TextureTest, ZeroSizeCanNotRender) { @@ -2002,6 +2000,26 @@ TEST_F(ProduceConsumeTextureTest, ProduceConsumeClearRectangle) { decoder_.get(), restored_texture.get(), GL_TEXTURE_RECTANGLE_ARB, 0)); } +TEST_F(ProduceConsumeTextureTest, ProduceConsumeExternal) { + manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_EXTERNAL_OES); + Texture* texture = texture_ref_->texture(); + EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), texture->target()); + LevelInfo level0( + GL_TEXTURE_EXTERNAL_OES, GL_RGBA, 1, 1, 1, 0, GL_UNSIGNED_BYTE, false); + SetLevelInfo(texture_ref_.get(), 0, level0); + EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); + Texture* produced_texture = Produce(texture_ref_.get()); + EXPECT_EQ(produced_texture, texture); + + GLuint client_id = texture2_->client_id(); + manager_->RemoveTexture(client_id); + Consume(client_id, produced_texture); + scoped_refptr<TextureRef> restored_texture = manager_->GetTexture(client_id); + EXPECT_EQ(produced_texture, restored_texture->texture()); + EXPECT_EQ(level0, + GetLevelInfo(restored_texture.get(), GL_TEXTURE_EXTERNAL_OES, 0)); +} + TEST_F(ProduceConsumeTextureTest, ProduceConsumeStreamTexture) { manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_EXTERNAL_OES); Texture* texture = texture_ref_->texture(); @@ -2349,5 +2367,65 @@ TEST_F(SharedTextureTest, Memory) { memory_tracker2_->GetSize(MemoryTracker::kUnmanaged)); } +TEST_F(SharedTextureTest, Images) { + scoped_refptr<TextureRef> ref1 = texture_manager1_->CreateTexture(10, 10); + scoped_refptr<TextureRef> ref2 = + texture_manager2_->Consume(20, ref1->texture()); + + texture_manager1_->SetTarget(ref1.get(), GL_TEXTURE_2D); + texture_manager1_->SetLevelInfo(ref1.get(), + GL_TEXTURE_2D, + 1, + GL_RGBA, + 2, + 2, + 1, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + true); + EXPECT_FALSE(ref1->texture()->HasImages()); + EXPECT_FALSE(ref2->texture()->HasImages()); + EXPECT_FALSE(texture_manager1_->HaveImages()); + EXPECT_FALSE(texture_manager2_->HaveImages()); + texture_manager1_->SetLevelImage(ref1.get(), + GL_TEXTURE_2D, + 1, + gfx::GLImage::CreateGLImage(0).get()); + EXPECT_TRUE(ref1->texture()->HasImages()); + EXPECT_TRUE(ref2->texture()->HasImages()); + EXPECT_TRUE(texture_manager1_->HaveImages()); + EXPECT_TRUE(texture_manager2_->HaveImages()); + texture_manager1_->SetLevelImage(ref1.get(), + GL_TEXTURE_2D, + 1, + gfx::GLImage::CreateGLImage(0).get()); + EXPECT_TRUE(ref1->texture()->HasImages()); + EXPECT_TRUE(ref2->texture()->HasImages()); + EXPECT_TRUE(texture_manager1_->HaveImages()); + EXPECT_TRUE(texture_manager2_->HaveImages()); + texture_manager1_->SetLevelInfo(ref1.get(), + GL_TEXTURE_2D, + 1, + GL_RGBA, + 2, + 2, + 1, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + true); + EXPECT_FALSE(ref1->texture()->HasImages()); + EXPECT_FALSE(ref2->texture()->HasImages()); + EXPECT_FALSE(texture_manager1_->HaveImages()); + EXPECT_FALSE(texture_manager1_->HaveImages()); + + EXPECT_CALL(*gl_, DeleteTextures(1, _)) + .Times(1) + .RetiresOnSaturation(); + texture_manager1_->RemoveTexture(10); + texture_manager2_->RemoveTexture(20); +} + } // namespace gles2 } // namespace gpu |