diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-25 22:08:35 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-25 22:08:35 +0000 |
commit | 6217d397bf501ec1ec5b7270d493006badd4d87a (patch) | |
tree | fce6c8e9c15b79bab29a9535ce9929dd9d53735b /chrome/renderer/ggl | |
parent | 21dedcc12d21ccb288244249522d77bc074c501e (diff) | |
download | chromium_src-6217d397bf501ec1ec5b7270d493006badd4d87a.zip chromium_src-6217d397bf501ec1ec5b7270d493006badd4d87a.tar.gz chromium_src-6217d397bf501ec1ec5b7270d493006badd4d87a.tar.bz2 |
Calling OpenGL from the renderer process
- Added ability for renderer processes to render to a real window (Windows only so far).
- Added ability to create offscreen frame buffer objects that can be resized later.
- OpenGL context can have a "parent" context that can access its last swapped back buffer through a texture ID.
- Moved code to establish GPU channel from RenderWidget to RenderThread.
- Changed way service size command buffer object lifetimes are managed.
TEST=trybot and visual verification that OpenGL can clear the browser window to magenta.
BUG=none
Review URL: http://codereview.chromium.org/1136006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42679 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/ggl')
-rw-r--r-- | chrome/renderer/ggl/ggl.cc | 88 | ||||
-rw-r--r-- | chrome/renderer/ggl/ggl.h | 34 |
2 files changed, 106 insertions, 16 deletions
diff --git a/chrome/renderer/ggl/ggl.cc b/chrome/renderer/ggl/ggl.cc index b5c1d9d..2c41126 100644 --- a/chrome/renderer/ggl/ggl.cc +++ b/chrome/renderer/ggl/ggl.cc @@ -50,12 +50,21 @@ class GLES2Initializer { // Manages a GL context. class Context { public: - Context(); + Context(GpuChannelHost* channel, Context* parent); ~Context(); // Initialize a GGL context that can be used in association with a a GPU // channel acquired from a RenderWidget or RenderView. - bool Initialize(GpuChannelHost* channel); + bool Initialize(gfx::NativeViewId view, const gfx::Size& size); + + // Asynchronously resizes an offscreen frame buffer. + void ResizeOffscreen(const gfx::Size& size); + + // For an offscreen frame buffer context, return the frame buffer ID with + // respect to the parent. + uint32 parent_texture_id() const { + return parent_texture_id_; + } // Destroy all resources associated with the GGL context. void Destroy(); @@ -73,6 +82,8 @@ class Context { private: scoped_refptr<GpuChannelHost> channel_; + Context* parent_; + uint32 parent_texture_id_; CommandBufferProxy* command_buffer_; gpu::gles2::GLES2CmdHelper* gles2_helper_; int32 transfer_buffer_id_; @@ -81,31 +92,46 @@ class Context { DISALLOW_COPY_AND_ASSIGN(Context); }; -Context::Context() - : channel_(NULL), +Context::Context(GpuChannelHost* channel, Context* parent) + : channel_(channel), + parent_(parent), + parent_texture_id_(0), command_buffer_(NULL), gles2_helper_(NULL), transfer_buffer_id_(0), gles2_implementation_(NULL) { + DCHECK(channel); } Context::~Context() { Destroy(); } -bool Context::Initialize(GpuChannelHost* channel) { - DCHECK(channel); +bool Context::Initialize(gfx::NativeViewId view, const gfx::Size& size) { + DCHECK(size.width() >= 0 && size.height() >= 0); - if (!channel->ready()) + if (!channel_->ready()) return false; - channel_ = channel; - // Ensure the gles2 library is initialized first in a thread safe way. Singleton<GLES2Initializer>::get(); + // Allocate a frame buffer ID with respect to the parent. + if (parent_) { + parent_->gles2_implementation_->MakeIds(1, &parent_texture_id_); + } + // Create a proxy to a command buffer in the GPU process. - command_buffer_ = channel_->CreateCommandBuffer(); + if (view) { + command_buffer_ = channel_->CreateViewCommandBuffer(view); + } else { + CommandBufferProxy* parent_command_buffer = + parent_ ? parent_->command_buffer_ : NULL; + command_buffer_ = channel_->CreateOffscreenCommandBuffer( + parent_command_buffer, + size, + parent_texture_id_); + } if (!command_buffer_) { Destroy(); return false; @@ -151,7 +177,15 @@ bool Context::Initialize(GpuChannelHost* channel) { return true; } +void Context::ResizeOffscreen(const gfx::Size& size) { + DCHECK(size.width() > 0 && size.height() > 0); + command_buffer_->ResizeOffscreenFrameBuffer(size); +} + void Context::Destroy() { + if (parent_ && parent_texture_id_ != 0) + parent_->gles2_implementation_->FreeIds(1, &parent_texture_id_); + delete gles2_implementation_; gles2_implementation_ = NULL; @@ -213,10 +247,10 @@ Error Context::GetError() { #endif // ENABLE_GPU -Context* CreateContext(GpuChannelHost* channel) { +Context* CreateViewContext(GpuChannelHost* channel, gfx::NativeViewId view) { #if defined(ENABLE_GPU) - scoped_ptr<Context> context(new Context); - if (!context->Initialize(channel)) + scoped_ptr<Context> context(new Context(channel, NULL)); + if (!context->Initialize(view, gfx::Size())) return NULL; return context.release(); @@ -225,6 +259,34 @@ Context* CreateContext(GpuChannelHost* channel) { #endif } +Context* CreateOffscreenContext(GpuChannelHost* channel, + Context* parent, + const gfx::Size& size) { +#if defined(ENABLE_GPU) + scoped_ptr<Context> context(new Context(channel, parent)); + if (!context->Initialize(NULL, size)) + return NULL; + + return context.release(); +#else + return NULL; +#endif +} + +void ResizeOffscreenContext(Context* context, const gfx::Size& size) { +#if defined(ENABLE_GPU) + context->ResizeOffscreen(size); +#endif +} + +uint32 GetParentTextureId(Context* context) { +#if defined(ENABLE_GPU) + return context->parent_texture_id(); +#else + return 0; +#endif +} + bool MakeCurrent(Context* context) { #if defined(ENABLE_GPU) return Context::MakeCurrent(context); diff --git a/chrome/renderer/ggl/ggl.h b/chrome/renderer/ggl/ggl.h index 26607ec..e5c661f 100644 --- a/chrome/renderer/ggl/ggl.h +++ b/chrome/renderer/ggl/ggl.h @@ -10,6 +10,9 @@ #ifndef CHROME_RENDERER_GGL_GGL_H_ #define CHROME_RENDERER_GGL_GGL_H_ +#include "gfx/native_widget_types.h" +#include "gfx/size.h" + class GpuChannelHost; namespace ggl { @@ -32,8 +35,30 @@ bool Initialize(); // have completed. bool Terminate(); -// Create A GGL context for an offscreen 1 x 1 pbuffer. -Context* CreateContext(GpuChannelHost* channel); +// Create a GGL context that renders directly to a view. +Context* CreateViewContext(GpuChannelHost* channel, gfx::NativeViewId view); + +// Create a GGL context that renders to an offscreen frame buffer. If parent is +// not NULL, that context can access a copy of the created +// context's frame buffer that is updated every time SwapBuffers is called. It +// is not as general as shared contexts in other implementations of OpenGL. If +// parent is not NULL, it must be used on the same thread as the parent. A child +// context may not outlive its parent. +Context* CreateOffscreenContext(GpuChannelHost* channel, + Context* parent, + const gfx::Size& size); + +// Resize an offscreen frame buffer. The resize occurs on the next call to +// SwapBuffers. This is to avoid waiting until all pending GL calls have been +// executed by the GPU process. Everything rendered up to the call to +// SwapBuffers will be lost. A lost context will be reported if the resize +// fails. +void ResizeOffscreenContext(Context* context, const gfx::Size& size); + +// For an offscreen frame buffer context, return the texture ID with +// respect to the parent context. Returns zero if context does not have a +// parent. +uint32 GetParentTextureId(Context* context); // Set the current GGL context for the calling thread. bool MakeCurrent(Context* context); @@ -41,7 +66,10 @@ bool MakeCurrent(Context* context); // Get the calling thread's current GGL context. Context* GetCurrentContext(); -// Display everything that has been rendered since the last call. +// For a view context, display everything that has been rendered since the +// last call. For an offscreen context, resolve everything that has been +// rendered since the last call to a copy that can be accessed by the parent +// context. bool SwapBuffers(); // Destroy the given GGL context. |