summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-28 00:48:56 +0000
committerjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-28 00:48:56 +0000
commita3a93e7bbb8275069f319e0807c43f7395502abf (patch)
treef5424f889285ff09f930ffc30ed16c0203ad1827 /chrome
parent9117fb714da99c44319cc8e56909d0a48bf7da02 (diff)
downloadchromium_src-a3a93e7bbb8275069f319e0807c43f7395502abf.zip
chromium_src-a3a93e7bbb8275069f319e0807c43f7395502abf.tar.gz
chromium_src-a3a93e7bbb8275069f319e0807c43f7395502abf.tar.bz2
Add way to create a texture in parent's context and copy into it
For canvas we need a way to create multiple offscreen render targets within the same OpenGL context and expose them all to the compositor, which exists as a parent context. ggl currently provides a single framebuffer and texture pair per offscreen context and implements swapBuffers() to copy to the parent texture. This generalizes that to let clients create as many parent textures as necessary and do the equivalent of swapBuffers() for each without the service side needing to keep track of the mapping. We'll want to change this in the future when we start using glBlitFramebuffer to support multisampling. I think in that world we'll need a way to bind a texture in the parent's context to the DRAW_FRAMEBUFFER context. For now, I think this is OK. TEST=open a page with multiple accelerated canvases in a shared context BUG=52684 Review URL: http://codereview.chromium.org/3211005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57761 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/renderer/ggl/ggl.cc59
-rw-r--r--chrome/renderer/ggl/ggl.h7
-rw-r--r--chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc23
-rw-r--r--chrome/renderer/webgraphicscontext3d_command_buffer_impl.h5
4 files changed, 94 insertions, 0 deletions
diff --git a/chrome/renderer/ggl/ggl.cc b/chrome/renderer/ggl/ggl.cc
index 18e400b3..279247f 100644
--- a/chrome/renderer/ggl/ggl.cc
+++ b/chrome/renderer/ggl/ggl.cc
@@ -83,6 +83,9 @@ class Context : public base::SupportsWeakPtr<Context> {
return parent_texture_id_;
}
+ uint32 CreateParentTexture(const gfx::Size& size) const;
+ void DeleteParentTexture(uint32 texture) const;
+
// Destroy all resources associated with the GGL context.
void Destroy();
@@ -223,6 +226,48 @@ void Context::ResizeOffscreen(const gfx::Size& size) {
command_buffer_->ResizeOffscreenFrameBuffer(size);
}
+uint32 Context::CreateParentTexture(const gfx::Size& size) const {
+ // Allocate a texture ID with respect to the parent.
+ if (parent_.get()) {
+ if (!MakeCurrent(parent_.get()))
+ return 0;
+ uint32 texture_id = parent_->gles2_implementation_->MakeTextureId();
+ parent_->gles2_implementation_->BindTexture(GL_TEXTURE_2D, texture_id);
+ parent_->gles2_implementation_->TexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ parent_->gles2_implementation_->TexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ parent_->gles2_implementation_->TexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ parent_->gles2_implementation_->TexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ parent_->gles2_implementation_->TexImage2D(GL_TEXTURE_2D,
+ 0, // mip level
+ GL_RGBA,
+ size.width(),
+ size.height(),
+ 0, // border
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ NULL);
+ // Make sure that the parent texture's storage is allocated before we let
+ // the caller attempt to use it.
+ int32 token = parent_->gles2_helper_->InsertToken();
+ parent_->gles2_helper_->WaitForToken(token);
+ return texture_id;
+ }
+ return 0;
+}
+
+void Context::DeleteParentTexture(uint32 texture) const {
+ if (parent_.get()) {
+ if (!MakeCurrent(parent_.get()))
+ return;
+ parent_->gles2_implementation_->DeleteTextures(1, &texture);
+ }
+}
+
void Context::Destroy() {
if (parent_.get() && parent_texture_id_ != 0)
parent_->gles2_implementation_->FreeTextureId(parent_texture_id_);
@@ -348,6 +393,20 @@ uint32 GetParentTextureId(Context* context) {
#endif
}
+uint32 CreateParentTexture(Context* context, const gfx::Size& size) {
+#if defined(ENABLE_GPU)
+ return context->CreateParentTexture(size);
+#else
+ return 0;
+#endif
+}
+
+void DeleteParentTexture(Context* context, uint32 texture) {
+#if defined(ENABLE_GPU)
+ context->DeleteParentTexture(texture);
+#endif
+}
+
void SetSwapBuffersCallback(Context* context,
Callback1<Context*>::Type* callback) {
#if defined(ENABLE_GPU)
diff --git a/chrome/renderer/ggl/ggl.h b/chrome/renderer/ggl/ggl.h
index fd1cd56..38f83ad 100644
--- a/chrome/renderer/ggl/ggl.h
+++ b/chrome/renderer/ggl/ggl.h
@@ -87,6 +87,13 @@ void ResizeOffscreenContext(Context* context, const gfx::Size& size);
// parent.
uint32 GetParentTextureId(Context* context);
+// Create a new texture in the parent's context. Returns zero if context
+// does not have a parent.
+uint32 CreateParentTexture(Context* context, const gfx::Size& size);
+
+// Deletes a texture in the parent's context.
+void DeleteParentTexture(Context* context, uint32 texture);
+
// Provides a callback that will be invoked when SwapBuffers has completed
// service side.
void SetSwapBuffersCallback(Context* context,
diff --git a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc
index 2b078ea..0c7d966 100644
--- a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc
+++ b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc
@@ -7,6 +7,10 @@
#include "chrome/renderer/webgraphicscontext3d_command_buffer_impl.h"
#include <GLES2/gl2.h>
+#ifndef GL_GLEXT_PROTOTYPES
+#define GL_GLEXT_PROTOTYPES 1
+#endif
+#include <GLES2/gl2ext.h>
#include <algorithm>
@@ -146,6 +150,18 @@ void WebGraphicsContext3DCommandBufferImpl::reshape(int width, int height) {
#endif // FLIP_FRAMEBUFFER_VERTICALLY
}
+unsigned WebGraphicsContext3DCommandBufferImpl::createCompositorTexture(
+ unsigned width, unsigned height) {
+ makeContextCurrent();
+ return ggl::CreateParentTexture(context_, gfx::Size(width, height));
+}
+
+void WebGraphicsContext3DCommandBufferImpl::deleteCompositorTexture(
+ unsigned parent_texture) {
+ makeContextCurrent();
+ ggl::DeleteParentTexture(context_, parent_texture);
+}
+
#ifdef FLIP_FRAMEBUFFER_VERTICALLY
void WebGraphicsContext3DCommandBufferImpl::FlipVertically(
uint8* framebuffer,
@@ -871,5 +887,12 @@ void WebGraphicsContext3DCommandBufferImpl::deleteTexture(unsigned texture) {
glDeleteTextures(1, &texture);
}
+void WebGraphicsContext3DCommandBufferImpl::copyTextureToCompositor(
+ unsigned texture, unsigned parentTexture) {
+ makeContextCurrent();
+ glCopyTextureToParentTexture(texture, parentTexture);
+ glFlush();
+}
+
#endif // defined(ENABLE_GPU)
diff --git a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h
index 4698278..d32952e 100644
--- a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h
+++ b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h
@@ -341,6 +341,11 @@ class WebGraphicsContext3DCommandBufferImpl
virtual void synthesizeGLError(unsigned long error);
virtual bool supportsBGRA();
+ virtual unsigned createCompositorTexture(unsigned width, unsigned height);
+ virtual void deleteCompositorTexture(unsigned parent_texture);
+ virtual void copyTextureToCompositor(unsigned texture,
+ unsigned parent_texture);
+
private:
// The GGL context we use for OpenGL rendering.
ggl::Context* context_;