diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-03 23:27:43 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-03 23:27:43 +0000 |
commit | 9a298ada39103abf74e423519a9ee8251bbe0555 (patch) | |
tree | fe6229f2fe75a3d844408d9051cc3fa90dfe7fa8 /gpu/pgl | |
parent | 49a518aabe67f9366bc23d0142493cb6508d662d (diff) | |
download | chromium_src-9a298ada39103abf74e423519a9ee8251bbe0555.zip chromium_src-9a298ada39103abf74e423519a9ee8251bbe0555.tar.gz chromium_src-9a298ada39103abf74e423519a9ee8251bbe0555.tar.bz2 |
Added support for lost context recovery on the client side. None of our service side GL implementations actually report lost contexts (yet).
Added pglGetError to PGL library.
pglSwapBuffers returns false on a lost context or other non-recoverable error and pglGetError reports PGL_CONTEXT_LOST.
Updated demo plugins to reset their PGL contexts on context lost. Standalone plugins cannot currently recover from lost context because they don't use PGL.
Added error code to NPDeviceContext3D for lost context.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/566021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38039 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/pgl')
-rw-r--r-- | gpu/pgl/pgl.cc | 85 | ||||
-rw-r--r-- | gpu/pgl/pgl.h | 18 |
2 files changed, 81 insertions, 22 deletions
diff --git a/gpu/pgl/pgl.cc b/gpu/pgl/pgl.cc index 41903e1..68a074f 100644 --- a/gpu/pgl/pgl.cc +++ b/gpu/pgl/pgl.cc @@ -7,6 +7,7 @@ #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "gpu/command_buffer/client/gles2_lib.h" +#include "gpu/command_buffer/common/constants.h" #include "gpu/command_buffer/common/thread_local.h" #include "gpu/pgl/command_buffer_pepper.h" #include "gpu/pgl/pgl.h" @@ -22,16 +23,19 @@ class PGLContextImpl { ~PGLContextImpl(); // Initlaize a PGL context with a transfer buffer of a particular size. - bool Initialize(int32 transfer_buffer_size); + PGLBoolean Initialize(int32 transfer_buffer_size); // Destroy all resources associated with the PGL context. void Destroy(); // Make a PGL context current for the calling thread. - static bool MakeCurrent(PGLContextImpl* pgl_context); + static PGLBoolean MakeCurrent(PGLContextImpl* pgl_context); // Display all content rendered since last call to SwapBuffers. - bool SwapBuffers(); + PGLBoolean SwapBuffers(); + + // Get the current error code. + PGLInt GetError(); private: PGLContextImpl(const PGLContextImpl&); @@ -64,7 +68,7 @@ PGLContextImpl::~PGLContextImpl() { Destroy(); } -bool PGLContextImpl::Initialize(int32 transfer_buffer_size) { +PGLBoolean PGLContextImpl::Initialize(int32 transfer_buffer_size) { // Create and initialize the objects required to issue GLES2 calls. command_buffer_ = new CommandBufferPepper( npp_, device_, device_context_); @@ -80,13 +84,13 @@ bool PGLContextImpl::Initialize(int32 transfer_buffer_size) { transfer_buffer.size, transfer_buffer.ptr, transfer_buffer_id_); - return true; + return PGL_TRUE; } } // Tear everything down if initialization failed. Destroy(); - return false; + return PGL_FALSE; } void PGLContextImpl::Destroy() { @@ -105,22 +109,48 @@ void PGLContextImpl::Destroy() { command_buffer_ = NULL; } -bool PGLContextImpl::MakeCurrent(PGLContextImpl* pgl_context) { +PGLBoolean PGLContextImpl::MakeCurrent(PGLContextImpl* pgl_context) { if (!g_pgl_context_key) - return false; + return PGL_FALSE; gpu::ThreadLocalSetValue(g_pgl_context_key, pgl_context); - if (pgl_context) + if (pgl_context) { gles2::SetGLContext(pgl_context->gles2_implementation_); - else + + // Don't request latest error status from service. Just use the locally + // cached information from the last flush. + // TODO(apatrick): I'm not sure if this should actually change the + // current context if it fails. For now it gets changed even if it fails + // becuase making GL calls with a NULL context crashes. + if (pgl_context->device_context_->error != NPDeviceContext3DError_NoError) + return PGL_FALSE; + } + else { gles2::SetGLContext(NULL); + } - return true; + return PGL_TRUE; } -bool PGLContextImpl::SwapBuffers() { +PGLBoolean PGLContextImpl::SwapBuffers() { + // Don't request latest error status from service. Just use the locally cached + // information from the last flush. + if (device_context_->error != NPDeviceContext3DError_NoError) + return PGL_FALSE; + gles2_implementation_->SwapBuffers(); - return true; + return PGL_TRUE; +} + +PGLInt PGLContextImpl::GetError() { + gpu::CommandBuffer::State state = command_buffer_->GetState(); + if (state.error == gpu::error::kNoError) { + return PGL_SUCCESS; + } else { + // All command buffer errors are unrecoverable. The error is treated as a + // lost context: destroy the context and create another one. + return PGL_CONTEXT_LOST; + } } } // namespace anonymous @@ -128,20 +158,22 @@ extern "C" { PGLBoolean pglInitialize() { if (g_pgl_context_key) - return true; + return PGL_TRUE; gles2::Initialize(); g_pgl_context_key = gpu::ThreadLocalAlloc(); - return true; + return PGL_TRUE; } PGLBoolean pglTerminate() { if (!g_pgl_context_key) - return true; + return PGL_TRUE; gpu::ThreadLocalFree(g_pgl_context_key); + g_pgl_context_key = 0; + gles2::Terminate(); - return true; + return PGL_TRUE; } PGLContext pglCreateContext(NPP npp, @@ -175,23 +207,34 @@ PGLBoolean pglSwapBuffers(void) { PGLContextImpl* context = static_cast<PGLContextImpl*>( pglGetCurrentContext()); if (!context) - return false; + return PGL_FALSE; return context->SwapBuffers(); } PGLBoolean pglDestroyContext(PGLContext pgl_context) { if (!g_pgl_context_key) - return NULL; + return PGL_FALSE; if (!pgl_context) - return false; + return PGL_FALSE; if (pgl_context == pglGetCurrentContext()) pglMakeCurrent(NULL); delete static_cast<PGLContextImpl*>(pgl_context); - return true; + return PGL_TRUE; } +PGLInt pglGetError() { + if (!g_pgl_context_key) + return PGL_NOT_INITIALIZED; + + PGLContextImpl* context = static_cast<PGLContextImpl*>( + pglGetCurrentContext()); + if (!context) + return PGL_BAD_CONTEXT; + + return context->GetError(); +} } // extern "C" diff --git a/gpu/pgl/pgl.h b/gpu/pgl/pgl.h index 3a7735e..ac67ec1 100644 --- a/gpu/pgl/pgl.h +++ b/gpu/pgl/pgl.h @@ -8,12 +8,25 @@ #include "npapi.h" #include "npapi_extensions.h" +#define PGL_TRUE 1 +#define PGL_FALSE 0 + #ifdef __cplusplus extern "C" { #endif typedef void* PGLContext; -typedef bool PGLBoolean; +typedef unsigned int PGLBoolean; +typedef int32 PGLInt; + +// These are the same error codes as used by EGL. +enum { + PGL_SUCCESS = 0x3000, + PGL_NOT_INITIALIZED = 0x3001, + PGL_BAD_CONTEXT = 0x3006, + PGL_BAD_PARAMETER = 0x300C, + PGL_CONTEXT_LOST = 0x300E +}; // Initialize the PGL library. This must have completed before any other PGL // functions are invoked. @@ -40,6 +53,9 @@ PGLBoolean pglSwapBuffers(void); // Destroy the given PGL context. PGLBoolean pglDestroyContext(PGLContext pgl_context); +// Return the current PGL error. +PGLInt pglGetError(); + #ifdef __cplusplus } // extern "C" #endif |