diff options
-rw-r--r-- | base/base.gyp | 2 | ||||
-rw-r--r-- | base/gfx/blit.cc | 87 | ||||
-rw-r--r-- | base/gfx/blit.h | 47 | ||||
-rw-r--r-- | chrome/plugin/webplugin_proxy.cc | 11 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_proxy.cc | 106 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_gtk.cc | 26 |
6 files changed, 160 insertions, 119 deletions
diff --git a/base/base.gyp b/base/base.gyp index e281a43..8aa8a3a 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -538,6 +538,8 @@ 'type': '<(library)', 'msvs_guid': 'A508ADD3-CECE-4E0F-8448-2F5E454DF551', 'sources': [ + 'gfx/blit.cc', + 'gfx/blit.h', 'gfx/gdi_util.cc', 'gfx/gdi_util.h', 'gfx/gtk_native_view_id_manager.cc', diff --git a/base/gfx/blit.cc b/base/gfx/blit.cc new file mode 100644 index 0000000..2965c4c --- /dev/null +++ b/base/gfx/blit.cc @@ -0,0 +1,87 @@ +// 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. + +#include "base/gfx/blit.h" + +#if defined(OS_LINUX) +#include <cairo/cairo.h> +#endif + +#include "base/gfx/point.h" +#include "base/gfx/rect.h" +#if defined(OS_MACOSX) +#include "base/scoped_cftyperef.h" +#endif +#include "skia/ext/platform_canvas.h" +#include "skia/ext/platform_device.h" + +namespace gfx { + +void BlitContextToContext(NativeDrawingContext dst_context, + const Rect& dst_rect, + NativeDrawingContext src_context, + const Point& src_origin) { +#if defined(OS_WIN) + BitBlt(dst_context, dst_rect.x(), dst_rect.y(), + dst_rect.width(), dst_rect.height(), + src_context, src_origin.x(), src_origin.y(), SRCCOPY); +#elif defined(OS_MACOSX) + Rect src_rect(src_origin, dst_rect.size()); + scoped_cftyperef<CGImageRef> + src_image(CGBitmapContextCreateImage(src_context)); + scoped_cftyperef<CGImageRef> src_sub_image( + CGImageCreateWithImageInRect(src_image, src_rect.ToCGRect())); + CGContextDrawImage(dst_context, dst_rect.ToCGRect(), src_sub_image); +#elif defined(OS_LINUX) + cairo_save(dst_context); + double surface_x = src_origin.x(); + double surface_y = src_origin.y(); + cairo_user_to_device(src_context, &surface_x, &surface_y); + cairo_set_source_surface(dst_context, cairo_get_target(src_context), + dst_rect.x()-surface_x, dst_rect.y()-surface_y); + cairo_rectangle(dst_context, dst_rect.x(), dst_rect.y(), + dst_rect.width(), dst_rect.height()); + cairo_clip(dst_context); + cairo_paint(dst_context); + cairo_restore(dst_context); +#endif +} + +static NativeDrawingContext GetContextFromCanvas( + skia::PlatformCanvas *canvas) { + skia::PlatformDevice& device = canvas->getTopPlatformDevice(); +#if defined(OS_WIN) + return device.getBitmapDC(); +#elif defined(OS_MACOSX) + return device.GetBitmapContext(); +#elif defined(OS_LINUX) + return device.beginPlatformPaint(); +#endif +} + +void BlitContextToCanvas(skia::PlatformCanvas *dst_canvas, + const Rect& dst_rect, + NativeDrawingContext src_context, + const Point& src_origin) { + BlitContextToContext(GetContextFromCanvas(dst_canvas), dst_rect, + src_context, src_origin); +} + +void BlitCanvasToContext(NativeDrawingContext dst_context, + const Rect& dst_rect, + skia::PlatformCanvas *src_canvas, + const Point& src_origin) { + BlitContextToContext(dst_context, dst_rect, + GetContextFromCanvas(src_canvas), src_origin); +} + +void BlitCanvasToCanvas(skia::PlatformCanvas *dst_canvas, + const Rect& dst_rect, + skia::PlatformCanvas *src_canvas, + const Point& src_origin) { + BlitContextToContext(GetContextFromCanvas(dst_canvas), dst_rect, + GetContextFromCanvas(src_canvas), src_origin); +} + +} // namespace gfx diff --git a/base/gfx/blit.h b/base/gfx/blit.h new file mode 100644 index 0000000..25f7a5e --- /dev/null +++ b/base/gfx/blit.h @@ -0,0 +1,47 @@ +// 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. + +#ifndef BASE_GFX_BLIT_H_ +#define BASE_GFX_BLIT_H_ + +#include "base/gfx/native_widget_types.h" +#include "base/gfx/point.h" +#include "base/gfx/rect.h" + +namespace skia { +class PlatformCanvas; +} // namespace skia + +namespace gfx { + +class Point; +class Rect; + +// Blits a rectangle from the source context into the destination context. +void BlitContextToContext(NativeDrawingContext dst_context, + const Rect& dst_rect, + NativeDrawingContext src_context, + const Point& src_origin); + +// Blits a rectangle from the source context into the destination canvas. +void BlitContextToCanvas(skia::PlatformCanvas *dst_canvas, + const Rect& dst_rect, + NativeDrawingContext src_context, + const Point& src_origin); + +// Blits a rectangle from the source canvas into the destination context. +void BlitCanvasToContext(NativeDrawingContext dst_context, + const Rect& dst_rect, + skia::PlatformCanvas *src_canvas, + const Point& src_origin); + +// Blits a rectangle from the source canvas into the destination canvas. +void BlitCanvasToCanvas(skia::PlatformCanvas *dst_canvas, + const Rect& dst_rect, + skia::PlatformCanvas *src_canvas, + const Point& src_origin); + +} // namespace gfx + +#endif // BASE_GFX_BLIT_H_ diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc index 3d34674..38cd306f 100644 --- a/chrome/plugin/webplugin_proxy.cc +++ b/chrome/plugin/webplugin_proxy.cc @@ -8,6 +8,7 @@ #if defined(OS_WIN) #include "app/win_util.h" #endif +#include "base/gfx/blit.h" #include "base/scoped_handle.h" #include "base/shared_memory.h" #include "base/singleton.h" @@ -426,17 +427,15 @@ void WebPluginProxy::Paint(const gfx::Rect& rect) { 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); - if (background_canvas_.get()) { - cairo_t *background = - background_canvas_->getTopPlatformDevice().beginPlatformPaint(); - cairo_set_source_surface(cairo, cairo_get_target(background), 0, 0); - cairo_paint(cairo); - } cairo_translate(cairo, -delegate_->GetRect().x(), -delegate_->GetRect().y()); delegate_->Paint(cairo, offset_rect); cairo_restore(cairo); diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc index 4b87f7e..016c851 100644 --- a/chrome/renderer/webplugin_delegate_proxy.cc +++ b/chrome/renderer/webplugin_delegate_proxy.cc @@ -17,6 +17,7 @@ #include "base/logging.h" #include "base/ref_counted.h" #include "base/string_util.h" +#include "base/gfx/blit.h" #include "base/gfx/size.h" #include "base/gfx/native_widget_types.h" #include "chrome/common/child_process_logging.h" @@ -523,34 +524,8 @@ void WebPluginDelegateProxy::Paint(gfx::NativeDrawingContext context, bool background_changed = false; if (background_store_canvas_.get() && BackgroundChanged(context, rect)) { background_changed = true; -#if defined(OS_WIN) - HDC background_hdc = - background_store_canvas_->getTopPlatformDevice().getBitmapDC(); - BitBlt(background_hdc, offset_rect.x(), offset_rect.y(), - rect.width(), rect.height(), context, rect.x(), rect.y(), SRCCOPY); -#elif defined(OS_MACOSX) - CGContextRef background_context = - background_store_canvas_->getTopPlatformDevice().GetBitmapContext(); - scoped_cftyperef<CGImageRef> - background_image(CGBitmapContextCreateImage(background_context)); - scoped_cftyperef<CGImageRef> sub_image( - CGImageCreateWithImageInRect(background_image, offset_rect.ToCGRect())); - CGContextDrawImage(context, rect.ToCGRect(), sub_image); -#else - cairo_t *cairo = - background_store_canvas_->getTopPlatformDevice().beginPlatformPaint(); - cairo_save(cairo); - double surface_x = plugin_rect_.x(); - double surface_y = plugin_rect_.y(); - cairo_user_to_device(context, &surface_x, &surface_y); - cairo_set_source_surface(cairo, cairo_get_target(context), - -surface_x, -surface_y); - cairo_rectangle(cairo, offset_rect.x(), offset_rect.y(), - offset_rect.width(), offset_rect.height()); - cairo_clip(cairo); - cairo_paint(cairo); - cairo_restore(cairo); -#endif + BlitContextToCanvas(background_store_canvas_.get(), offset_rect, + context, rect.origin()); } if (background_changed || !backing_store_painted_.Contains(offset_rect)) { @@ -558,29 +533,8 @@ void WebPluginDelegateProxy::Paint(gfx::NativeDrawingContext context, CopyFromTransportToBacking(offset_rect); } -#if defined(OS_WIN) - HDC backing_hdc = backing_store_canvas_->getTopPlatformDevice().getBitmapDC(); - BitBlt(context, rect.x(), rect.y(), rect.width(), rect.height(), backing_hdc, - offset_rect.x(), offset_rect.y(), SRCCOPY); -#elif defined(OS_MACOSX) - CGContextRef backing_context = - backing_store_canvas_->getTopPlatformDevice().GetBitmapContext(); - scoped_cftyperef<CGImageRef> - backing_image(CGBitmapContextCreateImage(backing_context)); - scoped_cftyperef<CGImageRef> sub_image( - CGImageCreateWithImageInRect(backing_image, offset_rect.ToCGRect())); - CGContextDrawImage(context, rect.ToCGRect(), sub_image); -#else - cairo_save(context); - cairo_t *cairo = - backing_store_canvas_->getTopPlatformDevice().beginPlatformPaint(); - cairo_set_source_surface(context, cairo_get_target(cairo), - plugin_rect_.x(), plugin_rect_.y()); - cairo_rectangle(context, rect.x(), rect.y(), rect.width(), rect.height()); - cairo_paint(context); - cairo_clip(context); - cairo_restore(context); -#endif + BlitCanvasToContext(context, rect, backing_store_canvas_.get(), + offset_rect.origin()); if (invalidate_pending_) { // Only send the PaintAck message if this paint is in response to an @@ -941,27 +895,7 @@ void WebPluginDelegateProxy::PaintSadPlugin(gfx::NativeDrawingContext context, std::max(0, (width - sad_plugin_->width())/2), std::max(0, (height - sad_plugin_->height())/2)); } - -#if defined(OS_WIN) - skia::PlatformDevice& device = canvas.getTopPlatformDevice(); - device.drawToHDC(context, plugin_rect_.x(), plugin_rect_.y(), NULL); -#elif defined(OS_LINUX) - cairo_save(context); - cairo_t* cairo = canvas.getTopPlatformDevice().beginPlatformPaint(); - cairo_set_source_surface(context, cairo_get_target(cairo), - plugin_rect_.x(), plugin_rect_.y()); - cairo_rectangle(context, rect.x(), rect.y(), rect.width(), rect.height()); - cairo_clip(context); - cairo_paint(context); - cairo_restore(context); - // We have no endPlatformPaint() on the Linux PlatformDevice. - // The cairo_t* is owned by the device. -#elif defined(OS_MACOSX) - canvas.getTopPlatformDevice().DrawToContext( - context, plugin_rect_.x(), plugin_rect_.y(), NULL); -#else - NOTIMPLEMENTED(); -#endif + BlitCanvasToContext(context, plugin_rect_, &canvas, gfx::Point(0, 0)); } void WebPluginDelegateProxy::CopyFromTransportToBacking(const gfx::Rect& rect) { @@ -970,32 +904,8 @@ void WebPluginDelegateProxy::CopyFromTransportToBacking(const gfx::Rect& rect) { } // Copy the damaged rect from the transport bitmap to the backing store. -#if defined(OS_WIN) - HDC backing = backing_store_canvas_->getTopPlatformDevice().getBitmapDC(); - HDC transport = transport_store_canvas_->getTopPlatformDevice().getBitmapDC(); - BitBlt(backing, rect.x(), rect.y(), rect.width(), rect.height(), - transport, rect.x(), rect.y(), SRCCOPY); -#elif defined(OS_MACOSX) - gfx::NativeDrawingContext backing = - backing_store_canvas_->getTopPlatformDevice().GetBitmapContext(); - gfx::NativeDrawingContext transport = - transport_store_canvas_->getTopPlatformDevice().GetBitmapContext(); - scoped_cftyperef<CGImageRef> image(CGBitmapContextCreateImage(transport)); - scoped_cftyperef<CGImageRef> sub_image( - CGImageCreateWithImageInRect(image, rect.ToCGRect())); - CGContextDrawImage(backing, rect.ToCGRect(), sub_image); -#else - cairo_t *cairo = - backing_store_canvas_->getTopPlatformDevice().beginPlatformPaint(); - cairo_save(cairo); - cairo_t *transport = - transport_store_canvas_->getTopPlatformDevice().beginPlatformPaint(); - cairo_set_source_surface(cairo, cairo_get_target(transport), 0, 0); - cairo_rectangle(cairo, rect.x(), rect.y(), rect.width(), rect.height()); - cairo_clip(cairo); - cairo_paint(cairo); - cairo_restore(cairo); -#endif + BlitCanvasToCanvas(backing_store_canvas_.get(), rect, + transport_store_canvas_.get(), rect.origin()); backing_store_painted_ = backing_store_painted_.Union(rect); } diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc index 265551a..d107a6d 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc @@ -12,6 +12,7 @@ #include "base/basictypes.h" #include "base/file_util.h" +#include "base/gfx/blit.h" #include "base/message_loop.h" #include "base/process_util.h" #include "base/stats_counters.h" @@ -516,24 +517,19 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_t* context, DCHECK_EQ(err, NPERR_NO_ERROR); } + gfx::Rect pixmap_draw_rect = draw_rect; + pixmap_draw_rect.Offset(offset_x, offset_y); + gfx::Rect pixmap_rect(0, 0, - draw_rect.x() + offset_x + draw_rect.width(), - draw_rect.y() + offset_y + draw_rect.height()); + pixmap_draw_rect.right(), + pixmap_draw_rect.bottom()); EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height()); // Copy the current image into the pixmap, so the plugin can draw over // this background. cairo_t* cairo = gdk_cairo_create(pixmap_); - double surface_x = -offset_x; - double surface_y = -offset_y; - cairo_user_to_device(context, &surface_x, &surface_y); - cairo_set_source_surface(cairo, cairo_get_target(context), - -surface_x, -surface_y); - cairo_rectangle(cairo, draw_rect.x() + offset_x, draw_rect.y() + offset_y, - draw_rect.width(), draw_rect.height()); - cairo_clip(cairo); - cairo_paint(cairo); + BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin()); cairo_destroy(cairo); // Construct the paint message, targeting the pixmap. @@ -542,10 +538,10 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_t* context, event.type = GraphicsExpose; event.display = GDK_DISPLAY(); event.drawable = GDK_PIXMAP_XID(pixmap_); - event.x = draw_rect.x() + offset_x; - event.y = draw_rect.y() + offset_y; - event.width = draw_rect.width(); - event.height = draw_rect.height(); + event.x = pixmap_draw_rect.x(); + event.y = pixmap_draw_rect.y(); + event.width = pixmap_draw_rect.width(); + event.height = pixmap_draw_rect.height(); // Tell the plugin to paint into the pixmap. static StatsRate plugin_paint("Plugin.Paint"); |