summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-16 20:54:53 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-16 20:54:53 +0000
commit7196e011d46f597b406e43a1978fa9d846e747c4 (patch)
treeb13701827207e5a223c9a916bdd90d6ca892e6d8
parentc59aa47960369c63ac773d5cf4b2d1052d4a69c3 (diff)
downloadchromium_src-7196e011d46f597b406e43a1978fa9d846e747c4.zip
chromium_src-7196e011d46f597b406e43a1978fa9d846e747c4.tar.gz
chromium_src-7196e011d46f597b406e43a1978fa9d846e747c4.tar.bz2
Automatically put all GL contexts associated with a particular GPU channel (and renderer process) in the same share group.
This is work towards allowing offscreen canvas contexts to be allocated before compositor view contexts are created. This is a problem because a canvas might be created before the window it will be displayed in exists. This does not fix the bug on its own. BUG=80703 Review URL: http://codereview.chromium.org/7104148 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@89395 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/common/gpu/gpu_channel.cc1
-rw-r--r--content/common/gpu/gpu_channel.h8
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc3
-rw-r--r--content/gpu/gpu_info_collector.cc4
-rw-r--r--gpu/command_buffer/client/gles2_demo.cc3
-rw-r--r--gpu/command_buffer/service/gpu_scheduler.h4
-rw-r--r--gpu/command_buffer/service/gpu_scheduler_linux.cc20
-rw-r--r--gpu/command_buffer/service/gpu_scheduler_mac.cc12
-rw-r--r--gpu/command_buffer/service/gpu_scheduler_win.cc12
-rw-r--r--gpu/demos/framework/window.cc4
-rw-r--r--gpu/gles2_conform_support/egl/display.cc2
-rw-r--r--ui/gfx/gl/gl.gyp2
-rw-r--r--ui/gfx/gl/gl_context.cc11
-rw-r--r--ui/gfx/gl/gl_context.h13
-rw-r--r--ui/gfx/gl/gl_context_cgl.cc12
-rw-r--r--ui/gfx/gl/gl_context_cgl.h5
-rw-r--r--ui/gfx/gl/gl_context_egl.cc10
-rw-r--r--ui/gfx/gl/gl_context_egl.h5
-rw-r--r--ui/gfx/gl/gl_context_glx.cc19
-rw-r--r--ui/gfx/gl/gl_context_glx.h5
-rw-r--r--ui/gfx/gl/gl_context_linux.cc16
-rw-r--r--ui/gfx/gl/gl_context_mac.cc12
-rw-r--r--ui/gfx/gl/gl_context_osmesa.cc15
-rw-r--r--ui/gfx/gl/gl_context_osmesa.h6
-rw-r--r--ui/gfx/gl/gl_context_stub.cc5
-rw-r--r--ui/gfx/gl/gl_context_stub.h3
-rw-r--r--ui/gfx/gl/gl_context_wgl.cc23
-rw-r--r--ui/gfx/gl/gl_context_wgl.h5
-rw-r--r--ui/gfx/gl/gl_context_win.cc14
-rw-r--r--ui/gfx/gl/gl_share_group.cc36
-rw-r--r--ui/gfx/gl/gl_share_group.h45
-rw-r--r--ui/gfx/surface/accelerated_surface_mac.cc6
-rw-r--r--webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc10
-rw-r--r--webkit/gpu/webgraphicscontext3d_in_process_impl.cc8
34 files changed, 236 insertions, 123 deletions
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc
index dbb8e6a..0031602 100644
--- a/content/common/gpu/gpu_channel.cc
+++ b/content/common/gpu/gpu_channel.cc
@@ -33,6 +33,7 @@ GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
renderer_id_(renderer_id),
renderer_process_(base::kNullProcessHandle),
renderer_pid_(base::kNullProcessId),
+ share_group_(new gfx::GLShareGroup),
watchdog_(watchdog) {
DCHECK(gpu_channel_manager);
DCHECK(renderer_id);
diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h
index a7bf112..10b2315 100644
--- a/content/common/gpu/gpu_channel.h
+++ b/content/common/gpu/gpu_channel.h
@@ -11,6 +11,7 @@
#include <vector>
#include "base/id_map.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/process.h"
#include "build/build_config.h"
@@ -19,6 +20,7 @@
#include "content/common/gpu/gpu_surface_stub.h"
#include "content/common/message_router.h"
#include "ipc/ipc_sync_channel.h"
+#include "ui/gfx/gl/gl_share_group.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
@@ -84,6 +86,8 @@ class GpuChannel : public IPC::Channel::Listener,
void ViewResized(int32 command_buffer_route_id);
+ gfx::GLShareGroup* share_group() const { return share_group_.get(); }
+
#if defined(OS_MACOSX)
virtual void AcceleratedSurfaceBuffersSwapped(
int32 route_id, uint64 swap_buffers_count);
@@ -156,6 +160,10 @@ class GpuChannel : public IPC::Channel::Listener,
// Used to implement message routing functionality to CommandBuffer objects
MessageRouter router_;
+ // The share group that all contexts associated with a particular renderer
+ // process use.
+ scoped_refptr<gfx::GLShareGroup> share_group_;
+
#if defined(ENABLE_GPU)
typedef IDMap<GpuCommandBufferStub, IDMapOwnPointer> StubMap;
StubMap stubs_;
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index a677337..a88161d 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -144,7 +144,8 @@ void GpuCommandBufferStub::OnInitialize(
allowed_extensions_.c_str(),
requested_attribs_,
parent_processor,
- parent_texture_id_)) {
+ parent_texture_id_,
+ channel_->share_group())) {
command_buffer_->SetPutOffsetChangeCallback(
NewCallback(scheduler_.get(),
&gpu::GpuScheduler::PutChanged));
diff --git a/content/gpu/gpu_info_collector.cc b/content/gpu/gpu_info_collector.cc
index 2e4630b..93cd767 100644
--- a/content/gpu/gpu_info_collector.cc
+++ b/content/gpu/gpu_info_collector.cc
@@ -31,8 +31,8 @@ scoped_refptr<gfx::GLSurface> InitializeGLSurface() {
scoped_refptr<gfx::GLContext> InitializeGLContext(gfx::GLSurface* surface) {
- scoped_refptr<gfx::GLContext> context(gfx::GLContext::CreateGLContext(NULL,
- surface));
+ scoped_refptr<gfx::GLContext> context(
+ gfx::GLContext::CreateGLContext(NULL, surface));
if (!context.get()) {
LOG(ERROR) << "gfx::GLContext::CreateGLContext failed";
return NULL;
diff --git a/gpu/command_buffer/client/gles2_demo.cc b/gpu/command_buffer/client/gles2_demo.cc
index 90825b09..b95a2c2 100644
--- a/gpu/command_buffer/client/gles2_demo.cc
+++ b/gpu/command_buffer/client/gles2_demo.cc
@@ -65,7 +65,8 @@ bool GLES2Demo::Setup(void* hwnd, int32 size) {
NULL,
std::vector<int32>(),
NULL,
- 0)) {
+ 0,
+ NULL)) {
return NULL;
}
diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h
index 7f74734..78845df 100644
--- a/gpu/command_buffer/service/gpu_scheduler.h
+++ b/gpu/command_buffer/service/gpu_scheduler.h
@@ -27,6 +27,7 @@
namespace gfx {
class GLContext;
+class GLShareGroup;
class GLSurface;
}
@@ -63,7 +64,8 @@ class GpuScheduler : public CommandBufferEngine {
const char* allowed_extensions,
const std::vector<int32>& attribs,
GpuScheduler* parent,
- uint32 parent_texture_id);
+ uint32 parent_texture_id,
+ gfx::GLShareGroup* share_group);
void Destroy();
void DestroyCommon();
diff --git a/gpu/command_buffer/service/gpu_scheduler_linux.cc b/gpu/command_buffer/service/gpu_scheduler_linux.cc
index f1d49da..84d821e 100644
--- a/gpu/command_buffer/service/gpu_scheduler_linux.cc
+++ b/gpu/command_buffer/service/gpu_scheduler_linux.cc
@@ -4,6 +4,7 @@
#include "gpu/command_buffer/service/gpu_scheduler.h"
#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/gl/gl_share_group.h"
#include "ui/gfx/gl/gl_surface.h"
using ::base::SharedMemory;
@@ -17,28 +18,21 @@ bool GpuScheduler::Initialize(
const char* allowed_extensions,
const std::vector<int32>& attribs,
GpuScheduler* parent,
- uint32 parent_texture_id) {
- // Get the parent decoder and the GLContext to share IDs with, if any.
+ uint32 parent_texture_id,
+ gfx::GLShareGroup* share_group) {
+ // Get the parent decoder.
gles2::GLES2Decoder* parent_decoder = NULL;
- gfx::GLContext* parent_context = NULL;
- void* parent_handle = NULL;
if (parent) {
parent_decoder = parent->decoder_.get();
DCHECK(parent_decoder);
-
- parent_context = parent_decoder->GetGLContext();
- DCHECK(parent_context);
}
// Create either a view or pbuffer based GLSurface.
scoped_refptr<gfx::GLSurface> surface;
- if (window) {
- DCHECK(!parent_handle);
-
+ if (window)
surface = gfx::GLSurface::CreateViewGLSurface(window);
- } else {
+ else
surface = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
- }
if (!surface.get()) {
LOG(ERROR) << "GpuScheduler::Initialize failed.\n";
@@ -48,7 +42,7 @@ bool GpuScheduler::Initialize(
// Create a GLContext and attach the surface.
scoped_refptr<gfx::GLContext> context(
- gfx::GLContext::CreateGLContext(parent_context, surface.get()));
+ gfx::GLContext::CreateGLContext(share_group, surface.get()));
if (!context.get()) {
LOG(ERROR) << "CreateGLContext failed.\n";
Destroy();
diff --git a/gpu/command_buffer/service/gpu_scheduler_mac.cc b/gpu/command_buffer/service/gpu_scheduler_mac.cc
index 449a90f..0e4d8d6 100644
--- a/gpu/command_buffer/service/gpu_scheduler_mac.cc
+++ b/gpu/command_buffer/service/gpu_scheduler_mac.cc
@@ -4,6 +4,7 @@
#include "gpu/command_buffer/service/gpu_scheduler.h"
#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/gl/gl_share_group.h"
#include "ui/gfx/gl/gl_surface.h"
using ::base::SharedMemory;
@@ -17,16 +18,13 @@ bool GpuScheduler::Initialize(
const char* allowed_extensions,
const std::vector<int32>& attribs,
GpuScheduler* parent,
- uint32 parent_texture_id) {
- // Get the parent decoder and the GLContext to share IDs with, if any.
+ uint32 parent_texture_id,
+ gfx::GLShareGroup* share_group) {
+ // Get the parent decoder.
gles2::GLES2Decoder* parent_decoder = NULL;
- gfx::GLContext* parent_context = NULL;
if (parent) {
parent_decoder = parent->decoder_.get();
DCHECK(parent_decoder);
-
- parent_context = parent_decoder->GetGLContext();
- DCHECK(parent_context);
}
scoped_refptr<gfx::GLSurface> surface(
@@ -39,7 +37,7 @@ bool GpuScheduler::Initialize(
// Create a GLContext and attach the surface.
scoped_refptr<gfx::GLContext> context(
- gfx::GLContext::CreateGLContext(parent_context, surface.get()));
+ gfx::GLContext::CreateGLContext(share_group, surface.get()));
if (!context.get()) {
LOG(ERROR) << "CreateGLContext failed.\n";
Destroy();
diff --git a/gpu/command_buffer/service/gpu_scheduler_win.cc b/gpu/command_buffer/service/gpu_scheduler_win.cc
index 81ab10b..a92d225 100644
--- a/gpu/command_buffer/service/gpu_scheduler_win.cc
+++ b/gpu/command_buffer/service/gpu_scheduler_win.cc
@@ -6,6 +6,7 @@
#include "gpu/command_buffer/service/gpu_scheduler.h"
#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/gl/gl_share_group.h"
#include "ui/gfx/gl/gl_surface.h"
using ::base::SharedMemory;
@@ -19,16 +20,13 @@ bool GpuScheduler::Initialize(
const char* allowed_extensions,
const std::vector<int32>& attribs,
GpuScheduler* parent,
- uint32 parent_texture_id) {
- // Get the parent decoder and the GLContext to share IDs with, if any.
+ uint32 parent_texture_id,
+ gfx::GLShareGroup* share_group) {
+ // Get the parent decoder.
gles2::GLES2Decoder* parent_decoder = NULL;
- gfx::GLContext* parent_context = NULL;
if (parent) {
parent_decoder = parent->decoder_.get();
DCHECK(parent_decoder);
-
- parent_context = parent_decoder->GetGLContext();
- DCHECK(parent_context);
}
// Create either a view or pbuffer based GLSurface.
@@ -47,7 +45,7 @@ bool GpuScheduler::Initialize(
// Create a GLContext and attach the surface.
scoped_refptr<gfx::GLContext> context(
- gfx::GLContext::CreateGLContext(parent_context, surface.get()));
+ gfx::GLContext::CreateGLContext(share_group, surface.get()));
if (!context.get()) {
LOG(ERROR) << "CreateGLContext failed.\n";
Destroy();
diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc
index 4cbfbf6..01ce0d8 100644
--- a/gpu/demos/framework/window.cc
+++ b/gpu/demos/framework/window.cc
@@ -64,7 +64,9 @@ bool Window::CreateRenderContext(gfx::PluginWindowHandle hwnd) {
if (!gpu_scheduler->Initialize(hwnd, gfx::Size(),
gpu::gles2::DisallowedExtensions(),
NULL, std::vector<int32>(),
- NULL, 0)) {
+ NULL,
+ 0,
+ NULL)) {
return false;
}
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
index 2308196..3f18c7e 100644
--- a/gpu/gles2_conform_support/egl/display.cc
+++ b/gpu/gles2_conform_support/egl/display.cc
@@ -112,7 +112,7 @@ EGLSurface Display::CreateWindowSurface(EGLConfig config,
new GpuScheduler(command_buffer_.get(), NULL, NULL));
if (!gpu_scheduler->Initialize(
win, gfx::Size(), gpu::gles2::DisallowedExtensions(), NULL,
- attribs, NULL, 0))
+ attribs, NULL, 0, NULL))
return EGL_NO_SURFACE;
command_buffer_->SetPutOffsetChangeCallback(
diff --git a/ui/gfx/gl/gl.gyp b/ui/gfx/gl/gl.gyp
index 507c4e5..5da7cf3 100644
--- a/ui/gfx/gl/gl.gyp
+++ b/ui/gfx/gl/gl.gyp
@@ -74,6 +74,8 @@
'gl_implementation_win.cc',
'gl_interface.cc',
'gl_interface.h',
+ 'gl_share_group.cc',
+ 'gl_share_group.h',
'gl_surface.cc',
'gl_surface.h',
'gl_surface_linux.cc',
diff --git a/ui/gfx/gl/gl_context.cc b/ui/gfx/gl/gl_context.cc
index 9cf1e40..c19741f 100644
--- a/ui/gfx/gl/gl_context.cc
+++ b/ui/gfx/gl/gl_context.cc
@@ -13,10 +13,15 @@
namespace gfx {
-GLContext::GLContext() {
+GLContext::GLContext(GLShareGroup* share_group) : share_group_(share_group) {
+ if (!share_group_.get())
+ share_group_ = new GLShareGroup;
+
+ share_group_->AddContext(this);
}
GLContext::~GLContext() {
+ share_group_->RemoveContext(this);
}
std::string GLContext::GetExtensions() {
@@ -35,6 +40,10 @@ bool GLContext::HasExtension(const char* name) {
return extensions.find(delimited_name) != std::string::npos;
}
+GLShareGroup* GLContext::share_group() {
+ return share_group_.get();
+}
+
bool GLContext::LosesAllContextsOnContextLost()
{
switch (GetGLImplementation()) {
diff --git a/ui/gfx/gl/gl_context.h b/ui/gfx/gl/gl_context.h
index 77f167f..2159423 100644
--- a/ui/gfx/gl/gl_context.h
+++ b/ui/gfx/gl/gl_context.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
+#include "ui/gfx/gl/gl_share_group.h"
namespace gfx {
@@ -18,14 +19,13 @@ class GLSurface;
// Encapsulates an OpenGL context, hiding platform specific management.
class GLContext : public base::RefCounted<GLContext> {
public:
- GLContext();
+ explicit GLContext(GLShareGroup* share_group);
// Initializes the GL context to be compatible with the given surface. The GL
// context can be made with other surface's of the same type. The compatible
// surface is only needed for certain platforms like WGL, OSMesa and GLX. It
// should be specific for all platforms though.
- virtual bool Initialize(GLContext* shared_context,
- GLSurface* compatible_surface) = 0;
+ virtual bool Initialize(GLSurface* compatible_surface) = 0;
// Destroys the GL context.
virtual void Destroy() = 0;
@@ -53,11 +53,13 @@ class GLContext : public base::RefCounted<GLContext> {
// context must be current.
bool HasExtension(const char* name);
+ GLShareGroup* share_group();
+
// Create a GL context that is compatible with the given surface.
- // |share_context|, if non-NULL, is a context which the
+ // |share_group|, if non-NULL, is a group of contexts which the
// internally created OpenGL context shares textures and other resources.
static scoped_refptr<GLContext> CreateGLContext(
- GLContext* shared_context,
+ GLShareGroup* share_group,
GLSurface* compatible_surface);
static bool LosesAllContextsOnContextLost();
@@ -66,6 +68,7 @@ class GLContext : public base::RefCounted<GLContext> {
virtual ~GLContext();
private:
+ scoped_refptr<GLShareGroup> share_group_;
friend class base::RefCounted<GLContext>;
DISALLOW_COPY_AND_ASSIGN(GLContext);
};
diff --git a/ui/gfx/gl/gl_context_cgl.cc b/ui/gfx/gl/gl_context_cgl.cc
index 8d3d819..1629cec 100644
--- a/ui/gfx/gl/gl_context_cgl.cc
+++ b/ui/gfx/gl/gl_context_cgl.cc
@@ -10,22 +10,22 @@
namespace gfx {
-GLContextCGL::GLContextCGL()
- : context_(NULL) {
+GLContextCGL::GLContextCGL(GLShareGroup* share_group)
+ : GLContext(share_group),
+ context_(NULL) {
}
GLContextCGL::~GLContextCGL() {
Destroy();
}
-bool GLContextCGL::Initialize(GLContext* shared_context,
- GLSurface* compatible_surface) {
+bool GLContextCGL::Initialize(GLSurface* compatible_surface) {
DCHECK(compatible_surface);
CGLError res = CGLCreateContext(
static_cast<CGLPixelFormatObj>(GLSurfaceCGL::GetPixelFormat()),
- shared_context ?
- static_cast<CGLContextObj>(shared_context->GetHandle()) : NULL,
+ share_group() ?
+ static_cast<CGLContextObj>(share_group()->GetHandle()) : NULL,
reinterpret_cast<CGLContextObj*>(&context_));
if (res != kCGLNoError) {
LOG(ERROR) << "Error creating context.";
diff --git a/ui/gfx/gl/gl_context_cgl.h b/ui/gfx/gl/gl_context_cgl.h
index 0ebf558..14b59b3 100644
--- a/ui/gfx/gl/gl_context_cgl.h
+++ b/ui/gfx/gl/gl_context_cgl.h
@@ -11,12 +11,11 @@ class GLSurface;
// Encapsulates a CGL OpenGL context.
class GLContextCGL : public GLContext {
public:
- GLContextCGL();
+ explicit GLContextCGL(GLShareGroup* share_group);
virtual ~GLContextCGL();
// Implement GLContext.
- virtual bool Initialize(GLContext* shared_context,
- GLSurface* compatible_surface);
+ virtual bool Initialize(GLSurface* compatible_surface);
virtual void Destroy();
virtual bool MakeCurrent(GLSurface* surface);
virtual void ReleaseCurrent(GLSurface* surface);
diff --git a/ui/gfx/gl/gl_context_egl.cc b/ui/gfx/gl/gl_context_egl.cc
index 14701c0..63f63e9 100644
--- a/ui/gfx/gl/gl_context_egl.cc
+++ b/ui/gfx/gl/gl_context_egl.cc
@@ -32,8 +32,9 @@ std::string GLContextEGL::GetExtensions() {
return GLContext::GetExtensions() + " " + extensions;
}
-GLContextEGL::GLContextEGL()
- : context_(NULL)
+GLContextEGL::GLContextEGL(GLShareGroup* share_group)
+ : GLContext(share_group),
+ context_(NULL)
{
}
@@ -41,8 +42,7 @@ GLContextEGL::~GLContextEGL() {
Destroy();
}
-bool GLContextEGL::Initialize(GLContext* shared_context,
- GLSurface* compatible_surface) {
+bool GLContextEGL::Initialize(GLSurface* compatible_surface) {
DCHECK(compatible_surface);
DCHECK(!context_);
@@ -54,7 +54,7 @@ bool GLContextEGL::Initialize(GLContext* shared_context,
context_ = eglCreateContext(
GLSurfaceEGL::GetDisplay(),
GLSurfaceEGL::GetConfig(),
- shared_context ? shared_context->GetHandle() : NULL,
+ share_group() ? share_group()->GetHandle() : NULL,
kContextAttributes);
if (!context_) {
LOG(ERROR) << "eglCreateContext failed with error "
diff --git a/ui/gfx/gl/gl_context_egl.h b/ui/gfx/gl/gl_context_egl.h
index 2e8a446..f1a8193 100644
--- a/ui/gfx/gl/gl_context_egl.h
+++ b/ui/gfx/gl/gl_context_egl.h
@@ -19,12 +19,11 @@ class GLSurface;
// Encapsulates an EGL OpenGL ES context.
class GLContextEGL : public GLContext {
public:
- GLContextEGL();
+ explicit GLContextEGL(GLShareGroup* share_group);
virtual ~GLContextEGL();
// Implement GLContext.
- virtual bool Initialize(GLContext* shared_context,
- GLSurface* compatible_surface);
+ virtual bool Initialize(GLSurface* compatible_surface);
virtual void Destroy();
virtual bool MakeCurrent(GLSurface* surface);
virtual void ReleaseCurrent(GLSurface* surface);
diff --git a/ui/gfx/gl/gl_context_glx.cc b/ui/gfx/gl/gl_context_glx.cc
index 2625ad6..1b1a355 100644
--- a/ui/gfx/gl/gl_context_glx.cc
+++ b/ui/gfx/gl/gl_context_glx.cc
@@ -44,19 +44,21 @@ bool IsCompositingWindowManagerActive(Display* display) {
} // namespace anonymous
-GLContextGLX::GLContextGLX()
- : context_(NULL) {
+GLContextGLX::GLContextGLX(GLShareGroup* share_group)
+ : GLContext(share_group),
+ context_(NULL) {
}
GLContextGLX::~GLContextGLX() {
Destroy();
}
-bool GLContextGLX::Initialize(GLContext* shared_context,
- GLSurface* compatible_surface) {
+bool GLContextGLX::Initialize(GLSurface* compatible_surface) {
GLSurfaceGLX* surface_glx = static_cast<GLSurfaceGLX*>(compatible_surface);
GLXFBConfig config = static_cast<GLXFBConfig>(surface_glx->GetConfig());
+ GLXContext share_handle = static_cast<GLXContext>(
+ share_group() ? share_group()->GetHandle() : NULL);
// The means by which the context is created depends on whether the drawable
// type works reliably with GLX 1.3. If it does not then fall back to GLX 1.2.
@@ -65,8 +67,7 @@ bool GLContextGLX::Initialize(GLContext* shared_context,
GLSurfaceGLX::GetDisplay(),
static_cast<GLXFBConfig>(surface_glx->GetConfig()),
GLX_RGBA_TYPE,
- static_cast<GLXContext>(
- shared_context ? shared_context->GetHandle() : NULL),
+ share_handle,
True);
} else {
Display* display = GLSurfaceGLX::GetDisplay();
@@ -94,7 +95,11 @@ bool GLContextGLX::Initialize(GLContext* shared_context,
}
// Attempt to create a context with each visual in turn until one works.
- context_ = glXCreateContext(display, visual_info_list.get(), 0, True);
+ context_ = glXCreateContext(
+ display,
+ visual_info_list.get(),
+ share_handle,
+ True);
}
if (!context_) {
diff --git a/ui/gfx/gl/gl_context_glx.h b/ui/gfx/gl/gl_context_glx.h
index 0ee6b1a..e89bcb2 100644
--- a/ui/gfx/gl/gl_context_glx.h
+++ b/ui/gfx/gl/gl_context_glx.h
@@ -13,12 +13,11 @@ class GLSurface;
// Encapsulates a GLX OpenGL context.
class GLContextGLX : public GLContext {
public:
- GLContextGLX();
+ explicit GLContextGLX(GLShareGroup* share_group);
virtual ~GLContextGLX();
// Implement GLContext.
- virtual bool Initialize(GLContext* shared_context,
- GLSurface* compatible_surface);
+ virtual bool Initialize(GLSurface* compatible_surface);
virtual void Destroy();
virtual bool MakeCurrent(GLSurface* surface);
virtual void ReleaseCurrent(GLSurface* surface);
diff --git a/ui/gfx/gl/gl_context_linux.cc b/ui/gfx/gl/gl_context_linux.cc
index 8cf2eeb..238bd5f 100644
--- a/ui/gfx/gl/gl_context_linux.cc
+++ b/ui/gfx/gl/gl_context_linux.cc
@@ -20,27 +20,29 @@
namespace gfx {
+class GLShareGroup;
+
scoped_refptr<GLContext> GLContext::CreateGLContext(
- GLContext* shared_context,
+ GLShareGroup* share_group,
GLSurface* compatible_surface) {
switch (GetGLImplementation()) {
case kGLImplementationOSMesaGL: {
- scoped_refptr<GLContext> context(new GLContextOSMesa);
- if (!context->Initialize(shared_context, compatible_surface))
+ scoped_refptr<GLContext> context(new GLContextOSMesa(share_group));
+ if (!context->Initialize(compatible_surface))
return NULL;
return context;
}
case kGLImplementationEGLGLES2: {
- scoped_refptr<GLContext> context(new GLContextEGL);
- if (!context->Initialize(shared_context, compatible_surface))
+ scoped_refptr<GLContext> context(new GLContextEGL(share_group));
+ if (!context->Initialize(compatible_surface))
return NULL;
return context;
}
case kGLImplementationDesktopGL: {
- scoped_refptr<GLContext> context(new GLContextGLX);
- if (!context->Initialize(shared_context, compatible_surface))
+ scoped_refptr<GLContext> context(new GLContextGLX(share_group));
+ if (!context->Initialize(compatible_surface))
return NULL;
return context;
diff --git a/ui/gfx/gl/gl_context_mac.cc b/ui/gfx/gl/gl_context_mac.cc
index 482d93d..cdfc6f4 100644
--- a/ui/gfx/gl/gl_context_mac.cc
+++ b/ui/gfx/gl/gl_context_mac.cc
@@ -16,20 +16,22 @@
namespace gfx {
+class GLShareGroup;
+
scoped_refptr<GLContext> GLContext::CreateGLContext(
- GLContext* shared_context,
+ GLShareGroup* share_group,
GLSurface* compatible_surface) {
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL: {
- scoped_refptr<GLContext> context(new GLContextCGL);
- if (!context->Initialize(shared_context, compatible_surface))
+ scoped_refptr<GLContext> context(new GLContextCGL(share_group));
+ if (!context->Initialize(compatible_surface))
return NULL;
return context;
}
case kGLImplementationOSMesaGL: {
- scoped_refptr<GLContext> context(new GLContextOSMesa);
- if (!context->Initialize(shared_context, compatible_surface))
+ scoped_refptr<GLContext> context(new GLContextOSMesa(share_group));
+ if (!context->Initialize(compatible_surface))
return NULL;
return context;
diff --git a/ui/gfx/gl/gl_context_osmesa.cc b/ui/gfx/gl/gl_context_osmesa.cc
index 5fe5150..2b45836 100644
--- a/ui/gfx/gl/gl_context_osmesa.cc
+++ b/ui/gfx/gl/gl_context_osmesa.cc
@@ -12,21 +12,20 @@
namespace gfx {
-GLContextOSMesa::GLContextOSMesa()
- : context_(NULL) {
+GLContextOSMesa::GLContextOSMesa(GLShareGroup* share_group)
+ : GLContext(share_group),
+ context_(NULL) {
}
GLContextOSMesa::~GLContextOSMesa() {
Destroy();
}
-bool GLContextOSMesa::Initialize(GLContext* shared_context,
- GLSurface* compatible_surface) {
+bool GLContextOSMesa::Initialize(GLSurface* compatible_surface) {
DCHECK(!context_);
- OSMesaContext shared_handle = NULL;
- if (shared_context)
- shared_handle = static_cast<OSMesaContext>(shared_context->GetHandle());
+ OSMesaContext share_handle = static_cast<OSMesaContext>(
+ share_group() ? share_group()->GetHandle() : NULL);
GLuint format =
static_cast<GLSurfaceOSMesa*>(compatible_surface)->GetFormat();
@@ -34,7 +33,7 @@ bool GLContextOSMesa::Initialize(GLContext* shared_context,
24, // depth bits
8, // stencil bits
0, // accum bits
- shared_handle);
+ share_handle);
if (!context_) {
LOG(ERROR) << "OSMesaCreateContextExt failed.";
return false;
diff --git a/ui/gfx/gl/gl_context_osmesa.h b/ui/gfx/gl/gl_context_osmesa.h
index 633c0ad..6b4c0a9 100644
--- a/ui/gfx/gl/gl_context_osmesa.h
+++ b/ui/gfx/gl/gl_context_osmesa.h
@@ -12,17 +12,17 @@ typedef struct osmesa_context *OSMesaContext;
namespace gfx {
+class GLShareGroup;
class GLSurface;
// Encapsulates an OSMesa OpenGL context that uses software rendering.
class GLContextOSMesa : public GLContext {
public:
- GLContextOSMesa();
+ explicit GLContextOSMesa(GLShareGroup* share_group);
virtual ~GLContextOSMesa();
// Implement GLContext.
- virtual bool Initialize(GLContext* shared_context,
- GLSurface* compatible_surface);
+ virtual bool Initialize(GLSurface* compatible_surface);
virtual void Destroy();
virtual bool MakeCurrent(GLSurface* surface);
virtual void ReleaseCurrent(GLSurface* surface);
diff --git a/ui/gfx/gl/gl_context_stub.cc b/ui/gfx/gl/gl_context_stub.cc
index 195a396..82b7b94 100644
--- a/ui/gfx/gl/gl_context_stub.cc
+++ b/ui/gfx/gl/gl_context_stub.cc
@@ -6,14 +6,13 @@
namespace gfx {
-GLContextStub::GLContextStub() {
+GLContextStub::GLContextStub() : GLContext(NULL) {
}
GLContextStub::~GLContextStub() {
}
-bool GLContextStub::Initialize(GLContext* shared_context,
- GLSurface* compatible_surface) {
+bool GLContextStub::Initialize(GLSurface* compatible_surface) {
return true;
}
diff --git a/ui/gfx/gl/gl_context_stub.h b/ui/gfx/gl/gl_context_stub.h
index 58c2270..44219a2 100644
--- a/ui/gfx/gl/gl_context_stub.h
+++ b/ui/gfx/gl/gl_context_stub.h
@@ -17,8 +17,7 @@ class GLContextStub : public GLContext {
virtual ~GLContextStub();
// Implement GLContext.
- virtual bool Initialize(GLContext* shared_context,
- GLSurface* compatible_surface);
+ virtual bool Initialize(GLSurface* compatible_surface);
virtual void Destroy();
virtual bool MakeCurrent(GLSurface* surface);
virtual void ReleaseCurrent(GLSurface* surface);
diff --git a/ui/gfx/gl/gl_context_wgl.cc b/ui/gfx/gl/gl_context_wgl.cc
index 7df8772..8533be7 100644
--- a/ui/gfx/gl/gl_context_wgl.cc
+++ b/ui/gfx/gl/gl_context_wgl.cc
@@ -13,8 +13,9 @@
namespace gfx {
-GLContextWGL::GLContextWGL()
- : context_(NULL) {
+GLContextWGL::GLContextWGL(GLShareGroup* share_group)
+ : GLContext(share_group),
+ context_(NULL) {
}
GLContextWGL::~GLContextWGL() {
@@ -36,8 +37,7 @@ std::string GLContextWGL::GetExtensions() {
return GLContext::GetExtensions();
}
-bool GLContextWGL::Initialize(GLContext* shared_context,
- GLSurface* compatible_surface) {
+bool GLContextWGL::Initialize(GLSurface* compatible_surface) {
GLSurfaceWGL* surface_wgl = static_cast<GLSurfaceWGL*>(compatible_surface);
// TODO(apatrick): When contexts and surfaces are separated, we won't be
@@ -51,13 +51,14 @@ bool GLContextWGL::Initialize(GLContext* shared_context,
return false;
}
- if (shared_context) {
- if (!wglShareLists(
- static_cast<HGLRC>(shared_context->GetHandle()),
- context_)) {
- LOG(ERROR) << "Could not share GL contexts.";
- Destroy();
- return false;
+ if (share_group()) {
+ HGLRC share_handle = static_cast<HGLRC>(share_group()->GetHandle());
+ if (share_handle) {
+ if (!wglShareLists(share_handle, context_)) {
+ LOG(ERROR) << "Could not share GL contexts.";
+ Destroy();
+ return false;
+ }
}
}
diff --git a/ui/gfx/gl/gl_context_wgl.h b/ui/gfx/gl/gl_context_wgl.h
index f48a564..3684c96 100644
--- a/ui/gfx/gl/gl_context_wgl.h
+++ b/ui/gfx/gl/gl_context_wgl.h
@@ -17,12 +17,11 @@ class GLSurface;
// This class is a wrapper around a GL context.
class GLContextWGL : public GLContext {
public:
- GLContextWGL();
+ explicit GLContextWGL(GLShareGroup* share_group);
virtual ~GLContextWGL();
// Implement GLContext.
- virtual bool Initialize(GLContext* shared_context,
- GLSurface* compatible_surface);
+ virtual bool Initialize(GLSurface* compatible_surface);
virtual void Destroy();
virtual bool MakeCurrent(GLSurface* surface);
virtual void ReleaseCurrent(GLSurface* surface);
diff --git a/ui/gfx/gl/gl_context_win.cc b/ui/gfx/gl/gl_context_win.cc
index c9f90706..3ca5f3b 100644
--- a/ui/gfx/gl/gl_context_win.cc
+++ b/ui/gfx/gl/gl_context_win.cc
@@ -21,26 +21,26 @@
namespace gfx {
scoped_refptr<GLContext> GLContext::CreateGLContext(
- GLContext* shared_context,
+ GLShareGroup* share_group,
GLSurface* compatible_surface) {
switch (GetGLImplementation()) {
case kGLImplementationOSMesaGL: {
- scoped_refptr<GLContext> context(new GLContextOSMesa);
- if (!context->Initialize(shared_context, compatible_surface))
+ scoped_refptr<GLContext> context(new GLContextOSMesa(share_group));
+ if (!context->Initialize(compatible_surface))
return NULL;
return context;
}
case kGLImplementationEGLGLES2: {
- scoped_refptr<GLContext> context(new GLContextEGL);
- if (!context->Initialize(shared_context, compatible_surface))
+ scoped_refptr<GLContext> context(new GLContextEGL(share_group));
+ if (!context->Initialize(compatible_surface))
return NULL;
return context;
}
case kGLImplementationDesktopGL: {
- scoped_refptr<GLContext> context(new GLContextWGL);
- if (!context->Initialize(shared_context, compatible_surface))
+ scoped_refptr<GLContext> context(new GLContextWGL(share_group));
+ if (!context->Initialize(compatible_surface))
return NULL;
return context;
diff --git a/ui/gfx/gl/gl_share_group.cc b/ui/gfx/gl/gl_share_group.cc
new file mode 100644
index 0000000..fa2bfcb
--- /dev/null
+++ b/ui/gfx/gl/gl_share_group.cc
@@ -0,0 +1,36 @@
+// Copyright (c) 2011 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.
+
+#include "ui/gfx/gl/gl_share_group.h"
+
+#include "ui/gfx/gl/gl_context.h"
+
+namespace gfx {
+
+GLShareGroup::GLShareGroup() {
+}
+
+void GLShareGroup::AddContext(GLContext* context) {
+ contexts_.insert(context);
+}
+
+void GLShareGroup::RemoveContext(GLContext* context) {
+ contexts_.erase(context);
+}
+
+void* GLShareGroup::GetHandle() {
+ for (ContextSet::iterator it = contexts_.begin();
+ it != contexts_.end();
+ ++it) {
+ if ((*it)->GetHandle())
+ return (*it)->GetHandle();
+ }
+
+ return NULL;
+}
+
+GLShareGroup::~GLShareGroup() {
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_share_group.h b/ui/gfx/gl/gl_share_group.h
new file mode 100644
index 0000000..33bebb9
--- /dev/null
+++ b/ui/gfx/gl/gl_share_group.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2011 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.
+
+#ifndef UI_GFX_GL_GL_SHARE_GROUP_H_
+#define UI_GFX_GL_GL_SHARE_GROUP_H_
+#pragma once
+
+#include <set>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+
+namespace gfx {
+
+class GLContext;
+
+// A group of GL contexts that share an ID namespace.
+class GLShareGroup : public base::RefCounted<GLShareGroup> {
+ public:
+ GLShareGroup();
+
+ // These two should only be called from the constructor and destructor of
+ // GLContext.
+ void AddContext(GLContext* context);
+ void RemoveContext(GLContext* context);
+
+ // Returns a handle to any initialized context in the share group or NULL if
+ // there are no initialized contexts in the share group.
+ void* GetHandle();
+
+ private:
+ friend class base::RefCounted<GLShareGroup>;
+ ~GLShareGroup();
+
+ // References to GLContext are by raw pointer to avoid a reference count
+ // cycle.
+ typedef std::set<GLContext*> ContextSet;
+ ContextSet contexts_;
+ DISALLOW_COPY_AND_ASSIGN(GLShareGroup);
+};
+
+} // namespace gfx
+
+#endif // UI_GFX_GL_GL_SHARE_GROUP_H_
diff --git a/ui/gfx/surface/accelerated_surface_mac.cc b/ui/gfx/surface/accelerated_surface_mac.cc
index ce2f7a0..123e907 100644
--- a/ui/gfx/surface/accelerated_surface_mac.cc
+++ b/ui/gfx/surface/accelerated_surface_mac.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_context.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_surface.h"
#include "ui/gfx/rect.h"
@@ -41,7 +42,10 @@ bool AcceleratedSurface::Initialize(gfx::GLContext* share_context,
return false;
}
- gl_context_ = gfx::GLContext::CreateGLContext(share_context,
+ gfx::GLShareGroup* share_group =
+ share_context ? share_context->share_group() : NULL;
+
+ gl_context_ = gfx::GLContext::CreateGLContext(share_group,
gl_surface_.get());
if (!gl_context_.get()) {
Destroy();
diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
index 25795a7..1f7e672 100644
--- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
+++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
@@ -29,6 +29,7 @@
#include "gpu/GLES2/gles2_command_buffer.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+#include "ui/gfx/gl/gl_share_group.h"
#include "webkit/glue/gl_bindings_skia_cmd_buffer.h"
using gpu::Buffer;
@@ -526,6 +527,9 @@ bool GLInProcessContext::Initialize(bool onscreen,
const char* allowed_extensions,
const int32* attrib_list,
const GURL& active_url) {
+ // Use one share group for all contexts.
+ static scoped_refptr<gfx::GLShareGroup> share_group(new gfx::GLShareGroup);
+
DCHECK(size.width() >= 0 && size.height() >= 0);
// Ensure the gles2 library is initialized first in a thread safe way.
@@ -585,7 +589,8 @@ bool GLInProcessContext::Initialize(bool onscreen,
allowed_extensions,
attribs,
NULL,
- 0)) {
+ 0,
+ share_group.get())) {
LOG(ERROR) << "Could not initialize GpuScheduler.";
command_buffer_.reset();
}
@@ -600,7 +605,8 @@ bool GLInProcessContext::Initialize(bool onscreen,
allowed_extensions,
attribs,
parent_scheduler,
- parent_texture_id_)) {
+ parent_texture_id_,
+ share_group.get())) {
LOG(ERROR) << "Could not initialize offscreen GpuScheduler.";
command_buffer_.reset();
}
diff --git a/webkit/gpu/webgraphicscontext3d_in_process_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_impl.cc
index 3ff4387..f01543a 100644
--- a/webkit/gpu/webgraphicscontext3d_in_process_impl.cc
+++ b/webkit/gpu/webgraphicscontext3d_in_process_impl.cc
@@ -110,7 +110,7 @@ bool WebGraphicsContext3DInProcessImpl::initialize(
gfx::BindSkiaToInProcessGL();
render_directly_to_web_view_ = render_directly_to_web_view;
- gfx::GLContext* share_context = 0;
+ gfx::GLShareGroup* share_group = 0;
if (!render_directly_to_web_view) {
// Pick up the compositor's context to share resources with.
@@ -118,7 +118,7 @@ bool WebGraphicsContext3DInProcessImpl::initialize(
if (view_context) {
WebGraphicsContext3DInProcessImpl* contextImpl =
static_cast<WebGraphicsContext3DInProcessImpl*>(view_context);
- share_context = contextImpl->gl_context_.get();
+ share_group = contextImpl->gl_context_->share_group();
} else {
// The compositor's context didn't get created
// successfully, so conceptually there is no way we can
@@ -154,7 +154,7 @@ bool WebGraphicsContext3DInProcessImpl::initialize(
return false;
}
- gl_context_ = gfx::GLContext::CreateGLContext(share_context,
+ gl_context_ = gfx::GLContext::CreateGLContext(share_group,
gl_surface_.get());
if (!gl_context_.get()) {
if (!is_gles2_)
@@ -169,7 +169,7 @@ bool WebGraphicsContext3DInProcessImpl::initialize(
// necessary.
webView->mainFrame()->collectGarbage();
- gl_context_ = gfx::GLContext::CreateGLContext(share_context,
+ gl_context_ = gfx::GLContext::CreateGLContext(share_group,
gl_surface_.get());
if (!gl_context_.get())
return false;