summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/ggl
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-25 22:08:35 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-25 22:08:35 +0000
commit6217d397bf501ec1ec5b7270d493006badd4d87a (patch)
treefce6c8e9c15b79bab29a9535ce9929dd9d53735b /chrome/renderer/ggl
parent21dedcc12d21ccb288244249522d77bc074c501e (diff)
downloadchromium_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.cc88
-rw-r--r--chrome/renderer/ggl/ggl.h34
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.