summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-23 16:20:01 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-23 16:20:01 +0000
commit558833a430fd4b8cb2ab88d1bc4bdc580cbc11aa (patch)
tree9edd73b2b08cc1c5faa9bf531c05297f06261705
parentce2d6425e1d30127726c6c7c4482cc4a1f38c086 (diff)
downloadchromium_src-558833a430fd4b8cb2ab88d1bc4bdc580cbc11aa.zip
chromium_src-558833a430fd4b8cb2ab88d1bc4bdc580cbc11aa.tar.gz
chromium_src-558833a430fd4b8cb2ab88d1bc4bdc580cbc11aa.tar.bz2
Push the native canvas into the plugin implementation. On Windows, this means
using SkCanvas instead of an HDC. This way, the pepper implementation can use the more advanced blending of SkCanvas and avoid the Windows API. I did some refactoring in the standard plugin implementation to support this and make it as clean as I could. Hopefully the code is slightly clearer than before. TEST=none BUG=none Review URL: http://codereview.chromium.org/306027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29897 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/plugin/webplugin_proxy.cc152
-rw-r--r--chrome/plugin/webplugin_proxy.h42
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.cc55
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.h9
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc54
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.h4
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h2
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_gtk.cc10
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_win.cc9
-rw-r--r--webkit/glue/webplugin_delegate.h10
-rw-r--r--webkit/glue/webplugin_impl.cc15
11 files changed, 165 insertions, 197 deletions
diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc
index 252f3f2..4e86173 100644
--- a/chrome/plugin/webplugin_proxy.cc
+++ b/chrome/plugin/webplugin_proxy.cc
@@ -361,41 +361,55 @@ bool WebPluginProxy::SetDropEffect(struct NPObject* event, int effect) {
}
void WebPluginProxy::Paint(const gfx::Rect& rect) {
-#if defined(OS_WIN)
- if (!windowless_hdc_)
+#if defined(OS_WIN) || defined(OS_LINUX)
+ if (!windowless_canvas_.get())
return;
#elif defined(OS_MACOSX)
if (!windowless_context_.get())
return;
-#elif defined(OS_LINUX)
- if (!windowless_canvas_.get())
- return;
#endif
// Clear the damaged area so that if the plugin doesn't paint there we won't
// end up with the old values.
gfx::Rect offset_rect = rect;
offset_rect.Offset(delegate_->GetRect().origin());
-#if defined(OS_WIN)
- if (!background_hdc_) {
- FillRect(windowless_hdc_, &offset_rect.ToRECT(),
- static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
+#if defined(OS_WIN) || defined(OS_LINUX)
+ windowless_canvas_->save();
+
+ // The given clip rect is in global coordinates, so install it before the
+ // transformation is done for the coordinate system.
+ SkRect sk_rect = { SkIntToScalar(rect.x()),
+ SkIntToScalar(rect.y()),
+ SkIntToScalar(rect.right()),
+ SkIntToScalar(rect.bottom()) };
+ windowless_canvas_->clipRect(sk_rect);
+ windowless_canvas_->translate(SkIntToScalar(-delegate_->GetRect().x()),
+ SkIntToScalar(-delegate_->GetRect().y()));
+
+ // Setup the background.
+ if (!background_canvas_.get()) {
+ SkPaint black_fill_paint;
+ black_fill_paint.setARGB(0xFF, 0x00, 0x00, 0x00);
+ windowless_canvas_->drawPaint(black_fill_paint);
} else {
- BitBlt(windowless_hdc_, offset_rect.x(), offset_rect.y(),
- offset_rect.width(), offset_rect.height(), background_hdc_,
- rect.x(), rect.y(), SRCCOPY);
+ SkIRect src_rect = { rect.x(), rect.y(),
+ rect.x() + offset_rect.width(),
+ rect.y() + offset_rect.height() };
+
+ SkRect dest_rect = { SkIntToScalar(offset_rect.x()),
+ SkIntToScalar(offset_rect.y()),
+ SkIntToScalar(offset_rect.right()),
+ SkIntToScalar(offset_rect.bottom()) };
+ const SkBitmap& background_bitmap =
+ background_canvas_->getTopPlatformDevice().accessBitmap(false);
+ windowless_canvas_->drawBitmapRect(background_bitmap, &src_rect, dest_rect);
}
- RECT clip_rect = rect.ToRECT();
- HRGN clip_region = CreateRectRgnIndirect(&clip_rect);
- SelectClipRgn(windowless_hdc_, clip_region);
-
// Before we send the invalidate, paint so that renderer uses the updated
// bitmap.
- delegate_->Paint(windowless_hdc_, offset_rect);
+ delegate_->Paint(windowless_canvas_.get(), offset_rect);
- SelectClipRgn(windowless_hdc_, NULL);
- DeleteObject(clip_region);
+ windowless_canvas_->restore();
#elif defined(OS_MACOSX)
CGContextSaveGState(windowless_context_);
if (!background_context_.get()) {
@@ -412,19 +426,6 @@ void WebPluginProxy::Paint(const gfx::Rect& rect) {
CGContextClipToRect(windowless_context_, rect.ToCGRect());
delegate_->Paint(windowless_context_, rect);
CGContextRestoreGState(windowless_context_);
-#else
- if (background_canvas_.get()) {
- BlitCanvasToCanvas(windowless_canvas_.get(), rect,
- background_canvas_.get(), rect.origin());
- }
- cairo_t* cairo =
- windowless_canvas_->getTopPlatformDevice().beginPlatformPaint();
- cairo_save(cairo);
- cairo_rectangle(cairo, rect.x(), rect.y(), rect.width(), rect.height());
- cairo_clip(cairo);
- cairo_translate(cairo, -delegate_->GetRect().x(), -delegate_->GetRect().y());
- delegate_->Paint(cairo, offset_rect);
- cairo_restore(cairo);
#endif
}
@@ -437,15 +438,11 @@ void WebPluginProxy::UpdateGeometry(
gfx::Rect old_clip_rect = delegate_->GetClipRect();
delegate_->UpdateGeometry(window_rect, clip_rect);
- bool moved = old.x() != window_rect.x() || old.y() != window_rect.y();
if (TransportDIB::is_valid(windowless_buffer)) {
// The plugin's rect changed, so now we have a new buffer to draw into.
- SetWindowlessBuffer(windowless_buffer,
- background_buffer);
- } else if (moved) {
- // The plugin moved, so update our world transform.
- UpdateTransform();
+ SetWindowlessBuffer(windowless_buffer, background_buffer);
}
+
// Send over any pending invalidates which occured when the plugin was
// off screen.
if (delegate_->IsWindowless() && !clip_rect.IsEmpty() &&
@@ -458,73 +455,24 @@ void WebPluginProxy::UpdateGeometry(
void WebPluginProxy::SetWindowlessBuffer(
const TransportDIB::Handle& windowless_buffer,
const TransportDIB::Handle& background_buffer) {
- // Convert the shared memory handle to a handle that works in our process,
- // and then use that to create an HDC.
- ConvertBuffer(windowless_buffer,
- &windowless_shared_section_,
- &windowless_bitmap_,
- &windowless_hdc_);
+ // Create a canvas that will reference the shared bits.
+ windowless_canvas_.reset(new skia::PlatformCanvas(
+ delegate_->GetRect().width(),
+ delegate_->GetRect().height(),
+ true,
+ win_util::GetSectionFromProcess(windowless_buffer,
+ channel_->renderer_handle(), false)));
if (background_buffer) {
- ConvertBuffer(background_buffer,
- &background_shared_section_,
- &background_bitmap_,
- &background_hdc_);
- }
- UpdateTransform();
-}
-
-void WebPluginProxy::ConvertBuffer(const base::SharedMemoryHandle& buffer,
- ScopedHandle* shared_section,
- ScopedBitmap* bitmap,
- ScopedHDC* hdc) {
- shared_section->Set(win_util::GetSectionFromProcess(
- buffer, channel_->renderer_handle(), false));
- if (shared_section->Get() == NULL) {
- NOTREACHED();
- return;
- }
-
- void* data = NULL;
- HDC screen_dc = GetDC(NULL);
- BITMAPINFOHEADER bitmap_header;
- gfx::CreateBitmapHeader(delegate_->GetRect().width(),
- delegate_->GetRect().height(),
- &bitmap_header);
- bitmap->Set(CreateDIBSection(
- screen_dc, reinterpret_cast<const BITMAPINFO*>(&bitmap_header),
- DIB_RGB_COLORS, &data, shared_section->Get(), 0));
- ReleaseDC(NULL, screen_dc);
- if (bitmap->Get() == NULL) {
- NOTREACHED();
- return;
- }
-
- hdc->Set(CreateCompatibleDC(NULL));
- if (hdc->Get() == NULL) {
- NOTREACHED();
- return;
+ background_canvas_.reset(new skia::PlatformCanvas(
+ delegate_->GetRect().width(),
+ delegate_->GetRect().height(),
+ true,
+ win_util::GetSectionFromProcess(background_buffer,
+ channel_->renderer_handle(), false)));
}
-
- skia::PlatformDevice::InitializeDC(hdc->Get());
- SelectObject(hdc->Get(), bitmap->Get());
}
-void WebPluginProxy::UpdateTransform() {
- if (!windowless_hdc_)
- return;
-
- XFORM xf;
- xf.eDx = static_cast<FLOAT>(-delegate_->GetRect().x());
- xf.eDy = static_cast<FLOAT>(-delegate_->GetRect().y());
- xf.eM11 = 1;
- xf.eM21 = 0;
- xf.eM12 = 0;
- xf.eM22 = 1;
- SetWorldTransform(windowless_hdc_, &xf);
-}
#elif defined(OS_MACOSX)
-void WebPluginProxy::UpdateTransform() {
-}
void WebPluginProxy::SetWindowlessBuffer(
const TransportDIB::Handle& windowless_buffer,
@@ -560,9 +508,8 @@ void WebPluginProxy::SetWindowlessBuffer(
static_cast<WebPluginDelegateImpl*>(delegate_)->UpdateContext(
windowless_context_);
}
+
#elif defined (OS_LINUX)
-void WebPluginProxy::UpdateTransform() {
-}
void WebPluginProxy::SetWindowlessBuffer(
const TransportDIB::Handle& windowless_buffer,
@@ -584,6 +531,7 @@ void WebPluginProxy::SetWindowlessBuffer(
background_canvas_.reset();
}
}
+
#endif
void WebPluginProxy::CancelDocumentLoad() {
diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h
index 8f74109..f75bd20 100644
--- a/chrome/plugin/webplugin_proxy.h
+++ b/chrome/plugin/webplugin_proxy.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_PLUGIN_PLUGIN_WEBPLUGIN_PROXY_H__
-#define CHROME_PLUGIN_PLUGIN_WEBPLUGIN_PROXY_H__
+#ifndef CHROME_PLUGIN_WEBPLUGIN_PROXY_H_
+#define CHROME_PLUGIN_WEBPLUGIN_PROXY_H_
#include <string>
@@ -134,19 +134,6 @@ class WebPluginProxy : public webkit_glue::WebPlugin {
void SetWindowlessBuffer(const TransportDIB::Handle& windowless_buffer,
const TransportDIB::Handle& background_buffer);
-#if defined(OS_WIN)
- // Converts a shared memory section handle from the renderer process into a
- // bitmap and hdc that are mapped to this process.
- void ConvertBuffer(const base::SharedMemoryHandle& buffer,
- ScopedHandle* shared_section,
- ScopedBitmap* bitmap,
- ScopedHDC* hdc);
-#endif
-
- // Called when a plugin's origin moves, so that we can update the world
- // transform of the local HDC.
- void UpdateTransform();
-
typedef base::hash_map<int, webkit_glue::WebPluginResourceClient*>
ResourceClientMap;
ResourceClientMap resource_clients_;
@@ -163,32 +150,25 @@ class WebPluginProxy : public webkit_glue::WebPlugin {
// The url of the main frame hosting the plugin.
GURL page_url_;
-#if defined(OS_WIN)
// Variables used for desynchronized windowless plugin painting. See note in
// webplugin_delegate_proxy.h for how this works.
-
- // These hold the bitmap where the plugin draws.
- ScopedHandle windowless_shared_section_;
- ScopedBitmap windowless_bitmap_;
- ScopedHDC windowless_hdc_;
-
- // These hold the bitmap of the background image.
- ScopedHandle background_shared_section_;
- ScopedBitmap background_bitmap_;
- ScopedHDC background_hdc_;
-#elif defined(OS_MACOSX)
+#if defined(OS_MACOSX)
scoped_ptr<TransportDIB> windowless_dib_;
scoped_ptr<TransportDIB> background_dib_;
scoped_cftyperef<CGContextRef> windowless_context_;
scoped_cftyperef<CGContextRef> background_context_;
-#elif defined(OS_LINUX)
- scoped_ptr<TransportDIB> windowless_dib_;
- scoped_ptr<TransportDIB> background_dib_;
+#else
scoped_ptr<skia::PlatformCanvas> windowless_canvas_;
scoped_ptr<skia::PlatformCanvas> background_canvas_;
+
+#if defined(OS_LINUX)
+ scoped_ptr<TransportDIB> windowless_dib_;
+ scoped_ptr<TransportDIB> background_dib_;
+#endif
+
#endif
ScopedRunnableMethodFactory<WebPluginProxy> runnable_method_factory_;
};
-#endif // CHROME_PLUGIN_PLUGIN_WEBPLUGIN_PROXY_H__
+#endif // CHROME_PLUGIN_WEBPLUGIN_PROXY_H_
diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc
index 5d8f8c2..6e7e9f0 100644
--- a/chrome/renderer/webplugin_delegate_pepper.cc
+++ b/chrome/renderer/webplugin_delegate_pepper.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
@@ -146,6 +146,7 @@ void WebPluginDelegatePepper::UpdateGeometry(
window_.x = window_rect_.x();
window_.y = window_rect_.y();
window_.type = NPWindowTypeDrawable;
+ instance()->NPP_SetWindow(&window_);
}
NPObject* WebPluginDelegatePepper::GetPluginScriptableObject() {
@@ -240,8 +241,7 @@ WebPluginDelegatePepper::WebPluginDelegatePepper(
instance_(instance),
parent_(containing_view),
buffer_size_(0),
- plugin_buffer_(0),
- background_canvas_(0) {
+ plugin_buffer_(0) {
// For now we keep a window struct, although it isn't used.
memset(&window_, 0, sizeof(window_));
// All Pepper plugins are windowless and transparent.
@@ -258,15 +258,17 @@ void WebPluginDelegatePepper::PluginDestroyed() {
delete this;
}
-void WebPluginDelegatePepper::Paint(gfx::NativeDrawingContext context,
+void WebPluginDelegatePepper::Paint(WebKit::WebCanvas* canvas,
const gfx::Rect& rect) {
- static StatsRate plugin_paint("Plugin.Paint");
- StatsScope<StatsRate> scope(plugin_paint);
+#if defined(OS_WIN)
// Blit from background_context to context.
- if (background_canvas_ != NULL) {
+ if (!committed_bitmap_.isNull()) {
gfx::Point origin(window_rect_.origin().x(), window_rect_.origin().y());
- gfx::BlitCanvasToContext(context, rect, background_canvas_, origin);
+ canvas->drawBitmap(committed_bitmap_,
+ SkIntToScalar(window_rect_.origin().x()),
+ SkIntToScalar(window_rect_.origin().y()));
}
+#endif
}
void WebPluginDelegatePepper::Print(gfx::NativeDrawingContext context) {
@@ -404,12 +406,25 @@ NPError WebPluginDelegatePepper::InitializeRenderContext(
case NPRenderGraphicsRGBA: {
int width = window_rect_.width();
int height = window_rect_.height();
- background_canvas_ = new skia::PlatformCanvas(width, height, false);
- plugin_canvas_ = plugin_buffer_->GetPlatformCanvas(width, height);
- if (background_canvas_ == NULL || plugin_canvas_ == NULL) {
+
+ plugin_canvas_.reset(plugin_buffer_->GetPlatformCanvas(width, height));
+ if (!plugin_canvas_.get())
return NPERR_GENERIC_ERROR;
- }
- context->u.graphicsRgba.region = plugin_buffer_->memory();
+
+ // Note that we need to get the address out of the bitmap rather than
+ // using plugin_buffer_->memory(). The memory() is when the bitmap data
+ // has had "Map" called on it. For Windows, this is separate than making a
+ // bitmap using the shared section.
+ const SkBitmap& plugin_bitmap =
+ plugin_canvas_->getTopPlatformDevice().accessBitmap(true);
+ SkAutoLockPixels locker(plugin_bitmap);
+
+ // TODO(brettw) this theoretically shouldn't be necessary. But the
+ // platform device on Windows will fill itself with green to help you
+ // catch areas you didn't paint.
+ plugin_bitmap.eraseARGB(0, 0, 0, 0);
+
+ context->u.graphicsRgba.region = plugin_bitmap.getAddr32(0, 0);
context->u.graphicsRgba.stride = width * kBytesPerPixel;
return NPERR_NO_ERROR;
}
@@ -418,11 +433,13 @@ NPError WebPluginDelegatePepper::InitializeRenderContext(
}
}
-NPError WebPluginDelegatePepper::FlushRenderContext(
- NPRenderContext* context) {
- gfx::BlitCanvasToCanvas(background_canvas_,
- window_rect_,
- plugin_canvas_,
- window_rect_.origin());
+NPError WebPluginDelegatePepper::FlushRenderContext(NPRenderContext* context) {
+ // TODO(brettw): we should have some kind of swapping of the canvases so we
+ // can double buffer while avoiding this deep copy.
+ if (!plugin_canvas_->getTopPlatformDevice().accessBitmap(false).copyTo(
+ &committed_bitmap_, SkBitmap::kARGB_8888_Config))
+ return NPERR_OUT_OF_MEMORY_ERROR;
+
+ committed_bitmap_.setIsOpaque(false);
return NPERR_NO_ERROR;
}
diff --git a/chrome/renderer/webplugin_delegate_pepper.h b/chrome/renderer/webplugin_delegate_pepper.h
index bc59b2a..9374268 100644
--- a/chrome/renderer/webplugin_delegate_pepper.h
+++ b/chrome/renderer/webplugin_delegate_pepper.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
@@ -15,6 +15,7 @@
#include "base/file_path.h"
#include "base/gfx/rect.h"
#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
#include "base/task.h"
#include "chrome/common/transport_dib.h"
#include "skia/ext/platform_canvas.h"
@@ -49,7 +50,7 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
virtual void PluginDestroyed();
virtual void UpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect);
- virtual void Paint(gfx::NativeDrawingContext context, const gfx::Rect& rect);
+ virtual void Paint(WebKit::WebCanvas* canvas, const gfx::Rect& rect);
virtual void Print(gfx::NativeDrawingContext context);
virtual void SetFocus();
virtual bool HandleInputEvent(const WebKit::WebInputEvent& event,
@@ -122,8 +123,8 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
size_t buffer_size_;
TransportDIB* plugin_buffer_;
static uint32 next_buffer_id;
- skia::PlatformCanvas* plugin_canvas_;
- skia::PlatformCanvas* background_canvas_;
+ scoped_ptr<skia::PlatformCanvas> plugin_canvas_;
+ SkBitmap committed_bitmap_;
// The url with which the plugin was instantiated.
std::string plugin_url_;
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index 20cea7f..5241ccb 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -514,7 +514,7 @@ static void FlipRectVerticallyWithHeight(gfx::Rect* rect, int height) {
}
#endif
-void WebPluginDelegateProxy::Paint(gfx::NativeDrawingContext context,
+void WebPluginDelegateProxy::Paint(WebKit::WebCanvas* canvas,
const gfx::Rect& damaged_rect) {
// Limit the damaged rectangle to whatever is contained inside the plugin
// rectangle, as that's the rectangle that we'll actually draw.
@@ -523,7 +523,7 @@ void WebPluginDelegateProxy::Paint(gfx::NativeDrawingContext context,
// If the plugin is no longer connected (channel crashed) draw a crashed
// plugin bitmap
if (!channel_host_ || !channel_host_->channel_valid()) {
- PaintSadPlugin(context, rect);
+ PaintSadPlugin(canvas, rect);
return;
}
@@ -533,9 +533,15 @@ void WebPluginDelegateProxy::Paint(gfx::NativeDrawingContext context,
// We got a paint before the plugin's coordinates, so there's no buffer to
// copy from.
- if (!backing_store_canvas_.get()) {
+ if (!backing_store_canvas_.get())
return;
- }
+
+ // We're using the native OS APIs from here on out.
+#if WEBKIT_USING_SKIA
+ gfx::NativeDrawingContext context = canvas->beginPlatformPaint();
+#elif WEBKIT_USING_CG
+ gfx::NativeDrawingContext context = canvas;
+#endif
gfx::Rect offset_rect = rect;
offset_rect.Offset(-plugin_rect_.x(), -plugin_rect_.y());
@@ -565,6 +571,10 @@ void WebPluginDelegateProxy::Paint(gfx::NativeDrawingContext context,
invalidate_pending_ = false;
Send(new PluginMsg_DidPaint(instance_id_));
}
+
+#if WEBKIT_USING_SKIA
+ canvas->endPlatformPaint();
+#endif
}
bool WebPluginDelegateProxy::BackgroundChanged(
@@ -977,11 +987,19 @@ void WebPluginDelegateProxy::OnGetCPBrowsingContext(uint32* context) {
*context = render_view_ ? render_view_->GetCPBrowsingContext() : 0;
}
-void WebPluginDelegateProxy::PaintSadPlugin(gfx::NativeDrawingContext context,
+void WebPluginDelegateProxy::PaintSadPlugin(WebKit::WebCanvas* native_context,
const gfx::Rect& rect) {
+ // Lazily load the sad plugin image.
+ if (!sad_plugin_) {
+ sad_plugin_ = ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_SAD_PLUGIN);
+ }
+ if (!sad_plugin_)
+ return;
+
+ // Make a temporary canvas for the background image.
const int width = plugin_rect_.width();
const int height = plugin_rect_.height();
-
gfx::Canvas canvas(width, height, false);
#if defined(OS_MACOSX)
// Flip the canvas, since the context expects flipped data.
@@ -994,18 +1012,20 @@ void WebPluginDelegateProxy::PaintSadPlugin(gfx::NativeDrawingContext context,
paint.setColor(SK_ColorBLACK);
canvas.drawRectCoords(0, 0, SkIntToScalar(width), SkIntToScalar(height),
paint);
-
- if (!sad_plugin_) {
- sad_plugin_ = ResourceBundle::GetSharedInstance().GetBitmapNamed(
- IDR_SAD_PLUGIN);
- }
-
- if (sad_plugin_) {
- canvas.DrawBitmapInt(*sad_plugin_,
- std::max(0, (width - sad_plugin_->width())/2),
- std::max(0, (height - sad_plugin_->height())/2));
- }
+ canvas.DrawBitmapInt(*sad_plugin_,
+ std::max(0, (width - sad_plugin_->width())/2),
+ std::max(0, (height - sad_plugin_->height())/2));
+
+ // It's slightly less code to make a big SkBitmap of the sad tab image and
+ // then copy that to the screen than to use the native APIs. The small speed
+ // penalty is not important when drawing crashed plugins.
+#if WEBKIT_USING_SKIA
+ gfx::NativeDrawingContext context = native_context->beginPlatformPaint();
BlitCanvasToContext(context, plugin_rect_, &canvas, gfx::Point(0, 0));
+ native_context->endPlatformPaint();
+#elif WEBKIT_USING_CG
+ BlitCanvasToContext(native_context, plugin_rect_, &canvas, gfx::Point(0, 0));
+#endif
}
void WebPluginDelegateProxy::CopyFromTransportToBacking(const gfx::Rect& rect) {
diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h
index 5b2e6d9..5aa7a4a 100644
--- a/chrome/renderer/webplugin_delegate_proxy.h
+++ b/chrome/renderer/webplugin_delegate_proxy.h
@@ -54,7 +54,7 @@ class WebPluginDelegateProxy :
bool load_manually);
virtual void UpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect);
- virtual void Paint(gfx::NativeDrawingContext context, const gfx::Rect& rect);
+ virtual void Paint(WebKit::WebCanvas* canvas, const gfx::Rect& rect);
virtual void Print(gfx::NativeDrawingContext context);
virtual NPObject* GetPluginScriptableObject();
virtual void DidFinishLoadWithReason(const GURL& url, NPReason reason,
@@ -134,7 +134,7 @@ class WebPluginDelegateProxy :
void OnDeferResourceLoading(int resource_id, bool defer);
// Draw a graphic indicating a crashed plugin.
- void PaintSadPlugin(gfx::NativeDrawingContext context, const gfx::Rect& rect);
+ void PaintSadPlugin(WebKit::WebCanvas* canvas, const gfx::Rect& rect);
// Returns true if the given rectangle is different in the native drawing
// context and the current background bitmap.
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index 8e6a828..65e01b6 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -67,7 +67,7 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
virtual void PluginDestroyed();
virtual void UpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect);
- virtual void Paint(gfx::NativeDrawingContext context, const gfx::Rect& rect);
+ virtual void Paint(WebKit::WebCanvas* canvas, const gfx::Rect& rect);
virtual void Print(gfx::NativeDrawingContext context);
virtual void SetFocus();
virtual bool HandleInputEvent(const WebKit::WebInputEvent& event,
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
index 78ce170..3ee26cd 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
@@ -17,6 +17,7 @@
#include "base/process_util.h"
#include "base/stats_counters.h"
#include "base/string_util.h"
+#include "skia/ext/platform_canvas.h"
#include "webkit/api/public/WebCursorInfo.h"
#include "webkit/api/public/WebInputEvent.h"
#include "webkit/glue/glue_util.h"
@@ -98,10 +99,13 @@ void WebPluginDelegateImpl::PluginDestroyed() {
delete this;
}
-void WebPluginDelegateImpl::Paint(cairo_t* context,
+void WebPluginDelegateImpl::Paint(WebKit::WebCanvas* canvas,
const gfx::Rect& rect) {
- if (windowless_)
- WindowlessPaint(context, rect);
+ if (!windowless_)
+ return;
+ cairo_t* context = canvas->beginPlatformPaint();
+ WindowlessPaint(context, rect);
+ canvas->endPlatformPaint();
}
void WebPluginDelegateImpl::Print(cairo_t* context) {
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_win.cc b/webkit/glue/plugins/webplugin_delegate_impl_win.cc
index 06f105c..330cb39 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_win.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl_win.cc
@@ -16,6 +16,7 @@
#include "base/stats_counters.h"
#include "base/string_util.h"
#include "base/win_util.h"
+#include "skia/ext/platform_canvas.h"
#include "webkit/api/public/WebInputEvent.h"
#include "webkit/default_plugin/plugin_impl.h"
#include "webkit/glue/glue_util.h"
@@ -397,9 +398,13 @@ void WebPluginDelegateImpl::PlatformDestroyInstance() {
g_iat_patch_reg_enum_key_ex_w.Pointer()->Unpatch();
}
-void WebPluginDelegateImpl::Paint(HDC hdc, const gfx::Rect& rect) {
- if (windowless_)
+void WebPluginDelegateImpl::Paint(skia::PlatformCanvas* canvas,
+ const gfx::Rect& rect) {
+ if (windowless_) {
+ HDC hdc = canvas->beginPlatformPaint();
WindowlessPaint(hdc, rect);
+ canvas->endPlatformPaint();
+ }
}
void WebPluginDelegateImpl::Print(HDC hdc) {
diff --git a/webkit/glue/webplugin_delegate.h b/webkit/glue/webplugin_delegate.h
index 8b47b78..016f699 100644
--- a/webkit/glue/webplugin_delegate.h
+++ b/webkit/glue/webplugin_delegate.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
@@ -6,10 +6,13 @@
#define WEBKIT_GLUE_WEBPLUGIN_DELEGATE_H_
#include <string>
+#include <vector>
#include "app/gfx/native_widget_types.h"
#include "base/string16.h"
+#include "build/build_config.h"
#include "third_party/npapi/bindings/npapi.h"
+#include "webkit/api/public/WebCanvas.h"
class FilePath;
class GURL;
@@ -62,10 +65,9 @@ class WebPluginDelegate {
virtual void UpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect) = 0;
- // Tells the plugin to paint the damaged rect. |context| is only used for
+ // Tells the plugin to paint the damaged rect. |canvas| is only used for
// windowless plugins.
- virtual void Paint(gfx::NativeDrawingContext context,
- const gfx::Rect& rect) = 0;
+ virtual void Paint(WebKit::WebCanvas* canvas, const gfx::Rect& rect) = 0;
// Tells the plugin to print itself.
virtual void Print(gfx::NativeDrawingContext hdc) = 0;
diff --git a/webkit/glue/webplugin_impl.cc b/webkit/glue/webplugin_impl.cc
index 6c67b92..2e02340 100644
--- a/webkit/glue/webplugin_impl.cc
+++ b/webkit/glue/webplugin_impl.cc
@@ -238,18 +238,9 @@ NPObject* WebPluginImpl::scriptableObject() {
void WebPluginImpl::paint(WebCanvas* canvas, const WebRect& paint_rect) {
if (!delegate_)
return;
- // Note that |context| is only used when in windowless mode.
-#if WEBKIT_USING_SKIA
- gfx::NativeDrawingContext context = canvas->beginPlatformPaint();
-#elif WEBKIT_USING_CG
- gfx::NativeDrawingContext context = canvas;
-#endif
-
- delegate_->Paint(context, paint_rect);
-
-#if WEBKIT_USING_SKIA
- canvas->endPlatformPaint();
-#endif
+
+ // Note that |canvas| is only used when in windowless mode.
+ delegate_->Paint(canvas, paint_rect);
}
void WebPluginImpl::updateGeometry(