summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gpu/command_buffer/client/gles2_demo.cc9
-rw-r--r--gpu/command_buffer/client/gles2_lib.cc24
-rw-r--r--gpu/command_buffer/client/gles2_lib.h22
-rw-r--r--gpu/command_buffer/common/thread_local.h61
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_mock.h3
-rw-r--r--gpu/demos/framework/main_pepper.cc3
-rw-r--r--gpu/demos/framework/plugin.cc4
-rw-r--r--gpu/demos/framework/window.cc1
-rw-r--r--gpu/gpu.gyp1
-rw-r--r--gpu/pgl/pgl.cc48
-rw-r--r--gpu/pgl/pgl.h8
-rw-r--r--webkit/tools/pepper_test_plugin/main.cc8
12 files changed, 166 insertions, 26 deletions
diff --git a/gpu/command_buffer/client/gles2_demo.cc b/gpu/command_buffer/client/gles2_demo.cc
index 2b96ba8..9b5977e 100644
--- a/gpu/command_buffer/client/gles2_demo.cc
+++ b/gpu/command_buffer/client/gles2_demo.cc
@@ -77,10 +77,11 @@ bool GLES2Demo::Setup(void* hwnd, int32 size) {
return false;
- gles2::g_gl_impl = new GLES2Implementation(helper,
- transfer_buffer.size,
- transfer_buffer.ptr,
- transfer_buffer_id);
+ gles2::Initialize();
+ gles2::SetGLContext(new GLES2Implementation(helper,
+ transfer_buffer.size,
+ transfer_buffer.ptr,
+ transfer_buffer_id));
return command_buffer.release() != NULL;
}
diff --git a/gpu/command_buffer/client/gles2_lib.cc b/gpu/command_buffer/client/gles2_lib.cc
index cd7cfed..003a4cc 100644
--- a/gpu/command_buffer/client/gles2_lib.cc
+++ b/gpu/command_buffer/client/gles2_lib.cc
@@ -3,11 +3,29 @@
// found in the LICENSE file.
#include "gpu/command_buffer/client/gles2_lib.h"
+#include "gpu/command_buffer/common/thread_local.h"
namespace gles2 {
-
-THREAD_LOCAL ::gpu::gles2::GLES2Implementation* g_gl_impl;
-
+namespace {
+gpu::ThreadLocalKey g_gl_context_key;
+} // namespace anonymous
+
+void Initialize() {
+ g_gl_context_key = gpu::ThreadLocalAlloc();
+}
+
+void Terminate() {
+ gpu::ThreadLocalFree(g_gl_context_key);
+}
+
+gpu::gles2::GLES2Implementation* GetGLContext() {
+ return static_cast<gpu::gles2::GLES2Implementation*>(
+ gpu::ThreadLocalGetValue(g_gl_context_key));
+}
+
+void SetGLContext(gpu::gles2::GLES2Implementation* context) {
+ gpu::ThreadLocalSetValue(g_gl_context_key, context);
+}
} // namespace gles2
diff --git a/gpu/command_buffer/client/gles2_lib.h b/gpu/command_buffer/client/gles2_lib.h
index e2825fa..2242cc8 100644
--- a/gpu/command_buffer/client/gles2_lib.h
+++ b/gpu/command_buffer/client/gles2_lib.h
@@ -9,23 +9,19 @@
#include "gpu/command_buffer/client/gles2_implementation.h"
-#if defined(_MSC_VER)
-#define THREAD_LOCAL __declspec(thread)
-#else
-#define THREAD_LOCAL __thread
-#endif
-
namespace gles2 {
-extern THREAD_LOCAL gpu::gles2::GLES2Implementation* g_gl_impl;
+// Initialize the GLES2 library.
+void Initialize();
+
+// Terminate the GLES2 library.
+void Terminate();
-inline gpu::gles2::GLES2Implementation* GetGLContext() {
- return g_gl_impl;
-}
+// Get the current GL context.
+gpu::gles2::GLES2Implementation* GetGLContext();
-inline void SetGLContext(gpu::gles2::GLES2Implementation* impl) {
- g_gl_impl = impl;
-}
+// Set the current GL context.
+void SetGLContext(gpu::gles2::GLES2Implementation* impl);
} // namespace gles2
diff --git a/gpu/command_buffer/common/thread_local.h b/gpu/command_buffer/common/thread_local.h
new file mode 100644
index 0000000..4981c5d
--- /dev/null
+++ b/gpu/command_buffer/common/thread_local.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Functions for allocating and accessing thread local values via key.
+
+#ifndef GPU_COMMAND_BUFFER_COMMON_THREAD_LOCAL_H_
+#define GPU_COMMAND_BUFFER_COMMON_THREAD_LOCAL_H_
+
+#include <build/build_config.h>
+
+#if defined(OS_WIN)
+#include <windows.h>
+#else
+#include <pthread.h>
+#endif
+
+namespace gpu {
+
+#if defined(OS_WIN)
+typedef DWORD ThreadLocalKey;
+#else
+typedef pthread_key_t ThreadLocalKey;
+#endif
+
+inline ThreadLocalKey ThreadLocalAlloc() {
+#if defined(OS_WIN)
+ return TlsAlloc();
+#else
+ ThreadLocalKey key;
+ pthread_key_create(&key, NULL);
+ return key;
+#endif
+}
+
+inline void ThreadLocalFree(ThreadLocalKey key) {
+#if defined(OS_WIN)
+ TlsFree(key);
+#else
+ pthread_key_delete(key);
+#endif
+}
+
+inline void ThreadLocalSetValue(ThreadLocalKey key, void* value) {
+#if defined(OS_WIN)
+ TlsSetValue(key, value);
+#else
+ pthread_setspecific(key, value);
+#endif
+}
+
+inline void* ThreadLocalGetValue(ThreadLocalKey key) {
+#if defined(OS_WIN)
+ return TlsGetValue(key);
+#else
+ return pthread_getspecific(key);
+#endif
+}
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_COMMON_THREAD_LOCAL_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
index 2edea92..ccedc95 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -18,12 +18,13 @@ class MockGLES2Decoder : public GLES2Decoder {
MockGLES2Decoder() {
ON_CALL(*this, GetCommandName(testing::_))
.WillByDefault(testing::Return(""));
+ ON_CALL(*this, MakeCurrent())
+ .WillByDefault(testing::Return(true));
}
MOCK_METHOD0(Initialize, bool());
MOCK_METHOD0(Destroy, void());
MOCK_METHOD0(MakeCurrent, bool());
- MOCK_METHOD0(ReleaseCurrent, void());
MOCK_METHOD1(GetServiceIdForTesting, uint32(uint32 client_id));
MOCK_METHOD3(DoCommand, parse_error::ParseError(unsigned int command,
unsigned int arg_count,
diff --git a/gpu/demos/framework/main_pepper.cc b/gpu/demos/framework/main_pepper.cc
index d97cbd0..4d4ae4e 100644
--- a/gpu/demos/framework/main_pepper.cc
+++ b/gpu/demos/framework/main_pepper.cc
@@ -5,6 +5,7 @@
#include "base/at_exit.h"
#include "base/logging.h"
#include "gpu/demos/framework/plugin.h"
+#include "gpu/pgl/pgl.h"
#include "webkit/glue/plugins/nphostapi.h"
namespace {
@@ -139,10 +140,12 @@ NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* plugin_funcs) {
NPError API_CALL NP_Initialize(NPNetscapeFuncs* browser_funcs) {
g_at_exit_manager_ = new base::AtExitManager();
gpu::demos::g_browser = browser_funcs;
+ pglInitialize();
return NPERR_NO_ERROR;
}
void API_CALL NP_Shutdown() {
+ pglTerminate();
delete g_at_exit_manager_;
}
} // extern "C"
diff --git a/gpu/demos/framework/plugin.cc b/gpu/demos/framework/plugin.cc
index b5278b1..dafcffe 100644
--- a/gpu/demos/framework/plugin.cc
+++ b/gpu/demos/framework/plugin.cc
@@ -92,7 +92,11 @@ Plugin::Plugin(NPP npp)
}
Plugin::~Plugin() {
+ // Destroy demo while GL context is current and before it is destroyed.
+ pglMakeCurrent(pgl_context_);
+ demo_.reset();
pglMakeCurrent(NULL);
+
pglDestroyContext(pgl_context_);
}
diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc
index 6833feb..41538d5 100644
--- a/gpu/demos/framework/window.cc
+++ b/gpu/demos/framework/window.cc
@@ -117,6 +117,7 @@ bool InitRenderContext(HWND hwnd) {
command_buffer->GetTransferBuffer(transfer_buffer_id);
if (transfer_buffer.ptr == NULL) return false;
+ gles2::Initialize();
gles2::SetGLContext(new GLES2Implementation(helper,
transfer_buffer.size,
transfer_buffer.ptr,
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index 38e8059..dd98c60 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -114,6 +114,7 @@
'command_buffer/common/mocks.h',
'command_buffer/common/resource.cc',
'command_buffer/common/resource.h',
+ 'command_buffer/common/thread_local.h',
'command_buffer/common/types.h',
],
},
diff --git a/gpu/pgl/pgl.cc b/gpu/pgl/pgl.cc
index 2fd3d8b..41903e1 100644
--- a/gpu/pgl/pgl.cc
+++ b/gpu/pgl/pgl.cc
@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <build/build_config.h>
+
#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/thread_local.h"
#include "gpu/pgl/command_buffer_pepper.h"
#include "gpu/pgl/pgl.h"
@@ -43,7 +46,7 @@ class PGLContextImpl {
gpu::gles2::GLES2Implementation* gles2_implementation_;
};
-THREAD_LOCAL PGLContextImpl* g_current_pgl_context;
+gpu::ThreadLocalKey g_pgl_context_key;
PGLContextImpl::PGLContextImpl(NPP npp,
NPDevice* device,
@@ -103,7 +106,10 @@ void PGLContextImpl::Destroy() {
}
bool PGLContextImpl::MakeCurrent(PGLContextImpl* pgl_context) {
- g_current_pgl_context = pgl_context;
+ if (!g_pgl_context_key)
+ return false;
+
+ gpu::ThreadLocalSetValue(g_pgl_context_key, pgl_context);
if (pgl_context)
gles2::SetGLContext(pgl_context->gles2_implementation_);
else
@@ -120,9 +126,30 @@ bool PGLContextImpl::SwapBuffers() {
extern "C" {
+PGLBoolean pglInitialize() {
+ if (g_pgl_context_key)
+ return true;
+
+ gles2::Initialize();
+ g_pgl_context_key = gpu::ThreadLocalAlloc();
+ return true;
+}
+
+PGLBoolean pglTerminate() {
+ if (!g_pgl_context_key)
+ return true;
+
+ gpu::ThreadLocalFree(g_pgl_context_key);
+ gles2::Terminate();
+ return true;
+}
+
PGLContext pglCreateContext(NPP npp,
NPDevice* device,
NPDeviceContext3D* device_context) {
+ if (!g_pgl_context_key)
+ return NULL;
+
PGLContextImpl* pgl_context = new PGLContextImpl(
npp, device, device_context);
if (pgl_context->Initialize(kTransferBufferSize)) {
@@ -138,20 +165,31 @@ PGLBoolean pglMakeCurrent(PGLContext pgl_context) {
}
PGLContext pglGetCurrentContext(void) {
- return g_current_pgl_context;
+ if (!g_pgl_context_key)
+ return NULL;
+
+ return static_cast<PGLContext>(gpu::ThreadLocalGetValue(g_pgl_context_key));
}
PGLBoolean pglSwapBuffers(void) {
- if (!g_current_pgl_context)
+ PGLContextImpl* context = static_cast<PGLContextImpl*>(
+ pglGetCurrentContext());
+ if (!context)
return false;
- return g_current_pgl_context->SwapBuffers();
+ return context->SwapBuffers();
}
PGLBoolean pglDestroyContext(PGLContext pgl_context) {
+ if (!g_pgl_context_key)
+ return NULL;
+
if (!pgl_context)
return false;
+ if (pgl_context == pglGetCurrentContext())
+ pglMakeCurrent(NULL);
+
delete static_cast<PGLContextImpl*>(pgl_context);
return true;
}
diff --git a/gpu/pgl/pgl.h b/gpu/pgl/pgl.h
index f848968..3a7735e 100644
--- a/gpu/pgl/pgl.h
+++ b/gpu/pgl/pgl.h
@@ -15,6 +15,14 @@ extern "C" {
typedef void* PGLContext;
typedef bool PGLBoolean;
+// Initialize the PGL library. This must have completed before any other PGL
+// functions are invoked.
+PGLBoolean pglInitialize();
+
+// Terminate the PGL library. This must be called after any other PGL functions
+// have completed.
+PGLBoolean pglTerminate();
+
// Create A PGL context from a Pepper 3D device context.
PGLContext pglCreateContext(NPP npp,
NPDevice* device,
diff --git a/webkit/tools/pepper_test_plugin/main.cc b/webkit/tools/pepper_test_plugin/main.cc
index 851674c..81c963d 100644
--- a/webkit/tools/pepper_test_plugin/main.cc
+++ b/webkit/tools/pepper_test_plugin/main.cc
@@ -34,6 +34,8 @@
#include <stdlib.h>
#include <stdio.h>
+#include "gpu/pgl/pgl.h"
+
#if defined(INDEPENDENT_PLUGIN)
#include <iostream>
#define LOG(x) std::cerr
@@ -118,6 +120,9 @@ EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* browser_funcs
EXPORT NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* plugin_funcs);
EXPORT void API_CALL NP_Shutdown() {
+#if !defined(INDEPENDENT_PLUGIN)
+ pglTerminate();
+#endif
}
#if defined(OS_LINUX)
@@ -136,6 +141,9 @@ EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* browser_funcs
#endif
) {
browser = browser_funcs;
+#if !defined(INDEPENDENT_PLUGIN)
+ pglInitialize();
+#endif
#if defined(OS_LINUX)
return NP_GetEntryPoints(plugin_funcs);
#else