summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/renderer/pepper_plugin_delegate_impl.cc17
-rw-r--r--chrome/renderer/pepper_plugin_delegate_impl.h6
-rw-r--r--chrome/renderer/render_view.cc5
-rw-r--r--chrome/renderer/render_view.h2
-rw-r--r--chrome/renderer/render_widget.cc27
-rw-r--r--chrome/renderer/render_widget.h13
-rw-r--r--webkit/glue/plugins/pepper_graphics_2d.cc18
-rw-r--r--webkit/glue/plugins/pepper_graphics_2d.h6
-rw-r--r--webkit/glue/plugins/pepper_image_data.h4
-rw-r--r--webkit/glue/plugins/pepper_plugin_delegate.h4
-rw-r--r--webkit/glue/plugins/pepper_plugin_instance.cc24
-rw-r--r--webkit/glue/plugins/pepper_plugin_instance.h14
-rw-r--r--webkit/glue/plugins/pepper_plugin_module.cc4
-rw-r--r--webkit/glue/plugins/pepper_private2.cc32
-rw-r--r--webkit/glue/plugins/pepper_private2.h23
-rw-r--r--webkit/glue/plugins/ppb_private2.h21
-rw-r--r--webkit/glue/webkit_glue.gypi2
17 files changed, 214 insertions, 8 deletions
diff --git a/chrome/renderer/pepper_plugin_delegate_impl.cc b/chrome/renderer/pepper_plugin_delegate_impl.cc
index 3a866af..5f73ea7 100644
--- a/chrome/renderer/pepper_plugin_delegate_impl.cc
+++ b/chrome/renderer/pepper_plugin_delegate_impl.cc
@@ -53,6 +53,10 @@ class PlatformImage2DImpl : public pepper::PluginDelegate::PlatformImage2D {
return reinterpret_cast<intptr_t>(dib_.get());
}
+ virtual TransportDIB* GetTransportDIB() const {
+ return dib_.get();
+ }
+
private:
int width_;
int height_;
@@ -520,6 +524,19 @@ void PepperPluginDelegateImpl::ViewFlushedPaint() {
}
}
+bool PepperPluginDelegateImpl::GetBitmapForOptimizedPluginPaint(
+ gfx::Rect* bounds,
+ TransportDIB** dib) {
+ for (std::set<pepper::PluginInstance*>::iterator i =
+ active_instances_.begin();
+ i != active_instances_.end(); ++i) {
+ pepper::PluginInstance* instance = *i;
+ if (instance->GetBitmapForOptimizedPluginPaint(bounds, dib))
+ return true;
+ }
+ return false;
+}
+
void PepperPluginDelegateImpl::InstanceCreated(
pepper::PluginInstance* instance) {
active_instances_.insert(instance);
diff --git a/chrome/renderer/pepper_plugin_delegate_impl.h b/chrome/renderer/pepper_plugin_delegate_impl.h
index 19f08b1c..0119148 100644
--- a/chrome/renderer/pepper_plugin_delegate_impl.h
+++ b/chrome/renderer/pepper_plugin_delegate_impl.h
@@ -29,6 +29,8 @@ class WebFileChooserCompletion;
struct WebFileChooserParams;
}
+class TransportDIB;
+
class PepperPluginDelegateImpl
: public pepper::PluginDelegate,
public base::SupportsWeakPtr<PepperPluginDelegateImpl> {
@@ -41,6 +43,10 @@ class PepperPluginDelegateImpl
void ViewInitiatedPaint();
void ViewFlushedPaint();
+ // Called by RenderView to implement the corresponding function in its base
+ // class RenderWidget (see that for more).
+ bool GetBitmapForOptimizedPluginPaint(gfx::Rect* bounds, TransportDIB** dib);
+
// Called by RenderView when ViewMsg_AsyncOpenFile_ACK.
void OnAsyncFileOpened(base::PlatformFileError error_code,
base::PlatformFile file,
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index ae155e8..98cc445 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -4717,6 +4717,11 @@ void RenderView::DidFlushPaint() {
}
}
+bool RenderView::GetBitmapForOptimizedPluginPaint(gfx::Rect* bounds,
+ TransportDIB** dib) {
+ return pepper_delegate_.GetBitmapForOptimizedPluginPaint(bounds, dib);
+}
+
void RenderView::OnClearFocusedNode() {
if (webview())
webview()->clearFocusedNode();
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 01f9655..1a733fe 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -608,6 +608,8 @@ class RenderView : public RenderWidget,
const gfx::Rect& resizer_rect);
virtual void DidInitiatePaint();
virtual void DidFlushPaint();
+ virtual bool GetBitmapForOptimizedPluginPaint(gfx::Rect* bounds,
+ TransportDIB** dib);
virtual void DidHandleKeyEvent();
virtual void DidHandleMouseEvent(const WebKit::WebMouseEvent& event);
virtual void OnSetFocus(bool enable);
diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc
index 3252097..95346c3 100644
--- a/chrome/renderer/render_widget.cc
+++ b/chrome/renderer/render_widget.cc
@@ -505,11 +505,21 @@ void RenderWidget::DoDeferredUpdate() {
gfx::Rect scroll_damage = update.GetScrollDamage();
gfx::Rect bounds = update.GetPaintBounds().Union(scroll_damage);
+ // A plugin may be able to do an optimized paint. First check this, in which
+ // case we can skip all of the bitmap generation and regular paint code.
+ TransportDIB::Id dib_id;
+ TransportDIB* dib = NULL;
std::vector<gfx::Rect> copy_rects;
- if (!is_gpu_rendering_active_) {
+ if (update.scroll_rect.IsEmpty() &&
+ !is_gpu_rendering_active_ &&
+ GetBitmapForOptimizedPluginPaint(&bounds, &dib)) {
+ copy_rects.push_back(bounds);
+ dib_id = dib->id();
+ } else if (!is_gpu_rendering_active_) {
// Compute a buffer for painting and cache it.
- scoped_ptr<skia::PlatformCanvas> canvas
- (RenderProcess::current()->GetDrawingCanvas(&current_paint_buf_, bounds));
+ scoped_ptr<skia::PlatformCanvas> canvas(
+ RenderProcess::current()->GetDrawingCanvas(&current_paint_buf_,
+ bounds));
if (!canvas.get()) {
NOTREACHED();
return;
@@ -538,6 +548,8 @@ void RenderWidget::DoDeferredUpdate() {
for (size_t i = 0; i < copy_rects.size(); ++i)
PaintRect(copy_rects[i], bounds.origin(), canvas.get());
+
+ dib_id = current_paint_buf_->id();
} else { // Accelerated compositing path
// Begin painting.
bool finish = next_paint_is_resize_ack();
@@ -546,8 +558,7 @@ void RenderWidget::DoDeferredUpdate() {
// sending an ack to browser process that the paint is complete...
ViewHostMsg_UpdateRect_Params params;
- params.bitmap =
- current_paint_buf_ ? current_paint_buf_->id() : TransportDIB::Id();
+ params.bitmap = dib_id;
params.bitmap_rect = bounds;
params.dx = update.scroll_delta.x();
params.dy = update.scroll_delta.y();
@@ -889,6 +900,12 @@ void RenderWidget::OnSetTextDirection(WebTextDirection direction) {
webwidget_->setTextDirection(direction);
}
+bool RenderWidget::GetBitmapForOptimizedPluginPaint(gfx::Rect* bounds,
+ TransportDIB** dib) {
+ // Normal RenderWidgets don't support optimized plugin painting.
+ return false;
+}
+
void RenderWidget::SetHidden(bool hidden) {
if (is_hidden_ == hidden)
return;
diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h
index 7f9e247..61abdee 100644
--- a/chrome/renderer/render_widget.h
+++ b/chrome/renderer/render_widget.h
@@ -197,6 +197,19 @@ class RenderWidget : public IPC::Channel::Listener,
virtual void DidInitiatePaint() {}
virtual void DidFlushPaint() {}
+ // Detects if a suitable opaque plugin covers |*bounds| with no compositing
+ // necessary.
+ //
+ // Returns true if the paint can be handled by just blitting the plugin
+ // bitmap. In this case, the |*dib| parameter will contain the TransportDIB
+ // and the |*bounds| will be updated to contain the rect on the page that
+ // contains the given DIB (this may go off the visible page).
+ //
+ // A return value of false means optimized painting can not be used and we
+ // should continue with the normal painting code path.
+ virtual bool GetBitmapForOptimizedPluginPaint(gfx::Rect* bounds,
+ TransportDIB** dib);
+
// Sets the "hidden" state of this widget. All accesses to is_hidden_ should
// use this method so that we can properly inform the RenderThread of our
// state.
diff --git a/webkit/glue/plugins/pepper_graphics_2d.cc b/webkit/glue/plugins/pepper_graphics_2d.cc
index 049c17d..5011f87 100644
--- a/webkit/glue/plugins/pepper_graphics_2d.cc
+++ b/webkit/glue/plugins/pepper_graphics_2d.cc
@@ -174,7 +174,8 @@ Graphics2D::Graphics2D(PluginModule* module)
: Resource(module),
bound_instance_(NULL),
flushed_any_data_(false),
- offscreen_flush_pending_(false) {
+ offscreen_flush_pending_(false),
+ is_always_opaque_(false) {
}
Graphics2D::~Graphics2D() {
@@ -193,7 +194,7 @@ bool Graphics2D::Init(int width, int height, bool is_always_opaque) {
image_data_ = NULL;
return false;
}
-
+ is_always_opaque_ = is_always_opaque;
return true;
}
@@ -445,13 +446,24 @@ void Graphics2D::Paint(WebKit::WebCanvas* canvas,
bounds.size.width = backing_bitmap.width();
bounds.size.height = backing_bitmap.height();
+ // TODO(brettw) bug 56673: do a direct memcpy instead of going through CG
+ // if the is_always_opaque_ flag is set.
+
CGContextDrawImage(canvas, bounds, image);
CGContextRestoreGState(canvas);
#else
+ SkPaint paint;
+ if (is_always_opaque_) {
+ // When we know the device is opaque, we can disable blending for slightly
+ // more optimized painting.
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode);
+ }
+
gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y());
canvas->drawBitmap(backing_bitmap,
SkIntToScalar(plugin_rect.origin().x()),
- SkIntToScalar(plugin_rect.origin().y()));
+ SkIntToScalar(plugin_rect.origin().y()),
+ &paint);
#endif
}
diff --git a/webkit/glue/plugins/pepper_graphics_2d.h b/webkit/glue/plugins/pepper_graphics_2d.h
index c3fad68..3af84ded 100644
--- a/webkit/glue/plugins/pepper_graphics_2d.h
+++ b/webkit/glue/plugins/pepper_graphics_2d.h
@@ -36,6 +36,8 @@ class Graphics2D : public Resource {
bool Init(int width, int height, bool is_always_opaque);
+ bool is_always_opaque() const { return is_always_opaque_; }
+
// Resource override.
virtual Graphics2D* AsGraphics2D() { return this; }
@@ -166,6 +168,10 @@ class Graphics2D : public Resource {
// enforce the "only one pending flush at a time" constraint in the API.
bool offscreen_flush_pending_;
+ // Set to true if the plugin declares that this device will always be opaque.
+ // This allows us to do more optimized painting in some cases.
+ bool is_always_opaque_;
+
DISALLOW_COPY_AND_ASSIGN(Graphics2D);
};
diff --git a/webkit/glue/plugins/pepper_image_data.h b/webkit/glue/plugins/pepper_image_data.h
index c5937b2..04d769c 100644
--- a/webkit/glue/plugins/pepper_image_data.h
+++ b/webkit/glue/plugins/pepper_image_data.h
@@ -37,6 +37,10 @@ class ImageData : public Resource {
// invalid or not mapped. See ImageDataAutoMapper below.
bool is_mapped() const { return !!mapped_canvas_.get(); }
+ PluginDelegate::PlatformImage2D* platform_image() const {
+ return platform_image_.get();
+ }
+
// Returns a pointer to the interface implementing PPB_ImageData that is
// exposed to the plugin.
static const PPB_ImageData* GetInterface();
diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h
index d650fa9..3bd8897 100644
--- a/webkit/glue/plugins/pepper_plugin_delegate.h
+++ b/webkit/glue/plugins/pepper_plugin_delegate.h
@@ -44,6 +44,8 @@ struct PP_VideoCompressedDataBuffer_Dev;
struct PP_VideoDecoderConfig_Dev;
struct PP_VideoUncompressedDataBuffer_Dev;
+class TransportDIB;
+
namespace pepper {
class FileIO;
@@ -67,6 +69,8 @@ class PluginDelegate {
// this image. This is used by NativeClient to send the image to the
// out-of-process plugin. Returns 0 on failure.
virtual intptr_t GetSharedMemoryHandle() const = 0;
+
+ virtual TransportDIB* GetTransportDIB() const = 0;
};
class PlatformContext3D {
diff --git a/webkit/glue/plugins/pepper_plugin_instance.cc b/webkit/glue/plugins/pepper_plugin_instance.cc
index b246872..ae0cdcc 100644
--- a/webkit/glue/plugins/pepper_plugin_instance.cc
+++ b/webkit/glue/plugins/pepper_plugin_instance.cc
@@ -247,6 +247,7 @@ PluginInstance::PluginInstance(PluginDelegate* delegate,
#endif // defined (OS_LINUX)
plugin_print_interface_(NULL),
plugin_graphics_3d_interface_(NULL),
+ always_on_top_(false),
fullscreen_container_(NULL) {
memset(&current_print_settings_, 0, sizeof(current_print_settings_));
DCHECK(delegate);
@@ -500,6 +501,29 @@ void PluginInstance::ViewFlushedPaint() {
bound_graphics_2d_->ViewFlushedPaint();
}
+bool PluginInstance::GetBitmapForOptimizedPluginPaint(gfx::Rect* bounds,
+ TransportDIB** dib) {
+ if (!always_on_top_)
+ return false;
+ 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();
+ gfx::Rect plugin_backing_store_rect(position_.origin(),
+ gfx::Size(image_data->width(),
+ image_data->height()));
+ if (!plugin_backing_store_rect.Contains(*bounds))
+ return false;
+
+ // TODO(brettw) implement detection for always-on-top.
+ *bounds = plugin_backing_store_rect;
+ *dib = image_data->platform_image()->GetTransportDIB();
+ return true;
+}
+
string16 PluginInstance::GetSelectedText(bool html) {
PP_Var rv = instance_interface_->GetSelectedText(GetPPInstance(), html);
scoped_refptr<StringVar> string(StringVar::FromPPVar(rv));
diff --git a/webkit/glue/plugins/pepper_plugin_instance.h b/webkit/glue/plugins/pepper_plugin_instance.h
index 0ed6ee6..8837193 100644
--- a/webkit/glue/plugins/pepper_plugin_instance.h
+++ b/webkit/glue/plugins/pepper_plugin_instance.h
@@ -30,6 +30,7 @@ struct PPP_Instance;
struct PPP_Zoom_Dev;
class SkBitmap;
+class TransportDIB;
namespace gfx {
class Rect;
@@ -77,6 +78,8 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
int find_identifier() const { return find_identifier_; }
+ void set_always_on_top(bool on_top) { always_on_top_ = on_top; }
+
PP_Instance GetPPInstance();
// Paints the current backing store to the web page.
@@ -117,6 +120,13 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
void ViewInitiatedPaint();
void ViewFlushedPaint();
+ // If this plugin can be painted merely by copying the backing store to the
+ // screen, and the plugin bounds encloses the given paint bounds, returns
+ // true. In this case, the bounds will be updated to enclose the area covering
+ // the backing store of the plugin, and the ID of the backing store will be
+ // placed in |*dib|.
+ bool GetBitmapForOptimizedPluginPaint(gfx::Rect* bounds, TransportDIB** dib);
+
string16 GetSelectedText(bool html);
void Zoom(float factor, bool text_only);
bool StartFind(const string16& search_text,
@@ -218,6 +228,10 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
// Containes the cursor if it's set by the plugin.
scoped_ptr<WebKit::WebCursorInfo> cursor_;
+ // Set to true if this plugin thinks it will always be on top. This allows us
+ // to use a more optimized painting path in some cases.
+ bool always_on_top_;
+
// Plugin container for fullscreen mode. NULL if not in fullscreen mode.
FullscreenContainer* fullscreen_container_;
diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc
index 7acf06239..e43735f 100644
--- a/webkit/glue/plugins/pepper_plugin_module.cc
+++ b/webkit/glue/plugins/pepper_plugin_module.cc
@@ -59,6 +59,7 @@
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_plugin_object.h"
#include "webkit/glue/plugins/pepper_private.h"
+#include "webkit/glue/plugins/pepper_private2.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"
#include "webkit/glue/plugins/pepper_scrollbar.h"
#include "webkit/glue/plugins/pepper_transport.h"
@@ -70,6 +71,7 @@
#include "webkit/glue/plugins/pepper_video_decoder.h"
#include "webkit/glue/plugins/pepper_widget.h"
#include "webkit/glue/plugins/ppb_private.h"
+#include "webkit/glue/plugins/ppb_private2.h"
#ifdef ENABLE_GPU
#include "webkit/glue/plugins/pepper_graphics_3d.h"
@@ -257,6 +259,8 @@ const void* GetInterface(const char* name) {
return UrlUtil::GetInterface();
if (strcmp(name, PPB_PRIVATE_INTERFACE) == 0)
return Private::GetInterface();
+ if (strcmp(name, PPB_PRIVATE2_INTERFACE) == 0)
+ return Private2::GetInterface();
if (strcmp(name, PPB_FILECHOOSER_DEV_INTERFACE) == 0)
return FileChooser::GetInterface();
if (strcmp(name, PPB_VIDEODECODER_DEV_INTERFACE) == 0)
diff --git a/webkit/glue/plugins/pepper_private2.cc b/webkit/glue/plugins/pepper_private2.cc
new file mode 100644
index 0000000..9a740aa
--- /dev/null
+++ b/webkit/glue/plugins/pepper_private2.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/glue/plugins/pepper_private2.h"
+
+#include "webkit/glue/plugins/pepper_plugin_instance.h"
+#include "webkit/glue/plugins/ppb_private2.h"
+
+namespace pepper {
+
+namespace {
+
+void SetInstanceAlwaysOnTop(PP_Instance pp_instance, bool on_top) {
+ PluginInstance* instance = PluginInstance::FromPPInstance(pp_instance);
+ if (!instance)
+ return;
+ instance->set_always_on_top(on_top);
+}
+
+const PPB_Private2 ppb_private2 = {
+ &SetInstanceAlwaysOnTop
+};
+
+} // namespace
+
+// static
+const PPB_Private2* Private2::GetInterface() {
+ return &ppb_private2;
+}
+
+} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_private2.h b/webkit/glue/plugins/pepper_private2.h
new file mode 100644
index 0000000..492669a
--- /dev/null
+++ b/webkit/glue/plugins/pepper_private2.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_PRIVATE2_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_PRIVATE2_H_
+
+#include "webkit/glue/plugins/pepper_resource.h"
+
+struct PPB_Private2;
+
+namespace pepper {
+
+class Private2 {
+ public:
+ // Returns a pointer to the interface implementing PPB_Private2 that is
+ // exposed to the plugin.
+ static const PPB_Private2* GetInterface();
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_PRIVATE2_H_
diff --git a/webkit/glue/plugins/ppb_private2.h b/webkit/glue/plugins/ppb_private2.h
new file mode 100644
index 0000000..ca45471
--- /dev/null
+++ b/webkit/glue/plugins/ppb_private2.h
@@ -0,0 +1,21 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_GLUE_PLUGINS_PPB_PRIVATE2_H_
+#define WEBKIT_GLUE_PLUGINS_PPB_PRIVATE2_H_
+
+#include "third_party/ppapi/c/pp_instance.h"
+#include "third_party/ppapi/c/pp_module.h"
+#include "third_party/ppapi/c/pp_var.h"
+
+#define PPB_PRIVATE2_INTERFACE "PPB_Private2;1"
+
+struct PPB_Private2 {
+ // Sets or clears the rendering hint that the given plugin instance is always
+ // on top of page content. Somewhat more optimized painting can be used in
+ // this case.
+ void (*SetInstanceAlwaysOnTop)(PP_Instance instance, bool on_top);
+};
+
+#endif // WEBKIT_GLUE_PLUGINS_PPB_PRIVATE2_H_
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index e27f297..354b2d0 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -222,6 +222,8 @@
'plugins/pepper_plugin_object.h',
'plugins/pepper_private.cc',
'plugins/pepper_private.h',
+ 'plugins/pepper_private2.cc',
+ 'plugins/pepper_private2.h',
'plugins/pepper_resource_tracker.cc',
'plugins/pepper_resource_tracker.h',
'plugins/pepper_resource.cc',