diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-20 19:58:24 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-20 19:58:24 +0000 |
commit | 3c644d83d23318c6ba120e2303816369045f5964 (patch) | |
tree | 3f0a3b02ce1a4fd7cf8b68d3bb033be8ca8129dd /content/renderer/gpu/renderer_gl_context.cc | |
parent | 35c14eeb34ca5f21b70a388e868ff3968545812f (diff) | |
download | chromium_src-3c644d83d23318c6ba120e2303816369045f5964.zip chromium_src-3c644d83d23318c6ba120e2303816369045f5964.tar.gz chromium_src-3c644d83d23318c6ba120e2303816369045f5964.tar.bz2 |
RendererGLContext supports reparenting a GL context.
This will allow the parenting of offscreen canvas contexts to be deferred until the compositor's view context exists, which in some cases needs to be deferred until the window is asynchronously created by the browser's UI thread. An example is JavaScript opening a popup window and then immediately using canvas to attempt to render to it.
This patch alone does not fix the bug.
BUG=80703
Review URL: http://codereview.chromium.org/7205012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@89715 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/gpu/renderer_gl_context.cc')
-rw-r--r-- | content/renderer/gpu/renderer_gl_context.cc | 76 |
1 files changed, 45 insertions, 31 deletions
diff --git a/content/renderer/gpu/renderer_gl_context.cc b/content/renderer/gpu/renderer_gl_context.cc index 260b9d5..d5ec2b9 100644 --- a/content/renderer/gpu/renderer_gl_context.cc +++ b/content/renderer/gpu/renderer_gl_context.cc @@ -161,7 +161,7 @@ RendererGLContext* RendererGLContext::CreateViewContext( const int32* attrib_list, const GURL& active_url) { #if defined(ENABLE_GPU) - scoped_ptr<RendererGLContext> context(new RendererGLContext(channel, NULL)); + scoped_ptr<RendererGLContext> context(new RendererGLContext(channel)); if (!context->Initialize( true, render_surface, @@ -188,13 +188,12 @@ void RendererGLContext::ResizeOnscreen(const gfx::Size& size) { RendererGLContext* RendererGLContext::CreateOffscreenContext( GpuChannelHost* channel, - RendererGLContext* parent, const gfx::Size& size, const char* allowed_extensions, const int32* attrib_list, const GURL& active_url) { #if defined(ENABLE_GPU) - scoped_ptr<RendererGLContext> context(new RendererGLContext(channel, parent)); + scoped_ptr<RendererGLContext> context(new RendererGLContext(channel)); if (!context->Initialize( false, gfx::kNullPluginWindow, @@ -211,6 +210,42 @@ RendererGLContext* RendererGLContext::CreateOffscreenContext( #endif } +bool RendererGLContext::SetParent(RendererGLContext* new_parent) { + // Allocate a texture ID with respect to the parent and change the parent. + uint32 new_parent_texture_id = 0; + if (new_parent) { + TRACE_EVENT0("gpu", "RendererGLContext::SetParent::flushParent"); + // Flush any remaining commands in the parent context to make sure the + // texture id accounting stays consistent. + int32 token = new_parent->gles2_helper_->InsertToken(); + new_parent->gles2_helper_->WaitForToken(token); + new_parent_texture_id = new_parent->gles2_implementation_->MakeTextureId(); + + if (!command_buffer_->SetParent(new_parent->command_buffer_, + new_parent_texture_id)) { + new_parent->gles2_implementation_->FreeTextureId(parent_texture_id_); + return false; + } + } else { + if (!command_buffer_->SetParent(NULL, 0)) + return false; + } + + // Free the previous parent's texture ID. + if (parent_.get() && parent_texture_id_ != 0) + parent_->gles2_implementation_->FreeTextureId(parent_texture_id_); + + if (new_parent) { + parent_ = new_parent->AsWeakPtr(); + parent_texture_id_ = new_parent_texture_id; + } else { + parent_.reset(); + parent_texture_id_ = 0; + } + + return true; +} + void RendererGLContext::ResizeOffscreen(const gfx::Size& size) { DCHECK(size.width() > 0 && size.height() > 0); if (size_ != size) { @@ -342,11 +377,9 @@ gpu::gles2::GLES2Implementation* RendererGLContext::GetImplementation() { return gles2_implementation_; } -RendererGLContext::RendererGLContext(GpuChannelHost* channel, - RendererGLContext* parent) +RendererGLContext::RendererGLContext(GpuChannelHost* channel) : channel_(channel), - parent_(parent ? - parent->AsWeakPtr() : base::WeakPtr<RendererGLContext>()), + parent_(base::WeakPtr<RendererGLContext>()), parent_texture_id_(0), child_to_parent_latch_(kInvalidLatchId), parent_to_child_latch_(kInvalidLatchId), @@ -377,16 +410,6 @@ bool RendererGLContext::Initialize(bool onscreen, // Ensure the gles2 library is initialized first in a thread safe way. g_gles2_initializer.Get(); - // Allocate a frame buffer ID with respect to the parent. - if (parent_.get()) { - TRACE_EVENT0("gpu", "RendererGLContext::Initialize::flushParent"); - // Flush any remaining commands in the parent context to make sure the - // texture id accounting stays consistent. - int32 token = parent_->gles2_helper_->InsertToken(); - parent_->gles2_helper_->WaitForToken(token); - parent_texture_id_ = parent_->gles2_implementation_->MakeTextureId(); - } - std::vector<int32> attribs; while (attrib_list) { int32 attrib = *attrib_list++; @@ -431,14 +454,10 @@ bool RendererGLContext::Initialize(bool onscreen, active_url); } } else { - CommandBufferProxy* parent_command_buffer = - parent_.get() ? parent_->command_buffer_ : NULL; command_buffer_ = channel_->CreateOffscreenCommandBuffer( - parent_command_buffer, size, allowed_extensions, attribs, - parent_texture_id_, active_url); } if (!command_buffer_) { @@ -501,12 +520,10 @@ bool RendererGLContext::Initialize(bool onscreen, // If this is a child context, setup latches for synchronization between child // and parent. - if (parent_.get()) { - if (!CreateLatch(&child_to_parent_latch_) || - !CreateLatch(&parent_to_child_latch_)) { - Destroy(); - return false; - } + if (!CreateLatch(&child_to_parent_latch_) || + !CreateLatch(&parent_to_child_latch_)) { + Destroy(); + return false; } // Create the object exposing the OpenGL API. @@ -523,10 +540,7 @@ bool RendererGLContext::Initialize(bool onscreen, } void RendererGLContext::Destroy() { - if (parent_.get() && parent_texture_id_ != 0) { - parent_->gles2_implementation_->FreeTextureId(parent_texture_id_); - parent_texture_id_ = 0; - } + SetParent(NULL); delete gles2_implementation_; gles2_implementation_ = NULL; |