diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-30 18:35:59 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-30 18:35:59 +0000 |
commit | 4e46a73c1185a737a525585b25c5e27cb22e405e (patch) | |
tree | 105b1c4aedadf30271df1a74ef80a1622e0705bf | |
parent | 0a2686150c957ec46a1a9bdb3ae864c87a665c95 (diff) | |
download | chromium_src-4e46a73c1185a737a525585b25c5e27cb22e405e.zip chromium_src-4e46a73c1185a737a525585b25c5e27cb22e405e.tar.gz chromium_src-4e46a73c1185a737a525585b25c5e27cb22e405e.tar.bz2 |
PPAPI: Make GLES2 calls resilient to bad/dead resources.
Currently, if PPB_OpenGLES2 is passed a bad resource, or if a bad resource is
set prior to OpenGLES2 calls, our code happily dereferences a NULL pointer.
This CL tries to address that by handling failure in a way that's consistent
with our other Pepper interfaces.
It also appears that the "old" approach to locking would end up locking twice
per call. Once to get the PPB_GLES2Impl, then unlocked, and then locked
again inside the LockingCommandBuffer (meaning that the PPB_GLES2Impl
might not actually be valid at the time we dereference it!!). This change
simplifies that and removes the old/hacky way of locking.
BUG=275815
Review URL: https://codereview.chromium.org/24466004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226017 0039d316-1c4b-4281-b951-d872f2087c98
-rwxr-xr-x | gpu/command_buffer/build_gles2_cmd_buffer.py | 79 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_command_buffer_proxy.cc | 7 | ||||
-rw-r--r-- | ppapi/proxy/ppb_graphics_3d_proxy.cc | 161 | ||||
-rw-r--r-- | ppapi/proxy/ppb_graphics_3d_proxy.h | 6 | ||||
-rw-r--r-- | ppapi/shared_impl/ppb_graphics_3d_shared.cc | 14 | ||||
-rw-r--r-- | ppapi/shared_impl/ppb_graphics_3d_shared.h | 33 | ||||
-rw-r--r-- | ppapi/shared_impl/ppb_opengles2_shared.cc | 927 | ||||
-rw-r--r-- | ppapi/shared_impl/ppb_video_decoder_shared.cc | 10 | ||||
-rw-r--r-- | ppapi/shared_impl/proxy_lock.h | 5 | ||||
-rw-r--r-- | ppapi/tests/test_graphics_3d.cc | 30 | ||||
-rw-r--r-- | ppapi/tests/test_graphics_3d.h | 1 |
11 files changed, 824 insertions, 449 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index f4c7e5b..83700f6 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/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 @@ -1627,6 +1631,7 @@ _FUNCTION_INFO = { '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', @@ -1778,6 +1783,7 @@ _FUNCTION_INFO = { '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', @@ -1941,6 +1947,8 @@ _FUNCTION_INFO = { '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', @@ -2305,6 +2313,7 @@ _FUNCTION_INFO = { }, 'BindUniformLocationCHROMIUM': { 'type': 'GLchar', + 'extension': True, 'bucket': True, 'needs_size': True, 'gl_test_func': 'DoBindUniformLocationCHROMIUM', @@ -2313,20 +2322,24 @@ _FUNCTION_INFO = { '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 +2347,7 @@ _FUNCTION_INFO = { }, 'BindVertexArrayOES': { 'type': 'Bind', + 'extension': True, 'gl_test_func': 'glBindVertexArrayOES', 'decoder_func': 'DoBindVertexArrayOES', 'gen_func': 'GenVertexArraysOES', @@ -2342,6 +2356,7 @@ _FUNCTION_INFO = { }, 'DeleteVertexArraysOES': { 'type': 'DELn', + 'extension': True, 'gl_test_func': 'glDeleteVertexArraysOES', 'resource_type': 'VertexArray', 'resource_types': 'VertexArrays', @@ -2349,6 +2364,7 @@ _FUNCTION_INFO = { }, 'IsVertexArrayOES': { 'type': 'Is', + 'extension': True, 'gl_test_func': 'glIsVertexArrayOES', 'decoder_func': 'DoIsVertexArrayOES', 'expectation': False, @@ -6394,7 +6410,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 +6418,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""" @@ -7593,7 +7616,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 +7644,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/ppapi/proxy/ppapi_command_buffer_proxy.cc b/ppapi/proxy/ppapi_command_buffer_proxy.cc index d748678..5861071 100644 --- a/ppapi/proxy/ppapi_command_buffer_proxy.cc +++ b/ppapi/proxy/ppapi_command_buffer_proxy.cc @@ -8,6 +8,7 @@ #include "ppapi/proxy/proxy_channel.h" #include "ppapi/shared_impl/api_id.h" #include "ppapi/shared_impl/host_resource.h" +#include "ppapi/shared_impl/proxy_lock.h" namespace ppapi { namespace proxy { @@ -48,14 +49,12 @@ gpu::CommandBuffer::State PpapiCommandBufferProxy::GetState() { } gpu::CommandBuffer::State PpapiCommandBufferProxy::GetLastState() { - // Note: The locking command buffer wrapper does not take a global lock before - // calling this function. + ppapi::ProxyLock::AssertAcquiredDebugOnly(); return last_state_; } int32 PpapiCommandBufferProxy::GetLastToken() { - // Note: The locking command buffer wrapper does not take a global lock before - // calling this function. + ppapi::ProxyLock::AssertAcquiredDebugOnly(); return last_state_.token; } diff --git a/ppapi/proxy/ppb_graphics_3d_proxy.cc b/ppapi/proxy/ppb_graphics_3d_proxy.cc index ba988fd22..dfd72b3 100644 --- a/ppapi/proxy/ppb_graphics_3d_proxy.cc +++ b/ppapi/proxy/ppb_graphics_3d_proxy.cc @@ -12,7 +12,6 @@ #include "ppapi/proxy/ppapi_command_buffer_proxy.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/ppapi_globals.h" -#include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/resource_creation_api.h" #include "ppapi/thunk/thunk.h" @@ -53,132 +52,8 @@ gpu::CommandBuffer::State GetErrorState() { } // namespace -// This class just wraps a CommandBuffer and optionally locks around every -// method. This is used to ensure that we have the Proxy lock any time we enter -// PpapiCommandBufferProxy. -// -// Note, for performance reasons, most of this code is not truly thread -// safe in the sense of multiple threads concurrently rendering to the same -// Graphics3D context; this isn't allowed, and will likely either crash or -// result in undefined behavior. It is assumed that the thread which creates -// the Graphics3D context will be the thread on which subsequent gl rendering -// will be done. This is why it is okay to read need_to_lock_ without the lock; -// it should only ever be read and written on the same thread where the context -// was created. -// -// TODO(nfullagar): At some point, allow multiple threads to concurrently render -// each to its own context. First step is to allow a single thread (either main -// thread or background thread) to render to a single Graphics3D context. -class Graphics3D::LockingCommandBuffer : public gpu::CommandBuffer { - public: - explicit LockingCommandBuffer(gpu::CommandBuffer* gpu_command_buffer) - : gpu_command_buffer_(gpu_command_buffer), need_to_lock_(true) { - } - virtual ~LockingCommandBuffer() { - } - void set_need_to_lock(bool need_to_lock) { need_to_lock_ = need_to_lock; } - bool need_to_lock() const { return need_to_lock_; } - - private: - // MaybeLock acquires the proxy lock on construction if and only if - // need_to_lock is true. If it acquired the lock, it releases it on - // destruction. If need_to_lock is false, then the lock must already be held. - struct MaybeLock { - explicit MaybeLock(bool need_to_lock) : locked_(need_to_lock) { - if (need_to_lock) - ppapi::ProxyLock::Acquire(); - else - ppapi::ProxyLock::AssertAcquired(); - } - ~MaybeLock() { - if (locked_) - ppapi::ProxyLock::Release(); - } - private: - bool locked_; - }; - - // gpu::CommandBuffer implementation: - virtual bool Initialize() OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->Initialize(); - } - virtual State GetState() OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->GetState(); - } - virtual State GetLastState() OVERRIDE { - // During a normal scene, the vast majority of calls are to GetLastState(). - // We don't allow multi-threaded rendering on the same contex, so for - // performance reasons, avoid the global lock for this entry point. We can - // get away with this here because the underlying implementation of - // GetLastState() is trivial and does not involve global or shared state - // between other contexts. - // TODO(nfullagar): We can probably skip MaybeLock for other methods, but - // the performance gain may not be worth it. - // - // MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->GetLastState(); - } - virtual int32 GetLastToken() OVERRIDE { - return GetLastState().token; - } - virtual void Flush(int32 put_offset) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->Flush(put_offset); - } - virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->FlushSync(put_offset, last_known_get); - } - virtual void SetGetBuffer(int32 transfer_buffer_id) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->SetGetBuffer(transfer_buffer_id); - } - virtual void SetGetOffset(int32 get_offset) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->SetGetOffset(get_offset); - } - virtual gpu::Buffer CreateTransferBuffer(size_t size, - int32* id) OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->CreateTransferBuffer(size, id); - } - virtual void DestroyTransferBuffer(int32 id) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->DestroyTransferBuffer(id); - } - virtual gpu::Buffer GetTransferBuffer(int32 id) OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->GetTransferBuffer(id); - } - virtual void SetToken(int32 token) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->SetToken(token); - } - virtual void SetParseError(gpu::error::Error error) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->SetParseError(error); - } - virtual void SetContextLostReason( - gpu::error::ContextLostReason reason) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->SetContextLostReason(reason); - } - virtual uint32 InsertSyncPoint() OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->InsertSyncPoint(); - } - - // Weak pointer - see class Graphics3D for the scopted_ptr. - gpu::CommandBuffer* gpu_command_buffer_; - - bool need_to_lock_; -}; - Graphics3D::Graphics3D(const HostResource& resource) - : PPB_Graphics3D_Shared(resource), - num_already_locked_calls_(0) { + : PPB_Graphics3D_Shared(resource) { } Graphics3D::~Graphics3D() { @@ -193,10 +68,7 @@ bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2) { command_buffer_.reset( new PpapiCommandBufferProxy(host_resource(), dispatcher)); - locking_command_buffer_.reset( - new LockingCommandBuffer(command_buffer_.get())); - ScopedNoLocking already_locked(this); return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize, share_gles2); } @@ -242,7 +114,7 @@ uint32_t Graphics3D::InsertSyncPoint() { } gpu::CommandBuffer* Graphics3D::GetCommandBuffer() { - return locking_command_buffer_.get(); + return command_buffer_.get(); } gpu::GpuControl* Graphics3D::GetGpuControl() { @@ -250,10 +122,6 @@ gpu::GpuControl* Graphics3D::GetGpuControl() { } int32 Graphics3D::DoSwapBuffers() { - // gles2_impl()->SwapBuffers() results in CommandBuffer calls, and we already - // have the proxy lock. - ScopedNoLocking already_locked(this); - gles2_impl()->SwapBuffers(); IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers( API_ID_PPB_GRAPHICS_3D, host_resource()); @@ -263,31 +131,6 @@ int32 Graphics3D::DoSwapBuffers() { return PP_OK_COMPLETIONPENDING; } -void Graphics3D::PushAlreadyLocked() { - ppapi::ProxyLock::AssertAcquired(); - if (!locking_command_buffer_) { - NOTREACHED(); - return; - } - if (num_already_locked_calls_ == 0) - locking_command_buffer_->set_need_to_lock(false); - ++num_already_locked_calls_; -} - -void Graphics3D::PopAlreadyLocked() { - // We must have Pushed before we can Pop. - DCHECK(!locking_command_buffer_->need_to_lock()); - DCHECK_GT(num_already_locked_calls_, 0); - ppapi::ProxyLock::AssertAcquired(); - if (!locking_command_buffer_) { - NOTREACHED(); - return; - } - --num_already_locked_calls_; - if (num_already_locked_calls_ == 0) - locking_command_buffer_->set_need_to_lock(true); -} - PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher) : InterfaceProxy(dispatcher), callback_factory_(this) { diff --git a/ppapi/proxy/ppb_graphics_3d_proxy.h b/ppapi/proxy/ppb_graphics_3d_proxy.h index 8f6b40f..18ba9dd 100644 --- a/ppapi/proxy/ppb_graphics_3d_proxy.h +++ b/ppapi/proxy/ppb_graphics_3d_proxy.h @@ -49,18 +49,12 @@ class Graphics3D : public PPB_Graphics3D_Shared { virtual uint32_t InsertSyncPoint() OVERRIDE; private: - class LockingCommandBuffer; - // PPB_Graphics3D_Shared overrides. virtual gpu::CommandBuffer* GetCommandBuffer() OVERRIDE; virtual gpu::GpuControl* GetGpuControl() OVERRIDE; virtual int32 DoSwapBuffers() OVERRIDE; - virtual void PushAlreadyLocked() OVERRIDE; - virtual void PopAlreadyLocked() OVERRIDE; - int num_already_locked_calls_; scoped_ptr<PpapiCommandBufferProxy> command_buffer_; - scoped_ptr<LockingCommandBuffer> locking_command_buffer_; DISALLOW_COPY_AND_ASSIGN(Graphics3D); }; diff --git a/ppapi/shared_impl/ppb_graphics_3d_shared.cc b/ppapi/shared_impl/ppb_graphics_3d_shared.cc index 1f412d8..0f39663 100644 --- a/ppapi/shared_impl/ppb_graphics_3d_shared.cc +++ b/ppapi/shared_impl/ppb_graphics_3d_shared.cc @@ -50,7 +50,6 @@ int32_t PPB_Graphics3D_Shared::ResizeBuffers(int32_t width, int32_t height) { if ((width < 0) || (height < 0)) return PP_ERROR_BADARGUMENT; - ScopedNoLocking already_locked(this); gles2_impl()->ResizeCHROMIUM(width, height, 1.f); // TODO(alokp): Check if resize succeeded and return appropriate error code. return PP_OK; @@ -58,7 +57,6 @@ int32_t PPB_Graphics3D_Shared::ResizeBuffers(int32_t width, int32_t height) { int32_t PPB_Graphics3D_Shared::SwapBuffers( scoped_refptr<TrackedCallback> callback) { - ScopedNoLocking already_locked(this); if (HasPendingSwap()) { Log(PP_LOGLEVEL_ERROR, "PPB_Graphics3D.SwapBuffers: Plugin attempted swap " "with previous swap still pending."); @@ -85,13 +83,11 @@ void* PPB_Graphics3D_Shared::MapTexSubImage2DCHROMIUM(GLenum target, GLenum format, GLenum type, GLenum access) { - ScopedNoLocking already_locked(this); return gles2_impl_->MapTexSubImage2DCHROMIUM( target, level, xoffset, yoffset, width, height, format, type, access); } void PPB_Graphics3D_Shared::UnmapTexSubImage2DCHROMIUM(const void* mem) { - ScopedNoLocking already_locked(this); gles2_impl_->UnmapTexSubImage2DCHROMIUM(mem); } @@ -108,7 +104,6 @@ bool PPB_Graphics3D_Shared::CreateGLES2Impl( int32 command_buffer_size, int32 transfer_buffer_size, gpu::gles2::GLES2Implementation* share_gles2) { - ScopedNoLocking already_locked(this); gpu::CommandBuffer* command_buffer = GetCommandBuffer(); DCHECK(command_buffer); @@ -145,19 +140,10 @@ bool PPB_Graphics3D_Shared::CreateGLES2Impl( } void PPB_Graphics3D_Shared::DestroyGLES2Impl() { - ScopedNoLocking already_locked(this); gles2_impl_.reset(); transfer_buffer_.reset(); gles2_helper_.reset(); } -void PPB_Graphics3D_Shared::PushAlreadyLocked() { - // Do nothing. This should be overridden in the plugin side. -} - -void PPB_Graphics3D_Shared::PopAlreadyLocked() { - // Do nothing. This should be overridden in the plugin side. -} - } // namespace ppapi diff --git a/ppapi/shared_impl/ppb_graphics_3d_shared.h b/ppapi/shared_impl/ppb_graphics_3d_shared.h index c51c99b..d576d57 100644 --- a/ppapi/shared_impl/ppb_graphics_3d_shared.h +++ b/ppapi/shared_impl/ppb_graphics_3d_shared.h @@ -59,28 +59,6 @@ class PPAPI_SHARED_EXPORT PPB_Graphics3D_Shared void SwapBuffersACK(int32_t pp_error); protected: - // ScopedNoLocking makes sure we don't try to lock again when we already have - // the proxy lock. This is used when we need to use the CommandBuffer - // (possibly via gles2_impl) but we already have the proxy lock. The - // CommandBuffer in the plugin side of the proxy will otherwise try to acquire - // the ProxyLock, causing a crash because we already own the lock. (Locks in - // Chromium are never recursive). - class ScopedNoLocking { - public: - explicit ScopedNoLocking(PPB_Graphics3D_Shared* graphics3d_shared) - : graphics3d_shared_(graphics3d_shared) { - graphics3d_shared_->PushAlreadyLocked(); - } - ~ScopedNoLocking() { - graphics3d_shared_->PopAlreadyLocked(); - } - private: - PPB_Graphics3D_Shared* graphics3d_shared_; // Weak - - DISALLOW_COPY_AND_ASSIGN(ScopedNoLocking); - }; - - PPB_Graphics3D_Shared(PP_Instance instance); PPB_Graphics3D_Shared(const HostResource& host_resource); virtual ~PPB_Graphics3D_Shared(); @@ -96,17 +74,6 @@ class PPAPI_SHARED_EXPORT PPB_Graphics3D_Shared void DestroyGLES2Impl(); private: - // On the plugin side, we need to know that we already have the lock, so that - // we don't try to acquire it again. The default implementation does nothing; - // the Plugin side of the proxy must implement these. - friend class ScopedNoLocking; - virtual void PushAlreadyLocked(); - virtual void PopAlreadyLocked(); - - // The VideoDecoder needs to be able to call Graphics3D Flush() after taking - // the proxy lock. Hence it needs access to ScopedNoLocking. - friend class PPB_VideoDecoder_Shared; - scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_; scoped_ptr<gpu::TransferBuffer> transfer_buffer_; scoped_ptr<gpu::gles2::GLES2Implementation> gles2_impl_; diff --git a/ppapi/shared_impl/ppb_opengles2_shared.cc b/ppapi/shared_impl/ppb_opengles2_shared.cc index 03db463..534e816 100644 --- a/ppapi/shared_impl/ppb_opengles2_shared.cc +++ b/ppapi/shared_impl/ppb_opengles2_shared.cc @@ -17,827 +17,1344 @@ namespace ppapi { namespace { -gpu::gles2::GLES2Implementation* GetGLES(PP_Resource context) { - thunk::EnterResource<thunk::PPB_Graphics3D_API> enter_g3d(context, false); - DCHECK(enter_g3d.succeeded()); - return static_cast<PPB_Graphics3D_Shared*>(enter_g3d.object())->gles2_impl(); +typedef thunk::EnterResource<thunk::PPB_Graphics3D_API> Enter3D; + +gpu::gles2::GLES2Implementation* ToGles2Impl(Enter3D* enter) { + DCHECK(enter); + DCHECK(enter->succeeded()); + return static_cast<PPB_Graphics3D_Shared*>(enter->object())->gles2_impl(); } void ActiveTexture(PP_Resource context_id, GLenum texture) { - GetGLES(context_id)->ActiveTexture(texture); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ActiveTexture(texture); + } } void AttachShader(PP_Resource context_id, GLuint program, GLuint shader) { - GetGLES(context_id)->AttachShader(program, shader); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->AttachShader(program, shader); + } } void BindAttribLocation( PP_Resource context_id, GLuint program, GLuint index, const char* name) { - GetGLES(context_id)->BindAttribLocation(program, index, name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BindAttribLocation(program, index, name); + } } void BindBuffer(PP_Resource context_id, GLenum target, GLuint buffer) { - GetGLES(context_id)->BindBuffer(target, buffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BindBuffer(target, buffer); + } } void BindFramebuffer( PP_Resource context_id, GLenum target, GLuint framebuffer) { - GetGLES(context_id)->BindFramebuffer(target, framebuffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BindFramebuffer(target, framebuffer); + } } void BindRenderbuffer( PP_Resource context_id, GLenum target, GLuint renderbuffer) { - GetGLES(context_id)->BindRenderbuffer(target, renderbuffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BindRenderbuffer(target, renderbuffer); + } } void BindTexture(PP_Resource context_id, GLenum target, GLuint texture) { - GetGLES(context_id)->BindTexture(target, texture); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BindTexture(target, texture); + } } void BlendColor( PP_Resource context_id, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - GetGLES(context_id)->BlendColor(red, green, blue, alpha); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BlendColor(red, green, blue, alpha); + } } void BlendEquation(PP_Resource context_id, GLenum mode) { - GetGLES(context_id)->BlendEquation(mode); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BlendEquation(mode); + } } void BlendEquationSeparate( PP_Resource context_id, GLenum modeRGB, GLenum modeAlpha) { - GetGLES(context_id)->BlendEquationSeparate(modeRGB, modeAlpha); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BlendEquationSeparate(modeRGB, modeAlpha); + } } void BlendFunc(PP_Resource context_id, GLenum sfactor, GLenum dfactor) { - GetGLES(context_id)->BlendFunc(sfactor, dfactor); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BlendFunc(sfactor, dfactor); + } } void BlendFuncSeparate( PP_Resource context_id, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { - GetGLES(context_id)->BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); + } } void BufferData( PP_Resource context_id, GLenum target, GLsizeiptr size, const void* data, GLenum usage) { - GetGLES(context_id)->BufferData(target, size, data, usage); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BufferData(target, size, data, usage); + } } void BufferSubData( PP_Resource context_id, GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { - GetGLES(context_id)->BufferSubData(target, offset, size, data); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BufferSubData(target, offset, size, data); + } } GLenum CheckFramebufferStatus(PP_Resource context_id, GLenum target) { - return GetGLES(context_id)->CheckFramebufferStatus(target); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->CheckFramebufferStatus(target); + } else { + return 0; + } } void Clear(PP_Resource context_id, GLbitfield mask) { - GetGLES(context_id)->Clear(mask); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Clear(mask); + } } void ClearColor( PP_Resource context_id, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - GetGLES(context_id)->ClearColor(red, green, blue, alpha); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ClearColor(red, green, blue, alpha); + } } void ClearDepthf(PP_Resource context_id, GLclampf depth) { - GetGLES(context_id)->ClearDepthf(depth); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ClearDepthf(depth); + } } void ClearStencil(PP_Resource context_id, GLint s) { - GetGLES(context_id)->ClearStencil(s); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ClearStencil(s); + } } void ColorMask( PP_Resource context_id, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { - GetGLES(context_id)->ColorMask(red, green, blue, alpha); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ColorMask(red, green, blue, alpha); + } } void CompileShader(PP_Resource context_id, GLuint shader) { - GetGLES(context_id)->CompileShader(shader); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->CompileShader(shader); + } } void CompressedTexImage2D( PP_Resource context_id, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) { - GetGLES( - context_id)->CompressedTexImage2D( - target, level, internalformat, width, height, border, imageSize, - data); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->CompressedTexImage2D( + target, level, internalformat, width, height, border, imageSize, + data); + } } void CompressedTexSubImage2D( PP_Resource context_id, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) { - GetGLES( - context_id)->CompressedTexSubImage2D( - target, level, xoffset, yoffset, width, height, format, imageSize, - data); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->CompressedTexSubImage2D( + target, level, xoffset, yoffset, width, height, format, imageSize, + data); + } } void CopyTexImage2D( PP_Resource context_id, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - GetGLES( - context_id)->CopyTexImage2D( - target, level, internalformat, x, y, width, height, border); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->CopyTexImage2D( + target, level, internalformat, x, y, width, height, border); + } } void CopyTexSubImage2D( PP_Resource context_id, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - GetGLES( - context_id)->CopyTexSubImage2D( - target, level, xoffset, yoffset, x, y, width, height); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->CopyTexSubImage2D( + target, level, xoffset, yoffset, x, y, width, height); + } } GLuint CreateProgram(PP_Resource context_id) { - return GetGLES(context_id)->CreateProgram(); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->CreateProgram(); + } else { + return 0; + } } GLuint CreateShader(PP_Resource context_id, GLenum type) { - return GetGLES(context_id)->CreateShader(type); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->CreateShader(type); + } else { + return 0; + } } void CullFace(PP_Resource context_id, GLenum mode) { - GetGLES(context_id)->CullFace(mode); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->CullFace(mode); + } } void DeleteBuffers(PP_Resource context_id, GLsizei n, const GLuint* buffers) { - GetGLES(context_id)->DeleteBuffers(n, buffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteBuffers(n, buffers); + } } void DeleteFramebuffers( PP_Resource context_id, GLsizei n, const GLuint* framebuffers) { - GetGLES(context_id)->DeleteFramebuffers(n, framebuffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteFramebuffers(n, framebuffers); + } } void DeleteProgram(PP_Resource context_id, GLuint program) { - GetGLES(context_id)->DeleteProgram(program); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteProgram(program); + } } void DeleteRenderbuffers( PP_Resource context_id, GLsizei n, const GLuint* renderbuffers) { - GetGLES(context_id)->DeleteRenderbuffers(n, renderbuffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteRenderbuffers(n, renderbuffers); + } } void DeleteShader(PP_Resource context_id, GLuint shader) { - GetGLES(context_id)->DeleteShader(shader); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteShader(shader); + } } void DeleteTextures( PP_Resource context_id, GLsizei n, const GLuint* textures) { - GetGLES(context_id)->DeleteTextures(n, textures); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteTextures(n, textures); + } } void DepthFunc(PP_Resource context_id, GLenum func) { - GetGLES(context_id)->DepthFunc(func); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DepthFunc(func); + } } void DepthMask(PP_Resource context_id, GLboolean flag) { - GetGLES(context_id)->DepthMask(flag); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DepthMask(flag); + } } void DepthRangef(PP_Resource context_id, GLclampf zNear, GLclampf zFar) { - GetGLES(context_id)->DepthRangef(zNear, zFar); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DepthRangef(zNear, zFar); + } } void DetachShader(PP_Resource context_id, GLuint program, GLuint shader) { - GetGLES(context_id)->DetachShader(program, shader); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DetachShader(program, shader); + } } void Disable(PP_Resource context_id, GLenum cap) { - GetGLES(context_id)->Disable(cap); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Disable(cap); + } } void DisableVertexAttribArray(PP_Resource context_id, GLuint index) { - GetGLES(context_id)->DisableVertexAttribArray(index); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DisableVertexAttribArray(index); + } } void DrawArrays( PP_Resource context_id, GLenum mode, GLint first, GLsizei count) { - GetGLES(context_id)->DrawArrays(mode, first, count); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DrawArrays(mode, first, count); + } } void DrawElements( PP_Resource context_id, GLenum mode, GLsizei count, GLenum type, const void* indices) { - GetGLES(context_id)->DrawElements(mode, count, type, indices); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DrawElements(mode, count, type, indices); + } } void Enable(PP_Resource context_id, GLenum cap) { - GetGLES(context_id)->Enable(cap); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Enable(cap); + } } void EnableVertexAttribArray(PP_Resource context_id, GLuint index) { - GetGLES(context_id)->EnableVertexAttribArray(index); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->EnableVertexAttribArray(index); + } } void Finish(PP_Resource context_id) { - GetGLES(context_id)->Finish(); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Finish(); + } } void Flush(PP_Resource context_id) { - GetGLES(context_id)->Flush(); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Flush(); + } } void FramebufferRenderbuffer( PP_Resource context_id, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { - GetGLES( - context_id)->FramebufferRenderbuffer( - target, attachment, renderbuffertarget, renderbuffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->FramebufferRenderbuffer( + target, attachment, renderbuffertarget, renderbuffer); + } } void FramebufferTexture2D( PP_Resource context_id, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { - GetGLES( - context_id)->FramebufferTexture2D( - target, attachment, textarget, texture, level); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->FramebufferTexture2D( + target, attachment, textarget, texture, level); + } } void FrontFace(PP_Resource context_id, GLenum mode) { - GetGLES(context_id)->FrontFace(mode); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->FrontFace(mode); + } } void GenBuffers(PP_Resource context_id, GLsizei n, GLuint* buffers) { - GetGLES(context_id)->GenBuffers(n, buffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenBuffers(n, buffers); + } } void GenerateMipmap(PP_Resource context_id, GLenum target) { - GetGLES(context_id)->GenerateMipmap(target); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenerateMipmap(target); + } } void GenFramebuffers(PP_Resource context_id, GLsizei n, GLuint* framebuffers) { - GetGLES(context_id)->GenFramebuffers(n, framebuffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenFramebuffers(n, framebuffers); + } } void GenRenderbuffers( PP_Resource context_id, GLsizei n, GLuint* renderbuffers) { - GetGLES(context_id)->GenRenderbuffers(n, renderbuffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenRenderbuffers(n, renderbuffers); + } } void GenTextures(PP_Resource context_id, GLsizei n, GLuint* textures) { - GetGLES(context_id)->GenTextures(n, textures); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenTextures(n, textures); + } } void GetActiveAttrib( PP_Resource context_id, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { - GetGLES( - context_id)->GetActiveAttrib( - program, index, bufsize, length, size, type, name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->GetActiveAttrib( + program, index, bufsize, length, size, type, name); + } } void GetActiveUniform( PP_Resource context_id, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { - GetGLES( - context_id)->GetActiveUniform( - program, index, bufsize, length, size, type, name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->GetActiveUniform( + program, index, bufsize, length, size, type, name); + } } void GetAttachedShaders( PP_Resource context_id, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { - GetGLES(context_id)->GetAttachedShaders(program, maxcount, count, shaders); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetAttachedShaders(program, maxcount, count, shaders); + } } GLint GetAttribLocation( PP_Resource context_id, GLuint program, const char* name) { - return GetGLES(context_id)->GetAttribLocation(program, name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->GetAttribLocation(program, name); + } else { + return -1; + } } void GetBooleanv(PP_Resource context_id, GLenum pname, GLboolean* params) { - GetGLES(context_id)->GetBooleanv(pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetBooleanv(pname, params); + } } void GetBufferParameteriv( PP_Resource context_id, GLenum target, GLenum pname, GLint* params) { - GetGLES(context_id)->GetBufferParameteriv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetBufferParameteriv(target, pname, params); + } } GLenum GetError(PP_Resource context_id) { - return GetGLES(context_id)->GetError(); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->GetError(); + } else { + return 0; + } } void GetFloatv(PP_Resource context_id, GLenum pname, GLfloat* params) { - GetGLES(context_id)->GetFloatv(pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetFloatv(pname, params); + } } void GetFramebufferAttachmentParameteriv( PP_Resource context_id, GLenum target, GLenum attachment, GLenum pname, GLint* params) { - GetGLES( - context_id)->GetFramebufferAttachmentParameteriv( - target, attachment, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->GetFramebufferAttachmentParameteriv( + target, attachment, pname, params); + } } void GetIntegerv(PP_Resource context_id, GLenum pname, GLint* params) { - GetGLES(context_id)->GetIntegerv(pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetIntegerv(pname, params); + } } void GetProgramiv( PP_Resource context_id, GLuint program, GLenum pname, GLint* params) { - GetGLES(context_id)->GetProgramiv(program, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetProgramiv(program, pname, params); + } } void GetProgramInfoLog( PP_Resource context_id, GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) { - GetGLES(context_id)->GetProgramInfoLog(program, bufsize, length, infolog); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetProgramInfoLog(program, bufsize, length, infolog); + } } void GetRenderbufferParameteriv( PP_Resource context_id, GLenum target, GLenum pname, GLint* params) { - GetGLES(context_id)->GetRenderbufferParameteriv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetRenderbufferParameteriv(target, pname, params); + } } void GetShaderiv( PP_Resource context_id, GLuint shader, GLenum pname, GLint* params) { - GetGLES(context_id)->GetShaderiv(shader, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetShaderiv(shader, pname, params); + } } void GetShaderInfoLog( PP_Resource context_id, GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) { - GetGLES(context_id)->GetShaderInfoLog(shader, bufsize, length, infolog); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetShaderInfoLog(shader, bufsize, length, infolog); + } } void GetShaderPrecisionFormat( PP_Resource context_id, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { - GetGLES( - context_id)->GetShaderPrecisionFormat( - shadertype, precisiontype, range, precision); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->GetShaderPrecisionFormat( + shadertype, precisiontype, range, precision); + } } void GetShaderSource( PP_Resource context_id, GLuint shader, GLsizei bufsize, GLsizei* length, char* source) { - GetGLES(context_id)->GetShaderSource(shader, bufsize, length, source); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetShaderSource(shader, bufsize, length, source); + } } const GLubyte* GetString(PP_Resource context_id, GLenum name) { - return GetGLES(context_id)->GetString(name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->GetString(name); + } else { + return NULL; + } } void GetTexParameterfv( PP_Resource context_id, GLenum target, GLenum pname, GLfloat* params) { - GetGLES(context_id)->GetTexParameterfv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetTexParameterfv(target, pname, params); + } } void GetTexParameteriv( PP_Resource context_id, GLenum target, GLenum pname, GLint* params) { - GetGLES(context_id)->GetTexParameteriv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetTexParameteriv(target, pname, params); + } } void GetUniformfv( PP_Resource context_id, GLuint program, GLint location, GLfloat* params) { - GetGLES(context_id)->GetUniformfv(program, location, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetUniformfv(program, location, params); + } } void GetUniformiv( PP_Resource context_id, GLuint program, GLint location, GLint* params) { - GetGLES(context_id)->GetUniformiv(program, location, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetUniformiv(program, location, params); + } } GLint GetUniformLocation( PP_Resource context_id, GLuint program, const char* name) { - return GetGLES(context_id)->GetUniformLocation(program, name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->GetUniformLocation(program, name); + } else { + return -1; + } } void GetVertexAttribfv( PP_Resource context_id, GLuint index, GLenum pname, GLfloat* params) { - GetGLES(context_id)->GetVertexAttribfv(index, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetVertexAttribfv(index, pname, params); + } } void GetVertexAttribiv( PP_Resource context_id, GLuint index, GLenum pname, GLint* params) { - GetGLES(context_id)->GetVertexAttribiv(index, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetVertexAttribiv(index, pname, params); + } } void GetVertexAttribPointerv( PP_Resource context_id, GLuint index, GLenum pname, void** pointer) { - GetGLES(context_id)->GetVertexAttribPointerv(index, pname, pointer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetVertexAttribPointerv(index, pname, pointer); + } } void Hint(PP_Resource context_id, GLenum target, GLenum mode) { - GetGLES(context_id)->Hint(target, mode); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Hint(target, mode); + } } GLboolean IsBuffer(PP_Resource context_id, GLuint buffer) { - return GetGLES(context_id)->IsBuffer(buffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsBuffer(buffer); + } else { + return GL_FALSE; + } } GLboolean IsEnabled(PP_Resource context_id, GLenum cap) { - return GetGLES(context_id)->IsEnabled(cap); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsEnabled(cap); + } else { + return GL_FALSE; + } } GLboolean IsFramebuffer(PP_Resource context_id, GLuint framebuffer) { - return GetGLES(context_id)->IsFramebuffer(framebuffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsFramebuffer(framebuffer); + } else { + return GL_FALSE; + } } GLboolean IsProgram(PP_Resource context_id, GLuint program) { - return GetGLES(context_id)->IsProgram(program); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsProgram(program); + } else { + return GL_FALSE; + } } GLboolean IsRenderbuffer(PP_Resource context_id, GLuint renderbuffer) { - return GetGLES(context_id)->IsRenderbuffer(renderbuffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsRenderbuffer(renderbuffer); + } else { + return GL_FALSE; + } } GLboolean IsShader(PP_Resource context_id, GLuint shader) { - return GetGLES(context_id)->IsShader(shader); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsShader(shader); + } else { + return GL_FALSE; + } } GLboolean IsTexture(PP_Resource context_id, GLuint texture) { - return GetGLES(context_id)->IsTexture(texture); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsTexture(texture); + } else { + return GL_FALSE; + } } void LineWidth(PP_Resource context_id, GLfloat width) { - GetGLES(context_id)->LineWidth(width); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->LineWidth(width); + } } void LinkProgram(PP_Resource context_id, GLuint program) { - GetGLES(context_id)->LinkProgram(program); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->LinkProgram(program); + } } void PixelStorei(PP_Resource context_id, GLenum pname, GLint param) { - GetGLES(context_id)->PixelStorei(pname, param); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->PixelStorei(pname, param); + } } void PolygonOffset(PP_Resource context_id, GLfloat factor, GLfloat units) { - GetGLES(context_id)->PolygonOffset(factor, units); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->PolygonOffset(factor, units); + } } void ReadPixels( PP_Resource context_id, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { - GetGLES(context_id)->ReadPixels(x, y, width, height, format, type, pixels); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ReadPixels(x, y, width, height, format, type, pixels); + } } void ReleaseShaderCompiler(PP_Resource context_id) { - GetGLES(context_id)->ReleaseShaderCompiler(); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ReleaseShaderCompiler(); + } } void RenderbufferStorage( PP_Resource context_id, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { - GetGLES( - context_id)->RenderbufferStorage(target, internalformat, width, height); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->RenderbufferStorage(target, internalformat, width, height); + } } void SampleCoverage(PP_Resource context_id, GLclampf value, GLboolean invert) { - GetGLES(context_id)->SampleCoverage(value, invert); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->SampleCoverage(value, invert); + } } void Scissor( PP_Resource context_id, GLint x, GLint y, GLsizei width, GLsizei height) { - GetGLES(context_id)->Scissor(x, y, width, height); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Scissor(x, y, width, height); + } } void ShaderBinary( PP_Resource context_id, GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) { - GetGLES(context_id)->ShaderBinary(n, shaders, binaryformat, binary, length); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->ShaderBinary(n, shaders, binaryformat, binary, length); + } } void ShaderSource( PP_Resource context_id, GLuint shader, GLsizei count, const char** str, const GLint* length) { - GetGLES(context_id)->ShaderSource(shader, count, str, length); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ShaderSource(shader, count, str, length); + } } void StencilFunc(PP_Resource context_id, GLenum func, GLint ref, GLuint mask) { - GetGLES(context_id)->StencilFunc(func, ref, mask); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilFunc(func, ref, mask); + } } void StencilFuncSeparate( PP_Resource context_id, GLenum face, GLenum func, GLint ref, GLuint mask) { - GetGLES(context_id)->StencilFuncSeparate(face, func, ref, mask); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilFuncSeparate(face, func, ref, mask); + } } void StencilMask(PP_Resource context_id, GLuint mask) { - GetGLES(context_id)->StencilMask(mask); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilMask(mask); + } } void StencilMaskSeparate(PP_Resource context_id, GLenum face, GLuint mask) { - GetGLES(context_id)->StencilMaskSeparate(face, mask); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilMaskSeparate(face, mask); + } } void StencilOp( PP_Resource context_id, GLenum fail, GLenum zfail, GLenum zpass) { - GetGLES(context_id)->StencilOp(fail, zfail, zpass); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilOp(fail, zfail, zpass); + } } void StencilOpSeparate( PP_Resource context_id, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { - GetGLES(context_id)->StencilOpSeparate(face, fail, zfail, zpass); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilOpSeparate(face, fail, zfail, zpass); + } } void TexImage2D( PP_Resource context_id, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) { - GetGLES( - context_id)->TexImage2D( - target, level, internalformat, width, height, border, format, type, - pixels); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->TexImage2D( + target, level, internalformat, width, height, border, format, type, + pixels); + } } void TexParameterf( PP_Resource context_id, GLenum target, GLenum pname, GLfloat param) { - GetGLES(context_id)->TexParameterf(target, pname, param); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->TexParameterf(target, pname, param); + } } void TexParameterfv( PP_Resource context_id, GLenum target, GLenum pname, const GLfloat* params) { - GetGLES(context_id)->TexParameterfv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->TexParameterfv(target, pname, params); + } } void TexParameteri( PP_Resource context_id, GLenum target, GLenum pname, GLint param) { - GetGLES(context_id)->TexParameteri(target, pname, param); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->TexParameteri(target, pname, param); + } } void TexParameteriv( PP_Resource context_id, GLenum target, GLenum pname, const GLint* params) { - GetGLES(context_id)->TexParameteriv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->TexParameteriv(target, pname, params); + } } void TexSubImage2D( PP_Resource context_id, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) { - GetGLES( - context_id)->TexSubImage2D( - target, level, xoffset, yoffset, width, height, format, type, - pixels); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->TexSubImage2D( + target, level, xoffset, yoffset, width, height, format, type, + pixels); + } } void Uniform1f(PP_Resource context_id, GLint location, GLfloat x) { - GetGLES(context_id)->Uniform1f(location, x); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform1f(location, x); + } } void Uniform1fv( PP_Resource context_id, GLint location, GLsizei count, const GLfloat* v) { - GetGLES(context_id)->Uniform1fv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform1fv(location, count, v); + } } void Uniform1i(PP_Resource context_id, GLint location, GLint x) { - GetGLES(context_id)->Uniform1i(location, x); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform1i(location, x); + } } void Uniform1iv( PP_Resource context_id, GLint location, GLsizei count, const GLint* v) { - GetGLES(context_id)->Uniform1iv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform1iv(location, count, v); + } } void Uniform2f(PP_Resource context_id, GLint location, GLfloat x, GLfloat y) { - GetGLES(context_id)->Uniform2f(location, x, y); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform2f(location, x, y); + } } void Uniform2fv( PP_Resource context_id, GLint location, GLsizei count, const GLfloat* v) { - GetGLES(context_id)->Uniform2fv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform2fv(location, count, v); + } } void Uniform2i(PP_Resource context_id, GLint location, GLint x, GLint y) { - GetGLES(context_id)->Uniform2i(location, x, y); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform2i(location, x, y); + } } void Uniform2iv( PP_Resource context_id, GLint location, GLsizei count, const GLint* v) { - GetGLES(context_id)->Uniform2iv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform2iv(location, count, v); + } } void Uniform3f( PP_Resource context_id, GLint location, GLfloat x, GLfloat y, GLfloat z) { - GetGLES(context_id)->Uniform3f(location, x, y, z); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform3f(location, x, y, z); + } } void Uniform3fv( PP_Resource context_id, GLint location, GLsizei count, const GLfloat* v) { - GetGLES(context_id)->Uniform3fv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform3fv(location, count, v); + } } void Uniform3i( PP_Resource context_id, GLint location, GLint x, GLint y, GLint z) { - GetGLES(context_id)->Uniform3i(location, x, y, z); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform3i(location, x, y, z); + } } void Uniform3iv( PP_Resource context_id, GLint location, GLsizei count, const GLint* v) { - GetGLES(context_id)->Uniform3iv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform3iv(location, count, v); + } } void Uniform4f( PP_Resource context_id, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - GetGLES(context_id)->Uniform4f(location, x, y, z, w); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform4f(location, x, y, z, w); + } } void Uniform4fv( PP_Resource context_id, GLint location, GLsizei count, const GLfloat* v) { - GetGLES(context_id)->Uniform4fv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform4fv(location, count, v); + } } void Uniform4i( PP_Resource context_id, GLint location, GLint x, GLint y, GLint z, GLint w) { - GetGLES(context_id)->Uniform4i(location, x, y, z, w); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform4i(location, x, y, z, w); + } } void Uniform4iv( PP_Resource context_id, GLint location, GLsizei count, const GLint* v) { - GetGLES(context_id)->Uniform4iv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform4iv(location, count, v); + } } void UniformMatrix2fv( PP_Resource context_id, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - GetGLES(context_id)->UniformMatrix2fv(location, count, transpose, value); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UniformMatrix2fv(location, count, transpose, value); + } } void UniformMatrix3fv( PP_Resource context_id, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - GetGLES(context_id)->UniformMatrix3fv(location, count, transpose, value); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UniformMatrix3fv(location, count, transpose, value); + } } void UniformMatrix4fv( PP_Resource context_id, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - GetGLES(context_id)->UniformMatrix4fv(location, count, transpose, value); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UniformMatrix4fv(location, count, transpose, value); + } } void UseProgram(PP_Resource context_id, GLuint program) { - GetGLES(context_id)->UseProgram(program); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UseProgram(program); + } } void ValidateProgram(PP_Resource context_id, GLuint program) { - GetGLES(context_id)->ValidateProgram(program); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ValidateProgram(program); + } } void VertexAttrib1f(PP_Resource context_id, GLuint indx, GLfloat x) { - GetGLES(context_id)->VertexAttrib1f(indx, x); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib1f(indx, x); + } } void VertexAttrib1fv( PP_Resource context_id, GLuint indx, const GLfloat* values) { - GetGLES(context_id)->VertexAttrib1fv(indx, values); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib1fv(indx, values); + } } void VertexAttrib2f( PP_Resource context_id, GLuint indx, GLfloat x, GLfloat y) { - GetGLES(context_id)->VertexAttrib2f(indx, x, y); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib2f(indx, x, y); + } } void VertexAttrib2fv( PP_Resource context_id, GLuint indx, const GLfloat* values) { - GetGLES(context_id)->VertexAttrib2fv(indx, values); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib2fv(indx, values); + } } void VertexAttrib3f( PP_Resource context_id, GLuint indx, GLfloat x, GLfloat y, GLfloat z) { - GetGLES(context_id)->VertexAttrib3f(indx, x, y, z); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib3f(indx, x, y, z); + } } void VertexAttrib3fv( PP_Resource context_id, GLuint indx, const GLfloat* values) { - GetGLES(context_id)->VertexAttrib3fv(indx, values); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib3fv(indx, values); + } } void VertexAttrib4f( PP_Resource context_id, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - GetGLES(context_id)->VertexAttrib4f(indx, x, y, z, w); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib4f(indx, x, y, z, w); + } } void VertexAttrib4fv( PP_Resource context_id, GLuint indx, const GLfloat* values) { - GetGLES(context_id)->VertexAttrib4fv(indx, values); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib4fv(indx, values); + } } void VertexAttribPointer( PP_Resource context_id, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) { - GetGLES( - context_id)->VertexAttribPointer( - indx, size, type, normalized, stride, ptr); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->VertexAttribPointer( + indx, size, type, normalized, stride, ptr); + } } void Viewport( PP_Resource context_id, GLint x, GLint y, GLsizei width, GLsizei height) { - GetGLES(context_id)->Viewport(x, y, width, height); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Viewport(x, y, width, height); + } } void BlitFramebufferEXT( PP_Resource context_id, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - GetGLES( - context_id)->BlitFramebufferEXT( - srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, - filter); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->BlitFramebufferEXT( + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, + filter); + } } void RenderbufferStorageMultisampleEXT( PP_Resource context_id, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { - GetGLES( - context_id)->RenderbufferStorageMultisampleEXT( - target, samples, internalformat, width, height); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->RenderbufferStorageMultisampleEXT( + target, samples, internalformat, width, height); + } } void GenQueriesEXT(PP_Resource context_id, GLsizei n, GLuint* queries) { - GetGLES(context_id)->GenQueriesEXT(n, queries); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenQueriesEXT(n, queries); + } } void DeleteQueriesEXT( PP_Resource context_id, GLsizei n, const GLuint* queries) { - GetGLES(context_id)->DeleteQueriesEXT(n, queries); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteQueriesEXT(n, queries); + } } GLboolean IsQueryEXT(PP_Resource context_id, GLuint id) { - return GetGLES(context_id)->IsQueryEXT(id); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsQueryEXT(id); + } else { + return GL_FALSE; + } } void BeginQueryEXT(PP_Resource context_id, GLenum target, GLuint id) { - GetGLES(context_id)->BeginQueryEXT(target, id); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BeginQueryEXT(target, id); + } } void EndQueryEXT(PP_Resource context_id, GLenum target) { - GetGLES(context_id)->EndQueryEXT(target); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->EndQueryEXT(target); + } } void GetQueryivEXT( PP_Resource context_id, GLenum target, GLenum pname, GLint* params) { - GetGLES(context_id)->GetQueryivEXT(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetQueryivEXT(target, pname, params); + } } void GetQueryObjectuivEXT( PP_Resource context_id, GLuint id, GLenum pname, GLuint* params) { - GetGLES(context_id)->GetQueryObjectuivEXT(id, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetQueryObjectuivEXT(id, pname, params); + } } GLboolean EnableFeatureCHROMIUM(PP_Resource context_id, const char* feature) { - return GetGLES(context_id)->EnableFeatureCHROMIUM(feature); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->EnableFeatureCHROMIUM(feature); + } else { + return GL_FALSE; + } } void* MapBufferSubDataCHROMIUM( PP_Resource context_id, GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) { - return GetGLES( - context_id)->MapBufferSubDataCHROMIUM(target, offset, size, access); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl( + &enter)->MapBufferSubDataCHROMIUM(target, offset, size, access); + } else { + return NULL; + } } void UnmapBufferSubDataCHROMIUM(PP_Resource context_id, const void* mem) { - GetGLES(context_id)->UnmapBufferSubDataCHROMIUM(mem); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UnmapBufferSubDataCHROMIUM(mem); + } } void* MapTexSubImage2DCHROMIUM( PP_Resource context_id, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum access) { - return GetGLES( - context_id)->MapTexSubImage2DCHROMIUM( - target, level, xoffset, yoffset, width, height, format, type, - access); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl( + &enter)->MapTexSubImage2DCHROMIUM( + target, level, xoffset, yoffset, width, height, format, type, + access); + } else { + return NULL; + } } void UnmapTexSubImage2DCHROMIUM(PP_Resource context_id, const void* mem) { - GetGLES(context_id)->UnmapTexSubImage2DCHROMIUM(mem); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UnmapTexSubImage2DCHROMIUM(mem); + } } void DrawArraysInstancedANGLE( PP_Resource context_id, GLenum mode, GLint first, GLsizei count, GLsizei primcount) { - GetGLES(context_id)->DrawArraysInstancedANGLE(mode, first, count, primcount); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->DrawArraysInstancedANGLE(mode, first, count, primcount); + } } void DrawElementsInstancedANGLE( PP_Resource context_id, GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount) { - GetGLES( - context_id)->DrawElementsInstancedANGLE( - mode, count, type, indices, primcount); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->DrawElementsInstancedANGLE( + mode, count, type, indices, primcount); + } } void VertexAttribDivisorANGLE( PP_Resource context_id, GLuint index, GLuint divisor) { - GetGLES(context_id)->VertexAttribDivisorANGLE(index, divisor); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttribDivisorANGLE(index, divisor); + } } } // namespace diff --git a/ppapi/shared_impl/ppb_video_decoder_shared.cc b/ppapi/shared_impl/ppb_video_decoder_shared.cc index 7d8d021..5232e6c 100644 --- a/ppapi/shared_impl/ppb_video_decoder_shared.cc +++ b/ppapi/shared_impl/ppb_video_decoder_shared.cc @@ -96,16 +96,8 @@ void PPB_VideoDecoder_Shared::RunBitstreamBufferCallback( } void PPB_VideoDecoder_Shared::FlushCommandBuffer() { - if (gles2_impl_) { - // To call Flush() we have to tell Graphics3D that we hold the proxy lock. - thunk::EnterResource<thunk::PPB_Graphics3D_API, false> enter_g3d( - graphics_context_, false); - DCHECK(enter_g3d.succeeded()); - PPB_Graphics3D_Shared* graphics3d = - static_cast<PPB_Graphics3D_Shared*>(enter_g3d.object()); - PPB_Graphics3D_Shared::ScopedNoLocking dont_lock(graphics3d); + if (gles2_impl_) gles2_impl_->Flush(); - } } } // namespace ppapi diff --git a/ppapi/shared_impl/proxy_lock.h b/ppapi/shared_impl/proxy_lock.h index 9a81a13..f6dea31 100644 --- a/ppapi/shared_impl/proxy_lock.h +++ b/ppapi/shared_impl/proxy_lock.h @@ -50,6 +50,11 @@ class PPAPI_SHARED_EXPORT ProxyLock { // Assert that the lock is owned by the current thread (in the plugin // process). Does nothing when running in-process (or in the host process). static void AssertAcquired(); + static void AssertAcquiredDebugOnly() { +#ifndef NDEBUG + AssertAcquired(); +#endif + } // We have some unit tests where one thread pretends to be the host and one // pretends to be the plugin. This allows the lock to do nothing on only one diff --git a/ppapi/tests/test_graphics_3d.cc b/ppapi/tests/test_graphics_3d.cc index 61bedbf..8c1bdc1 100644 --- a/ppapi/tests/test_graphics_3d.cc +++ b/ppapi/tests/test_graphics_3d.cc @@ -34,6 +34,7 @@ void TestGraphics3D::RunTests(const std::string& filter) { RUN_CALLBACK_TEST(TestGraphics3D, FramePPAPI, filter); RUN_CALLBACK_TEST(TestGraphics3D, FrameGL, filter); RUN_CALLBACK_TEST(TestGraphics3D, ExtensionsGL, filter); + RUN_CALLBACK_TEST(TestGraphics3D, BadResource, filter); } std::string TestGraphics3D::TestFramePPAPI() { @@ -167,3 +168,32 @@ std::string TestGraphics3D::CheckPixelGL( PASS(); } +std::string TestGraphics3D::TestBadResource() { + // The point of this test is mostly just to make sure that we don't crash and + // provide reasonable (error) results when the resource is bad. + const PP_Resource kBadResource = 123; + + // Access OpenGLES API through the PPAPI interface. + opengl_es2_->ClearColor(kBadResource, 0.0f, 0.0f, 0.0f, 0.0f); + opengl_es2_->Clear(kBadResource, GL_COLOR_BUFFER_BIT); + ASSERT_EQ(0, opengl_es2_->GetError(kBadResource)); + ASSERT_EQ(NULL, opengl_es2_->GetString(kBadResource, GL_VERSION)); + ASSERT_EQ(-1, opengl_es2_->GetUniformLocation(kBadResource, 0, NULL)); + ASSERT_EQ(GL_FALSE, opengl_es2_->IsBuffer(kBadResource, 0)); + ASSERT_EQ(0, opengl_es2_->CheckFramebufferStatus(kBadResource, + GL_DRAW_FRAMEBUFFER)); + + glSetCurrentContextPPAPI(kBadResource); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + ASSERT_EQ(0, glGetError()); + ASSERT_EQ(NULL, glGetString(GL_VERSION)); + ASSERT_EQ(-1, glGetUniformLocation(0, NULL)); + ASSERT_EQ(GL_FALSE, glIsBuffer(0)); + ASSERT_EQ(0, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)); + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + PASS(); +} + diff --git a/ppapi/tests/test_graphics_3d.h b/ppapi/tests/test_graphics_3d.h index 3d5b1cf..2914f96 100644 --- a/ppapi/tests/test_graphics_3d.h +++ b/ppapi/tests/test_graphics_3d.h @@ -27,6 +27,7 @@ class TestGraphics3D : public TestCase { std::string TestExtensionsGL(); std::string TestFrameGL(); std::string TestFramePPAPI(); + std::string TestBadResource(); // Utils used by various tests. int32_t SwapBuffersSync(pp::Graphics3D* context); |