summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-06 00:00:07 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-06 00:00:07 +0000
commit5aa6a312dc935c3392e025e97daded48f5363a05 (patch)
tree2c1a286841459eba6b8b38528e2a18057f03c9d4 /webkit
parent7bc4b5d06145e8753fdc8b2db04a5fb20ab86299 (diff)
downloadchromium_src-5aa6a312dc935c3392e025e97daded48f5363a05.zip
chromium_src-5aa6a312dc935c3392e025e97daded48f5363a05.tar.gz
chromium_src-5aa6a312dc935c3392e025e97daded48f5363a05.tar.bz2
Reland r65152 with mac and linux fix.
Original review URL: http://codereview.chromium.org/3531008 TEST=try, ui_tests BUG=none Review URL: http://codereview.chromium.org/4545003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65283 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/plugins/pepper_graphics_3d.cc149
-rw-r--r--webkit/glue/plugins/pepper_graphics_3d.h47
-rw-r--r--webkit/glue/plugins/pepper_plugin_delegate.h33
-rw-r--r--webkit/glue/plugins/pepper_plugin_instance.cc104
-rw-r--r--webkit/glue/plugins/pepper_plugin_instance.h26
-rw-r--r--webkit/glue/plugins/pepper_webplugin_impl.cc4
-rw-r--r--webkit/glue/plugins/pepper_webplugin_impl.h1
-rw-r--r--webkit/glue/plugins/plugin_instance.cc5
-rw-r--r--webkit/glue/plugins/plugin_instance.h4
-rw-r--r--webkit/glue/plugins/webplugin_impl.cc5
-rw-r--r--webkit/glue/plugins/webplugin_impl.h1
11 files changed, 240 insertions, 139 deletions
diff --git a/webkit/glue/plugins/pepper_graphics_3d.cc b/webkit/glue/plugins/pepper_graphics_3d.cc
index fa9c2ec1c..2dc4def 100644
--- a/webkit/glue/plugins/pepper_graphics_3d.cc
+++ b/webkit/glue/plugins/pepper_graphics_3d.cc
@@ -92,8 +92,8 @@ PP_Bool MakeCurrent(PP_Resource graphics3d) {
}
PP_Resource GetCurrentContext() {
- Graphics3D* currentContext = Graphics3D::GetCurrent();
- return currentContext ? currentContext->GetReference() : 0;
+ Graphics3D* current_context = Graphics3D::GetCurrent();
+ return current_context ? current_context->GetReference() : 0;
}
PP_Bool SwapBuffers(PP_Resource graphics3d) {
@@ -102,8 +102,14 @@ PP_Bool SwapBuffers(PP_Resource graphics3d) {
}
uint32_t GetError() {
- // TODO(neb): Figure out error checking.
- return PP_GRAPHICS_3D_ERROR_SUCCESS;
+ // Technically, this should return the last error that occurred on the current
+ // thread, rather than an error associated with a particular context.
+ // TODO(apatrick): Fix this.
+ Graphics3D* current_context = Graphics3D::GetCurrent();
+ if (!current_context)
+ return 0;
+
+ return current_context->GetError();
}
const PPB_Graphics3D_Dev ppb_graphics3d = {
@@ -123,10 +129,8 @@ const PPB_Graphics3D_Dev ppb_graphics3d = {
} // namespace
Graphics3D::Graphics3D(PluginModule* module)
- : Resource(module),
- command_buffer_(NULL),
- transfer_buffer_id_(0),
- method_factory3d_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ : Resource(module),
+ bound_instance_(NULL) {
}
const PPB_Graphics3D_Dev* Graphics3D::GetInterface() {
@@ -154,103 +158,98 @@ bool Graphics3D::Init(PP_Instance instance_id, int32_t config,
// Create and initialize the objects required to issue GLES2 calls.
platform_context_.reset(instance->delegate()->CreateContext3D());
- if (!platform_context_.get())
+ if (!platform_context_.get()) {
+ Destroy();
return false;
+ }
- if (!platform_context_->Init(instance->position(),
- instance->clip())) {
- platform_context_.reset();
+ if (!platform_context_->Init()) {
+ Destroy();
return false;
}
- command_buffer_ = platform_context_->GetCommandBuffer();
- gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_));
- gpu::Buffer buffer = command_buffer_->GetRingBuffer();
- if (gles2_helper_->Initialize(buffer.size)) {
- transfer_buffer_id_ =
- command_buffer_->CreateTransferBuffer(kTransferBufferSize);
- gpu::Buffer transfer_buffer =
- command_buffer_->GetTransferBuffer(transfer_buffer_id_);
- if (transfer_buffer.ptr) {
- gles2_implementation_.reset(new gpu::gles2::GLES2Implementation(
- gles2_helper_.get(),
- transfer_buffer.size,
- transfer_buffer.ptr,
- transfer_buffer_id_,
- false));
- platform_context_->SetNotifyRepaintTask(
- method_factory3d_.NewRunnableMethod(&Graphics3D::HandleRepaint,
- instance_id));
- return true;
- }
+
+ gles2_implementation_ = platform_context_->GetGLES2Implementation();
+ DCHECK(gles2_implementation_);
+
+ return true;
+}
+
+bool Graphics3D::BindToInstance(PluginInstance* new_instance) {
+ if (bound_instance_ == new_instance)
+ return true; // Rebinding the same device, nothing to do.
+ if (bound_instance_ && new_instance)
+ return false; // Can't change a bound device.
+
+ if (new_instance) {
+ // Resize the backing texture to the size of the instance when it is bound.
+ platform_context_->ResizeBackingTexture(new_instance->position().size());
+
+ // This is a temporary hack. The SwapBuffers is issued to force the resize
+ // to take place before any subsequent rendering. This might lead to a
+ // partially rendered frame being displayed. It is also not thread safe
+ // since the SwapBuffers is written to the command buffer and that command
+ // buffer might be written to by another thread.
+ // TODO(apatrick): Figure out the semantics of binding and resizing.
+ platform_context_->SwapBuffers();
}
- // Tear everything down if initialization failed.
- Destroy();
- return false;
+ bound_instance_ = new_instance;
+ return true;
}
bool Graphics3D::MakeCurrent() {
- if (!command_buffer_)
+ if (!platform_context_.get())
return false;
CurrentContextKey::get()->Set(this);
- // Don't request latest error status from service. Just use the locally
- // cached information from the last flush.
- // TODO(apatrick): I'm not sure if this should actually change the
- // current context if it fails. For now it gets changed even if it fails
- // becuase making GL calls with a NULL context crashes.
- // TODO(neb): Figure out error checking.
-// if (command_buffer_->GetCachedError() != gpu::error::kNoError)
-// return false;
+ // TODO(apatrick): Return false on context lost.
return true;
}
bool Graphics3D::SwapBuffers() {
- if (!command_buffer_)
+ if (!platform_context_.get())
return false;
- // Don't request latest error status from service. Just use the locally cached
- // information from the last flush.
- // TODO(neb): Figure out error checking.
-// if (command_buffer_->GetCachedError() != gpu::error::kNoError)
-// return false;
+ return platform_context_->SwapBuffers();
+}
- gles2_implementation_->SwapBuffers();
- return true;
+unsigned Graphics3D::GetError() {
+ if (!platform_context_.get())
+ return 0;
+
+ return platform_context_->GetError();
}
-void Graphics3D::Destroy() {
- if (GetCurrent() == this) {
- ResetCurrent();
- }
+void Graphics3D::ResizeBackingTexture(const gfx::Size& size) {
+ if (!platform_context_.get())
+ return;
- method_factory3d_.RevokeAll();
+ platform_context_->ResizeBackingTexture(size);
+}
- gles2_implementation_.reset();
+void Graphics3D::SetSwapBuffersCallback(Callback0::Type* callback) {
+ if (!platform_context_.get())
+ return;
- if (command_buffer_ && transfer_buffer_id_ != 0) {
- command_buffer_->DestroyTransferBuffer(transfer_buffer_id_);
- transfer_buffer_id_ = 0;
- }
+ platform_context_->SetSwapBuffersCallback(callback);
+}
- gles2_helper_.reset();
+unsigned Graphics3D::GetBackingTextureId() {
+ if (!platform_context_.get())
+ return 0;
- // Platform context owns the command buffer.
- platform_context_.reset();
- command_buffer_ = NULL;
+ return platform_context_->GetBackingTextureId();
}
-void Graphics3D::HandleRepaint(PP_Instance instance_id) {
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
- if (instance) {
- instance->Graphics3DContextLost();
- if (platform_context_.get()) {
- platform_context_->SetNotifyRepaintTask(
- method_factory3d_.NewRunnableMethod(&Graphics3D::HandleRepaint,
- instance_id));
- }
+void Graphics3D::Destroy() {
+ if (GetCurrent() == this) {
+ ResetCurrent();
}
+
+ gles2_implementation_ = NULL;
+
+ platform_context_.reset();
}
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_graphics_3d.h b/webkit/glue/plugins/pepper_graphics_3d.h
index 96c7b80..5c00068 100644
--- a/webkit/glue/plugins/pepper_graphics_3d.h
+++ b/webkit/glue/plugins/pepper_graphics_3d.h
@@ -5,19 +5,19 @@
#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_GRAPHICS_3D_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_GRAPHICS_3D_H_
+#include "base/callback.h"
#include "base/scoped_ptr.h"
+#include "gfx/size.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "ppapi/c/pp_instance.h"
#include "webkit/glue/plugins/pepper_plugin_delegate.h"
#include "webkit/glue/plugins/pepper_resource.h"
-namespace gfx {
-class Rect;
-} // namespace gfx
-
namespace gpu {
-class CommandBuffer;
+namespace gles2 {
+class GLES2Implementation;
+}
} // namespace gpu
struct PPB_Graphics3D_Dev;
@@ -48,35 +48,40 @@ class Graphics3D : public Resource {
bool Init(PP_Instance instance_id, int32_t config,
const int32_t* attrib_list);
+ // Associates this Graphics3D with the given plugin instance. You can pass
+ // NULL to clear the existing device. Returns true on success. In this case,
+ // the last rendered frame is displayed.
+ // TODO(apatrick): Figure out the best semantics here.
+ bool BindToInstance(PluginInstance* new_instance);
+
bool MakeCurrent();
bool SwapBuffers();
+ unsigned GetError();
+
+ void ResizeBackingTexture(const gfx::Size& size);
+
+ void SetSwapBuffersCallback(Callback0::Type* callback);
+
+ unsigned GetBackingTextureId();
+
gpu::gles2::GLES2Implementation* impl() {
- return gles2_implementation_.get();
+ return gles2_implementation_;
}
private:
- void HandleRepaint(PP_Instance instance_id);
void Destroy();
+ // Non-owning pointer to the plugin instance this context is currently bound
+ // to, if any. If the context is currently unbound, this will be NULL.
+ PluginInstance* bound_instance_;
+
// PluginDelegate's 3D Context. Responsible for providing the command buffer.
scoped_ptr<PluginDelegate::PlatformContext3D> platform_context_;
- // Command buffer is owned by the platform context.
- gpu::CommandBuffer* command_buffer_;
-
- // GLES2 Command Helper instance.
- scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_;
-
- // ID of the transfer buffer.
- int32_t transfer_buffer_id_;
-
- // GLES2 Implementation instance.
- scoped_ptr<gpu::gles2::GLES2Implementation> gles2_implementation_;
-
- // Runnable methods that must be cancelled when the 3D context is destroyed.
- ScopedRunnableMethodFactory<Graphics3D> method_factory3d_;
+ // GLES2 Implementation instance. Owned by the platform context's GGL context.
+ gpu::gles2::GLES2Implementation* gles2_implementation_;
};
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h
index 0998355..d2c67c7 100644
--- a/webkit/glue/plugins/pepper_plugin_delegate.h
+++ b/webkit/glue/plugins/pepper_plugin_delegate.h
@@ -13,6 +13,7 @@
#include "base/shared_memory.h"
#include "base/sync_socket.h"
#include "base/task.h"
+#include "gfx/size.h"
#include "googleurl/src/gurl.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
@@ -37,7 +38,9 @@ class Rect;
}
namespace gpu {
-class CommandBuffer;
+namespace gles2 {
+class GLES2Implementation;
+}
}
namespace skia {
@@ -87,14 +90,30 @@ class PluginDelegate {
virtual ~PlatformContext3D() {}
// Initialize the context.
- virtual bool Init(const gfx::Rect& position, const gfx::Rect& clip) = 0;
+ virtual bool Init() = 0;
+
+ // Present the rendered frame to the compositor.
+ virtual bool SwapBuffers() = 0;
+
+ // Get the last EGL error.
+ virtual unsigned GetError() = 0;
+
+ // Resize the backing texture used as a back buffer by OpenGL.
+ virtual void ResizeBackingTexture(const gfx::Size& size) = 0;
+
+ // Set an optional callback that will be invoked when the side effects of
+ // a SwapBuffers call become visible to the compositor. Takes ownership
+ // of the callback.
+ virtual void SetSwapBuffersCallback(Callback0::Type* callback) = 0;
- // This call will return the address of the command buffer object that is
- // constructed in Initialize() and is valid until this context is destroyed.
- virtual gpu::CommandBuffer* GetCommandBuffer() = 0;
+ // If the plugin instance is backed by an OpenGL, return its ID in the
+ // compositors namespace. Otherwise return 0. Returns 0 by default.
+ virtual unsigned GetBackingTextureId() = 0;
- // Sets the function to be called on repaint.
- virtual void SetNotifyRepaintTask(Task* task) = 0;
+ // This call will return the address of the GLES2 implementation for this
+ // context that is constructed in Initialize() and is valid until this
+ // context is destroyed.
+ virtual gpu::gles2::GLES2Implementation* GetGLES2Implementation() = 0;
};
class PlatformAudio {
diff --git a/webkit/glue/plugins/pepper_plugin_instance.cc b/webkit/glue/plugins/pepper_plugin_instance.cc
index 31ef4da..8a20e74 100644
--- a/webkit/glue/plugins/pepper_plugin_instance.cc
+++ b/webkit/glue/plugins/pepper_plugin_instance.cc
@@ -50,6 +50,7 @@
#include "webkit/glue/plugins/pepper_buffer.h"
#include "webkit/glue/plugins/pepper_common.h"
#include "webkit/glue/plugins/pepper_graphics_2d.h"
+#include "webkit/glue/plugins/pepper_graphics_3d.h"
#include "webkit/glue/plugins/pepper_event_conversion.h"
#include "webkit/glue/plugins/pepper_fullscreen_container.h"
#include "webkit/glue/plugins/pepper_image_data.h"
@@ -161,11 +162,11 @@ PP_Var GetOwnerElementObject(PP_Instance instance_id) {
return instance->GetOwnerElementObject();
}
-PP_Bool BindGraphics(PP_Instance instance_id, PP_Resource device_id) {
+PP_Bool BindGraphics(PP_Instance instance_id, PP_Resource graphics_id) {
PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
if (!instance)
return PP_FALSE;
- return BoolToPPBool(instance->BindGraphics(device_id));
+ return BoolToPPBool(instance->BindGraphics(graphics_id));
}
PP_Bool IsFullFrame(PP_Instance instance_id) {
@@ -339,8 +340,8 @@ const PPB_Zoom_Dev* PluginInstance::GetZoomInterface() {
void PluginInstance::Paint(WebCanvas* canvas,
const gfx::Rect& plugin_rect,
const gfx::Rect& paint_rect) {
- if (bound_graphics_2d_)
- bound_graphics_2d_->Paint(canvas, plugin_rect, paint_rect);
+ if (bound_graphics_2d())
+ bound_graphics_2d()->Paint(canvas, plugin_rect, paint_rect);
}
void PluginInstance::InvalidateRect(const gfx::Rect& rect) {
@@ -373,6 +374,17 @@ void PluginInstance::ScrollRect(int dx, int dy, const gfx::Rect& rect) {
}
}
+unsigned PluginInstance::GetBackingTextureId() {
+ if (!bound_graphics_3d())
+ return 0;
+
+ return bound_graphics_3d()->GetBackingTextureId();
+}
+
+void PluginInstance::CommitBackingTexture() {
+ container_->commitBackingTexture();
+}
+
PP_Var PluginInstance::GetWindowObject() {
if (!container_)
return PP_MakeUndefined();
@@ -391,35 +403,44 @@ PP_Var PluginInstance::GetOwnerElementObject() {
container_->scriptableObjectForElement());
}
-bool PluginInstance::BindGraphics(PP_Resource device_id) {
- if (!device_id) {
+bool PluginInstance::BindGraphics(PP_Resource graphics_id) {
+ if (!graphics_id) {
// Special-case clearing the current device.
- if (bound_graphics_2d_) {
- bound_graphics_2d_->BindToInstance(NULL);
- bound_graphics_2d_ = NULL;
+ if (bound_graphics_.get()) {
+ if (bound_graphics_2d()) {
+ bound_graphics_2d()->BindToInstance(NULL);
+ } else if (bound_graphics_.get()) {
+ bound_graphics_3d()->SetSwapBuffersCallback(NULL);
+ bound_graphics_3d()->BindToInstance(NULL);
+ }
InvalidateRect(gfx::Rect());
}
+ bound_graphics_ = NULL;
return true;
}
- scoped_refptr<Graphics2D> device_2d = Resource::GetAs<Graphics2D>(device_id);
+ scoped_refptr<Graphics2D> graphics_2d =
+ Resource::GetAs<Graphics2D>(graphics_id);
+ scoped_refptr<Graphics3D> graphics_3d =
+ Resource::GetAs<Graphics3D>(graphics_id);
- if (device_2d) {
- if (!device_2d->BindToInstance(this))
+ if (graphics_2d) {
+ if (!graphics_2d->BindToInstance(this))
return false; // Can't bind to more than one instance.
+ bound_graphics_ = graphics_2d;
// See http://crbug.com/49403: this can be further optimized by keeping the
// old device around and painting from it.
- if (bound_graphics_2d_.get()) {
+ if (bound_graphics_2d()) {
// Start the new image with the content of the old image until the plugin
// repaints.
const SkBitmap* old_backing_bitmap =
- bound_graphics_2d_->image_data()->GetMappedBitmap();
+ bound_graphics_2d()->image_data()->GetMappedBitmap();
SkRect old_size = SkRect::MakeWH(
SkScalar(static_cast<float>(old_backing_bitmap->width())),
SkScalar(static_cast<float>(old_backing_bitmap->height())));
- SkCanvas canvas(*device_2d->image_data()->GetMappedBitmap());
+ SkCanvas canvas(*graphics_2d->image_data()->GetMappedBitmap());
canvas.drawBitmap(*old_backing_bitmap, 0, 0);
// Fill in any extra space with white.
@@ -427,8 +448,14 @@ bool PluginInstance::BindGraphics(PP_Resource device_id) {
canvas.drawARGB(255, 255, 255, 255);
}
- bound_graphics_2d_ = device_2d;
// BindToInstance will have invalidated the plugin if necessary.
+ } else if (graphics_3d) {
+ if (!graphics_3d->BindToInstance(this))
+ return false;
+
+ bound_graphics_ = graphics_3d;
+ bound_graphics_3d()->SetSwapBuffersCallback(
+ NewCallback(this, &PluginInstance::CommitBackingTexture));
}
return true;
@@ -538,7 +565,17 @@ PP_Var PluginInstance::GetInstanceObject() {
void PluginInstance::ViewChanged(const gfx::Rect& position,
const gfx::Rect& clip) {
+ if (position.size() != position_.size() && bound_graphics_3d()) {
+ // TODO(apatrick): This is a hack to force the back buffer to resize.
+ // It is obviously wrong to call SwapBuffers when a partial frame has
+ // potentially been rendered. Plan is to embed resize commands in the
+ // command buffer just before ViewChanged is called.
+ bound_graphics_3d()->ResizeBackingTexture(position.size());
+ bound_graphics_3d()->SwapBuffers();
+ }
+
position_ = position;
+
if (clip.IsEmpty()) {
// WebKit can give weird (x,y) positions for empty clip rects (since the
// position technically doesn't matter). But we want to make these
@@ -580,13 +617,13 @@ void PluginInstance::SetContentAreaFocus(bool has_focus) {
}
void PluginInstance::ViewInitiatedPaint() {
- if (bound_graphics_2d_)
- bound_graphics_2d_->ViewInitiatedPaint();
+ if (bound_graphics_2d())
+ bound_graphics_2d()->ViewInitiatedPaint();
}
void PluginInstance::ViewFlushedPaint() {
- if (bound_graphics_2d_)
- bound_graphics_2d_->ViewFlushedPaint();
+ if (bound_graphics_2d())
+ bound_graphics_2d()->ViewFlushedPaint();
}
bool PluginInstance::GetBitmapForOptimizedPluginPaint(
@@ -596,13 +633,13 @@ bool PluginInstance::GetBitmapForOptimizedPluginPaint(
gfx::Rect* clip) {
if (!always_on_top_)
return false;
- if (!bound_graphics_2d_ || !bound_graphics_2d_->is_always_opaque())
+ if (!bound_graphics_2d() || !bound_graphics_2d()->is_always_opaque())
return false;
// We specifically want to compare against the area covered by the backing
// store when seeing if we cover the given paint bounds, since the backing
// store could be smaller than the declared plugin area.
- ImageData* image_data = bound_graphics_2d_->image_data();
+ ImageData* image_data = bound_graphics_2d()->image_data();
gfx::Rect plugin_backing_store_rect(position_.origin(),
gfx::Size(image_data->width(),
image_data->height()));
@@ -838,16 +875,6 @@ void PluginInstance::PrintEnd() {
#endif // defined(OS_LINUX)
}
-void PluginInstance::Graphics3DContextLost() {
- if (!plugin_graphics_3d_interface_) {
- plugin_graphics_3d_interface_ =
- reinterpret_cast<const PPP_Graphics3D_Dev*>(module_->GetPluginInterface(
- PPP_GRAPHICS_3D_DEV_INTERFACE));
- }
- if (plugin_graphics_3d_interface_)
- plugin_graphics_3d_interface_->Graphics3DContextLost(pp_instance());
-}
-
bool PluginInstance::IsFullscreen() {
return fullscreen_container_ != NULL;
}
@@ -1118,5 +1145,18 @@ void PluginInstance::DrawSkBitmapToCanvas(
}
#endif // defined(OS_MACOSX)
+Graphics2D* PluginInstance::bound_graphics_2d() const {
+ if (bound_graphics_.get() == NULL)
+ return NULL;
+
+ return bound_graphics_->Cast<Graphics2D>();
+}
+
+Graphics3D* PluginInstance::bound_graphics_3d() const {
+ if (bound_graphics_.get() == NULL)
+ return NULL;
+
+ return bound_graphics_->Cast<Graphics3D>();
+}
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_plugin_instance.h b/webkit/glue/plugins/pepper_plugin_instance.h
index c348f66..4ee92b7 100644
--- a/webkit/glue/plugins/pepper_plugin_instance.h
+++ b/webkit/glue/plugins/pepper_plugin_instance.h
@@ -48,9 +48,11 @@ class WebPluginContainer;
namespace pepper {
class Graphics2D;
+class Graphics3D;
class ImageData;
class PluginDelegate;
class PluginModule;
+class Resource;
class URLLoader;
class FullscreenContainer;
@@ -105,10 +107,18 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
// slow path can also be triggered if there is an overlapping frame.
void ScrollRect(int dx, int dy, const gfx::Rect& rect);
+ // If the plugin instance is backed by a texture, return its texture ID in the
+ // compositor's namespace. Otherwise return 0. Returns 0 by default.
+ virtual unsigned GetBackingTextureId();
+
+ // Commit the backing texture to the screen once the side effects some
+ // rendering up to an offscreen SwapBuffers are visible.
+ void CommitBackingTexture();
+
// PPB_Instance implementation.
PP_Var GetWindowObject();
PP_Var GetOwnerElementObject();
- bool BindGraphics(PP_Resource device_id);
+ bool BindGraphics(PP_Resource graphics_id);
bool full_frame() const { return full_frame_; }
bool SetCursor(PP_CursorType_Dev type);
PP_Var ExecuteScript(PP_Var script, PP_Var* exception);
@@ -195,6 +205,14 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
const gfx::Rect& dest_rect, int canvas_height);
#endif // OS_MACOSX
+ // Get the bound graphics context as a concrete 2D graphics context or returns
+ // null if the context is not 2D.
+ Graphics2D* bound_graphics_2d() const;
+
+ // Get the bound graphics context as a concrete 3D graphics context or returns
+ // null if the context is not 3D.
+ Graphics3D* bound_graphics_3d() const;
+
PluginDelegate* delegate_;
scoped_refptr<PluginModule> module_;
const PPP_Instance* instance_interface_;
@@ -218,6 +236,9 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
// be (0, 0, w, h) regardless of scroll position.
gfx::Rect clip_;
+ // The current device context for painting in 2D or 3D.
+ scoped_refptr<Resource> bound_graphics_;
+
// We track two types of focus, one from WebKit, which is the focus among
// all elements of the page, one one from the browser, which is whether the
// tab/window has focus. We tell the plugin it has focus only when both of
@@ -225,9 +246,6 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
bool has_webkit_focus_;
bool has_content_area_focus_;
- // The current device context for painting in 2D.
- scoped_refptr<Graphics2D> bound_graphics_2d_;
-
// The id of the current find operation, or -1 if none is in process.
int find_identifier_;
diff --git a/webkit/glue/plugins/pepper_webplugin_impl.cc b/webkit/glue/plugins/pepper_webplugin_impl.cc
index 0fa6cdb..8da398f 100644
--- a/webkit/glue/plugins/pepper_webplugin_impl.cc
+++ b/webkit/glue/plugins/pepper_webplugin_impl.cc
@@ -109,6 +109,10 @@ void WebPluginImpl::updateGeometry(
instance_->ViewChanged(plugin_rect_, clip_rect);
}
+unsigned WebPluginImpl::getBackingTextureId() {
+ return instance_->GetBackingTextureId();
+}
+
void WebPluginImpl::updateFocus(bool focused) {
instance_->SetWebKitFocus(focused);
}
diff --git a/webkit/glue/plugins/pepper_webplugin_impl.h b/webkit/glue/plugins/pepper_webplugin_impl.h
index 15ee784..8922143 100644
--- a/webkit/glue/plugins/pepper_webplugin_impl.h
+++ b/webkit/glue/plugins/pepper_webplugin_impl.h
@@ -46,6 +46,7 @@ class WebPluginImpl : public WebKit::WebPlugin {
const WebKit::WebRect& clip_rect,
const WebKit::WebVector<WebKit::WebRect>& cut_outs_rects,
bool is_visible);
+ virtual unsigned getBackingTextureId();
virtual void updateFocus(bool focused);
virtual void updateVisibility(bool visible);
virtual bool acceptsInputEvents();
diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc
index df949d0..b271e4d 100644
--- a/webkit/glue/plugins/plugin_instance.cc
+++ b/webkit/glue/plugins/plugin_instance.cc
@@ -178,6 +178,11 @@ void PluginInstance::DidFinishLoadWithReason(
NPP_URLNotify(url.spec().c_str(), reason, notify_data);
}
+unsigned PluginInstance::GetBackingTextureId() {
+ // By default the plugin instance is not backed by an OpenGL texture.
+ return 0;
+}
+
// NPAPI methods
NPError PluginInstance::NPP_New(unsigned short mode,
short argc,
diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h
index 0dd3ee4..c853bfa 100644
--- a/webkit/glue/plugins/plugin_instance.h
+++ b/webkit/glue/plugins/plugin_instance.h
@@ -161,6 +161,10 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> {
bool use_mozilla_user_agent() { return use_mozilla_user_agent_; }
void set_use_mozilla_user_agent() { use_mozilla_user_agent_ = true; }
+ // If the plugin instance is backed by a texture, return its ID in the
+ // compositor's namespace. Otherwise return 0. Returns 0 by default.
+ virtual unsigned GetBackingTextureId();
+
// Helper that implements NPN_PluginThreadAsyncCall semantics
void PluginThreadAsyncCall(void (*func)(void *),
void *userData);
diff --git a/webkit/glue/plugins/webplugin_impl.cc b/webkit/glue/plugins/webplugin_impl.cc
index d033eb3..80774ff 100644
--- a/webkit/glue/plugins/webplugin_impl.cc
+++ b/webkit/glue/plugins/webplugin_impl.cc
@@ -327,6 +327,11 @@ void WebPluginImpl::updateGeometry(
first_geometry_update_ = false;
}
+unsigned WebPluginImpl::getBackingTextureId() {
+ // Regular plugins do not have a backing texture.
+ return 0;
+}
+
void WebPluginImpl::updateFocus(bool focused) {
if (accepts_input_events_)
delegate_->SetFocus(focused);
diff --git a/webkit/glue/plugins/webplugin_impl.h b/webkit/glue/plugins/webplugin_impl.h
index cb0970b..58289d6 100644
--- a/webkit/glue/plugins/webplugin_impl.h
+++ b/webkit/glue/plugins/webplugin_impl.h
@@ -73,6 +73,7 @@ class WebPluginImpl : public WebPlugin,
virtual void updateGeometry(
const WebKit::WebRect& frame_rect, const WebKit::WebRect& clip_rect,
const WebKit::WebVector<WebKit::WebRect>& cut_outs, bool is_visible);
+ virtual unsigned getBackingTextureId();
virtual void updateFocus(bool focused);
virtual void updateVisibility(bool visible);
virtual bool acceptsInputEvents();