summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gpu/command_buffer/client/gles2_demo.cc6
-rw-r--r--gpu/command_buffer/client/gles2_demo_c.c2
-rw-r--r--gpu/command_buffer/client/gles2_demo_c.h2
-rw-r--r--gpu/command_buffer/client/gles2_demo_cc.cc73
-rw-r--r--gpu/command_buffer/client/gles2_demo_cc.h3
-rw-r--r--gpu/command_buffer/client/gles2_lib.cc1
-rw-r--r--gpu/command_buffer/common/constants.h1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc2
-rw-r--r--gpu/demos/framework/plugin.cc55
-rw-r--r--gpu/demos/framework/plugin.h3
-rw-r--r--gpu/pgl/pgl.cc85
-rw-r--r--gpu/pgl/pgl.h18
-rw-r--r--third_party/npapi/bindings/npapi_extensions.h15
-rw-r--r--webkit/tools/pepper_test_plugin/plugin_object.cc72
-rw-r--r--webkit/tools/pepper_test_plugin/plugin_object.h2
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: