summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-27 20:30:45 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-27 20:30:45 +0000
commit1b1bba77bb2fe952a651c07b11d617709ccd2fcf (patch)
tree2941d33c7ea0f1fc40b10e823771a03f3dcd6287 /gpu/command_buffer
parent80ec6548d3f012c9b01e5dd5db39cb78c94c904b (diff)
downloadchromium_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/command_buffer')
-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
5 files changed, 98 insertions, 21 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,