diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-27 20:30:45 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-27 20:30:45 +0000 |
commit | 1b1bba77bb2fe952a651c07b11d617709ccd2fcf (patch) | |
tree | 2941d33c7ea0f1fc40b10e823771a03f3dcd6287 /gpu/pgl | |
parent | 80ec6548d3f012c9b01e5dd5db39cb78c94c904b (diff) | |
download | chromium_src-1b1bba77bb2fe952a651c07b11d617709ccd2fcf.zip chromium_src-1b1bba77bb2fe952a651c07b11d617709ccd2fcf.tar.gz chromium_src-1b1bba77bb2fe952a651c07b11d617709ccd2fcf.tar.bz2 |
Windows now uses the TLS API instead of __declspec(thread) for client side command buffer code compiled into DLLs. Other platforms use the pthreads API. This is because the __declspec(thread) approach does not on some platforms, including Windows XP and Mac.
This is used for thread local pointers to the GL and PGL contexts. This unfortunate because the PGL and GL APIs do not generally explicitly reference a context. The current context is set with a call to pglMakeCurrent.
An unfortunate consequence is that now in Pepper plugins, every call to a GL function will call TlsGetValue to get the thread's current context, which could have performance issues.
I can't use base::ThreadLocalPointer because this code is compiled into an untrusted NaCl module and we don't want Chromium dependencies.
TEST=try
BUG=none
Review URL: http://codereview.chromium.org/553050
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37300 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/pgl')
-rw-r--r-- | gpu/pgl/pgl.cc | 48 | ||||
-rw-r--r-- | gpu/pgl/pgl.h | 8 |
2 files changed, 51 insertions, 5 deletions
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, |