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 | |
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
-rw-r--r-- | gpu/command_buffer/client/gles2_demo.cc | 6 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_demo_c.c | 2 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_demo_c.h | 2 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_demo_cc.cc | 73 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_demo_cc.h | 3 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_lib.cc | 1 | ||||
-rw-r--r-- | gpu/command_buffer/common/constants.h | 1 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 2 | ||||
-rw-r--r-- | gpu/demos/framework/plugin.cc | 55 | ||||
-rw-r--r-- | gpu/demos/framework/plugin.h | 3 | ||||
-rw-r--r-- | gpu/pgl/pgl.cc | 85 | ||||
-rw-r--r-- | gpu/pgl/pgl.h | 18 | ||||
-rw-r--r-- | third_party/npapi/bindings/npapi_extensions.h | 15 | ||||
-rw-r--r-- | webkit/tools/pepper_test_plugin/plugin_object.cc | 72 | ||||
-rw-r--r-- | webkit/tools/pepper_test_plugin/plugin_object.h | 2 |
15 files changed, 232 insertions, 108 deletions
diff --git a/gpu/command_buffer/client/gles2_demo.cc b/gpu/command_buffer/client/gles2_demo.cc index 9b5977e..8992c2c 100644 --- a/gpu/command_buffer/client/gles2_demo.cc +++ b/gpu/command_buffer/client/gles2_demo.cc @@ -83,6 +83,8 @@ bool GLES2Demo::Setup(void* hwnd, int32 size) { transfer_buffer.ptr, transfer_buffer_id)); + GLFromCPPInit(); + return command_buffer.release() != NULL; } @@ -97,8 +99,8 @@ LRESULT CALLBACK WindowProc( PostQuitMessage(0); break; case WM_PAINT: { - GLFromCPPTestFunction(); - GLFromCTestFunction(); + GLFromCPPDraw(); + GLFromCDraw(); // TODO(gman): Not sure how SwapBuffer should be exposed. gles2::GetGLContext()->SwapBuffers(); break; diff --git a/gpu/command_buffer/client/gles2_demo_c.c b/gpu/command_buffer/client/gles2_demo_c.c index abba8b7..aa83b57 100644 --- a/gpu/command_buffer/client/gles2_demo_c.c +++ b/gpu/command_buffer/client/gles2_demo_c.c @@ -8,7 +8,7 @@ #include <GLES2/gl2.h> #include "gpu/command_buffer/client/gles2_demo_c.h" -void GLFromCTestFunction() { +void GLFromCDraw() { // glClear(GL_COLOR_BUFFER_BIT); } diff --git a/gpu/command_buffer/client/gles2_demo_c.h b/gpu/command_buffer/client/gles2_demo_c.h index 3ce07b2..d4d69e9 100644 --- a/gpu/command_buffer/client/gles2_demo_c.h +++ b/gpu/command_buffer/client/gles2_demo_c.h @@ -11,7 +11,7 @@ extern "C" { #endif -void GLFromCTestFunction(); +void GLFromCDraw(); #ifdef __cplusplus } diff --git a/gpu/command_buffer/client/gles2_demo_cc.cc b/gpu/command_buffer/client/gles2_demo_cc.cc index 2544f42..c6beff6 100644 --- a/gpu/command_buffer/client/gles2_demo_cc.cc +++ b/gpu/command_buffer/client/gles2_demo_cc.cc @@ -130,15 +130,43 @@ void InitShaders() { CheckGLError(); } -#define PI 3.1415926535897932384626433832795f +GLuint CreateCheckerboardTexture() { + static unsigned char pixels[] = { + 255, 255, 255, + 0, 0, 0, + 0, 0, 0, + 255, 255, 255, + }; + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, + pixels); + return texture; +} + +} // anonymous namespace. + +void GLFromCPPInit() { + glClearColor(0.f, 0.f, .7f, 1.f); + g_texture = CreateCheckerboardTexture(); + InitShaders(); +} + +void GLFromCPPDraw() { + const float kPi = 3.1415926535897932384626433832795f; -void Draw() { // TODO(kbr): base the angle on time rather than on ticks g_angle = (g_angle + 1) % 360; // Rotate about the Z axis GLfloat rot_matrix[16]; - GLfloat cos_angle = cosf(static_cast<GLfloat>(g_angle) * PI / 180.0f); - GLfloat sin_angle = sinf(static_cast<GLfloat>(g_angle) * PI / 180.0f); + GLfloat cos_angle = cosf(static_cast<GLfloat>(g_angle) * kPi / 180.0f); + GLfloat sin_angle = sinf(static_cast<GLfloat>(g_angle) * kPi / 180.0f); // OpenGL matrices are column-major rot_matrix[0] = cos_angle; rot_matrix[1] = sin_angle; @@ -188,40 +216,3 @@ void Draw() { CheckGLError(); glFlush(); } - -GLuint CreateCheckerboardTexture() { - static unsigned char pixels[] = { - 255, 255, 255, - 0, 0, 0, - 0, 0, 0, - 255, 255, 255, - }; - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, - pixels); - return texture; -} - -void Init() { - glClearColor(0.f, 0.f, .7f, 1.f); - g_texture = CreateCheckerboardTexture(); - InitShaders(); -} - -} // anonymous namespace. - -void GLFromCPPTestFunction() { - static bool initialized = false; - if (!initialized) { - initialized = true; - Init(); - } - Draw(); -} diff --git a/gpu/command_buffer/client/gles2_demo_cc.h b/gpu/command_buffer/client/gles2_demo_cc.h index ef074e0..158ba43 100644 --- a/gpu/command_buffer/client/gles2_demo_cc.h +++ b/gpu/command_buffer/client/gles2_demo_cc.h @@ -7,7 +7,8 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_CC_H #define GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_CC_H -void GLFromCPPTestFunction(); +void GLFromCPPInit(); +void GLFromCPPDraw(); #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_CC_H diff --git a/gpu/command_buffer/client/gles2_lib.cc b/gpu/command_buffer/client/gles2_lib.cc index 003a4cc..5753715 100644 --- a/gpu/command_buffer/client/gles2_lib.cc +++ b/gpu/command_buffer/client/gles2_lib.cc @@ -16,6 +16,7 @@ void Initialize() { void Terminate() { gpu::ThreadLocalFree(g_gl_context_key); + g_gl_context_key = 0; } gpu::gles2::GLES2Implementation* GetGLContext() { diff --git a/gpu/command_buffer/common/constants.h b/gpu/command_buffer/common/constants.h index b208153..2359bea 100644 --- a/gpu/command_buffer/common/constants.h +++ b/gpu/command_buffer/common/constants.h @@ -20,6 +20,7 @@ namespace error { kOutOfBounds, kUnknownCommand, kInvalidArguments, + kLostContext, kGenericError }; } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index ddfc358..684e579 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -1549,8 +1549,6 @@ void GLES2DecoderImpl::DoLinkProgram(GLuint program) { } }; -// NOTE: If you need to know the results of SwapBuffers (like losing -// the context) then add a new command. Do NOT make SwapBuffers synchronous. void GLES2DecoderImpl::DoSwapBuffers() { #if defined(UNIT_TEST) #elif defined(OS_WIN) diff --git a/gpu/demos/framework/plugin.cc b/gpu/demos/framework/plugin.cc index 153cd97..0514f81 100644 --- a/gpu/demos/framework/plugin.cc +++ b/gpu/demos/framework/plugin.cc @@ -7,12 +7,13 @@ #include "base/logging.h" #include "gpu/demos/framework/demo_factory.h" +using gpu::demos::Plugin; + namespace { const int32 kCommandBufferSize = 1024 * 1024; NPExtensions* g_extensions = NULL; // Plugin class functions. -using gpu::demos::Plugin; NPObject* PluginAllocate(NPP npp, NPClass* the_class) { Plugin* plugin = new Plugin(npp); return plugin; @@ -97,7 +98,7 @@ Plugin::~Plugin() { demo_.reset(); pglMakeCurrent(NULL); - pglDestroyContext(pgl_context_); + DestroyContext(); } NPClass* Plugin::GetPluginClass() { @@ -116,20 +117,10 @@ void Plugin::New(NPMIMEType pluginType, } void Plugin::SetWindow(const NPWindow& window) { - if (!pgl_context_) { - // Initialize a 3D context. - NPDeviceContext3DConfig config; - config.commandBufferSize = kCommandBufferSize; - device3d_->initializeContext(npp_, &config, &context3d_); - - // Create a PGL context. - pgl_context_ = pglCreateContext(npp_, device3d_, &context3d_); + demo_->InitWindowSize(window.width, window.height); - // Initialize demo. - pglMakeCurrent(pgl_context_); - demo_->InitWindowSize(window.width, window.height); - CHECK(demo_->InitGL()); - pglMakeCurrent(NULL); + if (!pgl_context_) { + CreateContext(); } // Schedule the first call to Draw. @@ -137,8 +128,12 @@ void Plugin::SetWindow(const NPWindow& window) { } void Plugin::Paint() { - // Render some stuff. - pglMakeCurrent(pgl_context_); + if (!pglMakeCurrent(pgl_context_) && pglGetError() == PGL_CONTEXT_LOST) { + DestroyContext(); + CreateContext(); + pglMakeCurrent(pgl_context_); + } + demo_->Draw(); pglSwapBuffers(); pglMakeCurrent(NULL); @@ -147,5 +142,31 @@ void Plugin::Paint() { g_browser->pluginthreadasynccall(npp_, PaintCallback, this); } +void Plugin::CreateContext() { + DCHECK(!pgl_context_); + + // Initialize a 3D context. + NPDeviceContext3DConfig config; + config.commandBufferSize = kCommandBufferSize; + device3d_->initializeContext(npp_, &config, &context3d_); + + // Create a PGL context. + pgl_context_ = pglCreateContext(npp_, device3d_, &context3d_); + + // Initialize demo. + pglMakeCurrent(pgl_context_); + CHECK(demo_->InitGL()); + pglMakeCurrent(NULL); +} + +void Plugin::DestroyContext() { + DCHECK(pgl_context_); + + pglDestroyContext(pgl_context_); + pgl_context_ = NULL; + + device3d_->destroyContext(npp_, &context3d_); +} + } // namespace demos } // namespace gpu diff --git a/gpu/demos/framework/plugin.h b/gpu/demos/framework/plugin.h index 7832d3b..0f4b55e 100644 --- a/gpu/demos/framework/plugin.h +++ b/gpu/demos/framework/plugin.h @@ -31,6 +31,9 @@ class Plugin : public NPObject { void Paint(); private: + void CreateContext(); + void DestroyContext(); + // This class object needs to be safely casted to NPObject* and cross // c-c++ module boundaries. To accomplish that this class should not have // any virtual member function. 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 diff --git a/third_party/npapi/bindings/npapi_extensions.h b/third_party/npapi/bindings/npapi_extensions.h index 1b775ba..b80e0bd 100644 --- a/third_party/npapi/bindings/npapi_extensions.h +++ b/third_party/npapi/bindings/npapi_extensions.h @@ -272,11 +272,26 @@ typedef struct _NPDeviceContext3DConfig { } NPDeviceContext3DConfig; typedef enum _NPDeviceContext3DError { + // No error has ocurred. NPDeviceContext3DError_NoError, + + // The size of a command was invalid. NPDeviceContext3DError_InvalidSize, + + // An offset was out of bounds. NPDeviceContext3DError_OutOfBounds, + + // A command was not recognized. NPDeviceContext3DError_UnknownCommand, + + // The arguments to a command were invalid. NPDeviceContext3DError_InvalidArguments, + + // The 3D context was lost, for example due to a power management event. The + // context must be destroyed and a new one created. + NPDeviceContext3DError_LostContext, + + // Any other error. NPDeviceContext3DError_GenericError } NPDeviceContext3DError; diff --git a/webkit/tools/pepper_test_plugin/plugin_object.cc b/webkit/tools/pepper_test_plugin/plugin_object.cc index 013702b..6880099 100644 --- a/webkit/tools/pepper_test_plugin/plugin_object.cc +++ b/webkit/tools/pepper_test_plugin/plugin_object.cc @@ -309,6 +309,11 @@ PluginObject::PluginObject(NPP npp) } PluginObject::~PluginObject() { +#if !defined(INDEPENDENT_PLUGIN) + if (pgl_context_) + Destroy3D(); +#endif + // TODO(kbr): add audio portion of test #if !defined(OS_MACOSX) deviceaudio_->destroyContext(npp_, &context_audio_); @@ -359,10 +364,10 @@ void PluginObject::New(NPMIMEType pluginType, } void PluginObject::SetWindow(const NPWindow& window) { - if (dimensions_ == 2) { - width_ = window.width; - height_ = window.height; + width_ = window.width; + height_ = window.height; + if (dimensions_ == 2) { NPDeviceContext2DConfig config; NPDeviceContext2D context; device2d_->initializeContext(npp_, &config, &context); @@ -376,20 +381,8 @@ void PluginObject::SetWindow(const NPWindow& window) { device2d_->flushContext(npp_, &context, callback, NULL); } else { #if !defined(INDEPENDENT_PLUGIN) - if (!pgl_context_) { - // Initialize a 3D context. - NPDeviceContext3DConfig config; - config.commandBufferSize = kCommandBufferSize; - device3d_->initializeContext(npp_, &config, &context3d_); - - // Create a PGL context. - pgl_context_ = pglCreateContext(npp_, device3d_, &context3d_); - } - - // Reset the viewport to new window size. - pglMakeCurrent(pgl_context_); - glViewport(0, 0, window.width, window.height); - pglMakeCurrent(NULL); + if (!pgl_context_) + Initialize3D(); // Schedule the first call to Draw. browser->pluginthreadasynccall(npp_, Draw3DCallback, this); @@ -413,15 +406,52 @@ void PluginObject::SetWindow(const NPWindow& window) { #endif } -void PluginObject::Draw3D() { +void PluginObject::Initialize3D() { #if !defined(INDEPENDENT_PLUGIN) - // Render some stuff. + DCHECK(!pgl_context_); + + // Initialize a 3D context. + NPDeviceContext3DConfig config; + config.commandBufferSize = kCommandBufferSize; + device3d_->initializeContext(npp_, &config, &context3d_); + + // Create a PGL context. + pgl_context_ = pglCreateContext(npp_, device3d_, &context3d_); + + // Initialize the demo GL state. pglMakeCurrent(pgl_context_); - GLFromCPPTestFunction(); + GLFromCPPInit(); + pglMakeCurrent(NULL); +#endif // INDEPENDENT_PLUGIN +} + +void PluginObject::Destroy3D() { +#if !defined(INDEPENDENT_PLUGIN) + DCHECK(pgl_context_); + + // Destroy the PGL context. + pglDestroyContext(pgl_context_); + pgl_context_ = NULL; + + // Destroy the Device3D context. + device3d_->destroyContext(npp_, &context3d_); +#endif // INDEPENDENT_PLUGIN +} + +void PluginObject::Draw3D() { +#if !defined(INDEPENDENT_PLUGIN) + if (!pglMakeCurrent(pgl_context_) && pglGetError() == PGL_CONTEXT_LOST) { + Destroy3D(); + Initialize3D(); + pglMakeCurrent(pgl_context_); + } + + glViewport(0, 0, width_, height_); + GLFromCPPDraw(); pglSwapBuffers(); pglMakeCurrent(NULL); // Schedule another call to Draw. browser->pluginthreadasynccall(npp_, Draw3DCallback, this); -#endif +#endif // INDEPENDENT_PLUGIN } diff --git a/webkit/tools/pepper_test_plugin/plugin_object.h b/webkit/tools/pepper_test_plugin/plugin_object.h index 1d9970d..73a3277 100644 --- a/webkit/tools/pepper_test_plugin/plugin_object.h +++ b/webkit/tools/pepper_test_plugin/plugin_object.h @@ -47,6 +47,8 @@ class PluginObject { void New(NPMIMEType pluginType, int16 argc, char* argn[], char* argv[]); void SetWindow(const NPWindow& window); + void Initialize3D(); + void Destroy3D(); void Draw3D(); private: |