Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2512)

Unified Diff: content/renderer/webplugin_delegate_proxy.cc

Issue 11361170: Get windowless plugins working when accelerated compositing is turned on. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/renderer/webplugin_delegate_proxy.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/webplugin_delegate_proxy.cc
===================================================================
--- content/renderer/webplugin_delegate_proxy.cc (revision 166499)
+++ content/renderer/webplugin_delegate_proxy.cc (working copy)
@@ -48,6 +48,7 @@
#include "ui/gfx/canvas.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
+#include "ui/gfx/skia_util.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/plugins/npapi/webplugin.h"
#include "webkit/plugins/plugin_constants.h"
@@ -402,6 +403,7 @@
(silverlight && LowerCaseEqualsASCII(arg_names[i], "background") &&
SilverlightColorIsTransparent(arg_values[i]))) {
transparent_ = true;
+ RenderThread::Get()->RecordUserMetrics("Plugin_Transparent");
}
}
params.load_manually = load_manually;
@@ -409,8 +411,7 @@
plugin_ = plugin;
result = false;
- IPC::Message* msg = new PluginMsg_Init(instance_id_, params, &result);
- Send(msg);
+ Send(new PluginMsg_Init(instance_id_, params, &result));
if (!result)
LOG(ERROR) << "PluginMsg_Init returned false";
@@ -668,6 +669,12 @@
ResetWindowlessBitmaps();
return;
}
+
+ if (needs_background_store &&
+ render_view_->is_accelerated_compositing_active()) {
+ // Better than grabage...
+ background_store_.canvas->drawColor(SK_ColorWHITE);
piman 2012/11/09 19:27:03 How about writing transparent pixels? If the plugi
jam 2012/11/09 22:50:24 Thanks, actually trying this out shows that NPAPI
+ }
}
}
}
@@ -762,40 +769,28 @@
if (!front_buffer_canvas())
return;
- // We're using the native OS APIs from here on out.
- if (!skia::SupportsPlatformPaint(canvas)) {
- // TODO(alokp): Implement this path.
- // This block will only get hit with --enable-accelerated-drawing flag.
- // With accelerated canvas, we do not have a bitmap that can be provided
- // to the plugin for compositing. We may have to implement a solution
- // described in crbug.com/12586.
- DLOG(WARNING) << "Could not paint plugin";
- return;
- }
- skia::ScopedPlatformPaint scoped_platform_paint(canvas);
- gfx::NativeDrawingContext context =
- scoped_platform_paint.GetPlatformSurface();
-
gfx::Rect offset_rect = rect;
offset_rect.Offset(-plugin_rect_.x(), -plugin_rect_.y());
- gfx::Rect canvas_rect = offset_rect;
-#if defined(OS_MACOSX)
- // The canvases are flipped relative to the context, so flip the rect too.
- FlipRectVerticallyWithHeight(&canvas_rect, plugin_rect_.height());
-#endif
bool background_changed = false;
- if (background_store_.canvas.get() && BackgroundChanged(context, rect)) {
+ if (background_store_.canvas.get() && BackgroundChanged(canvas, rect) &&
+ // When accelerated compositing is used we don't have access to the
+ // page data under the plugin. This might result in painting glitches,
+ // but there's nothing we can do about that. This is mostly mitigiated
piman 2012/11/09 19:27:03 typo: mitigated
+ // by the fact that this is only for NPAPI plugins, and for Flash we use
+ // Pepper.
+ !render_view_->is_accelerated_compositing_active()) {
background_changed = true;
- BlitContextToCanvas(background_store_.canvas.get(), canvas_rect,
- context, rect.origin());
+ SkIRect src_rect = gfx::RectToSkIRect(rect);
+ background_store_.canvas->drawBitmapRect(
+ canvas->getDevice()->accessBitmap(false),
+ &src_rect, gfx::RectToSkRect(offset_rect));
jam 2012/11/09 19:02:25 btw I found that somehow this isn't working on Lin
piman 2012/11/09 19:27:03 I'm not sure specifically, but I was going to ment
}
// transport_store_painted_ is really a bounding box, so in principle this
// check could falsely indicate that we don't need to paint offset_rect, but
// in practice it works fine.
- if (background_changed ||
- !transport_store_painted_.Contains(offset_rect)) {
+ if (background_changed || !transport_store_painted_.Contains(offset_rect)) {
Send(new PluginMsg_Paint(instance_id_, offset_rect));
// Since the plugin is not blocked on the renderer in this context, there is
// a chance that it will begin repainting the back-buffer before we complete
@@ -805,20 +800,15 @@
UpdateFrontBuffer(offset_rect, false);
}
-#if defined(OS_MACOSX)
- // The canvases are flipped relative to the context, so flip the context's
- // coordinate space so that the blit unflips the content.
- CGContextSaveGState(context);
- CGContextScaleCTM(context, 1, -1);
- rect.set_y(-rect.bottom());
-#endif
- BlitCanvasToContext(context,
- rect,
- front_buffer_canvas(),
- offset_rect.origin());
-#if defined(OS_MACOSX)
- CGContextRestoreGState(context);
-#endif
+ const SkBitmap& bitmap =
+ front_buffer_canvas()->getDevice()->accessBitmap(false);
+ SkPaint paint;
+ paint.setXfermodeMode(SkXfermode::kSrcATop_Mode);
+ SkIRect src_rect = gfx::RectToSkIRect(offset_rect);
+ canvas->drawBitmapRect(bitmap,
+ &src_rect,
+ gfx::RectToSkRect(rect),
+ &paint);
if (invalidate_pending_) {
// Only send the PaintAck message if this paint is in response to an
@@ -829,154 +819,26 @@
}
}
-bool WebPluginDelegateProxy::BackgroundChanged(
- gfx::NativeDrawingContext context,
- const gfx::Rect& rect) {
-#if defined(OS_ANDROID)
- NOTIMPLEMENTED();
-#else
-#if defined(OS_WIN)
piman 2012/11/09 19:27:03 Awesome thanks for removing this horrible per-plat
- HBITMAP hbitmap = static_cast<HBITMAP>(GetCurrentObject(context, OBJ_BITMAP));
- if (hbitmap == NULL) {
- NOTREACHED();
- return true;
- }
+bool WebPluginDelegateProxy::BackgroundChanged(SkCanvas* canvas,
+ const gfx::Rect& rect) {
+ const SkMatrix& matrix = canvas->getTotalMatrix();
+ const SkBitmap& page = canvas->getDevice()->accessBitmap(false);
+ const SkBitmap& background =
+ background_store_.canvas->getDevice()->accessBitmap(false);
+ CHECK(page.bytesPerPixel() == background.bytesPerPixel());
+ int row_byte_size = rect.width() * page.bytesPerPixel();
piman 2012/11/09 19:27:03 This can get tricky with CSS transforms, in partic
+ for (int y = rect.y(); y < rect.bottom(); y++) {
+ SkPoint result;
+ matrix.mapXY(SkIntToScalar(rect.x()), SkIntToScalar(y), &result);
+ uint32_t* page_row_start = page.getAddr32(result.x(), result.y());
- BITMAP bitmap = { 0 };
- int result = GetObject(hbitmap, sizeof(bitmap), &bitmap);
- if (!result) {
- NOTREACHED();
- return true;
- }
-
- XFORM xf;
- if (!GetWorldTransform(context, &xf)) {
- NOTREACHED();
- return true;
- }
-
- // The damaged rect that we're given can be larger than the bitmap, so
- // intersect their rects first.
- gfx::Rect bitmap_rect(static_cast<int>(-xf.eDx), static_cast<int>(-xf.eDy),
- bitmap.bmWidth, bitmap.bmHeight);
- gfx::Rect check_rect = gfx::IntersectRects(rect, bitmap_rect);
- int row_byte_size = check_rect.width() * (bitmap.bmBitsPixel / 8);
- for (int y = check_rect.y(); y < check_rect.bottom(); y++) {
- char* hdc_row_start = static_cast<char*>(bitmap.bmBits) +
- (y + static_cast<int>(xf.eDy)) * bitmap.bmWidthBytes +
- (check_rect.x() + static_cast<int>(xf.eDx)) * (bitmap.bmBitsPixel / 8);
-
// getAddr32 doesn't use the translation units, so we have to subtract
// the plugin origin from the coordinates.
- uint32_t* canvas_row_start =
- background_store_.canvas->getDevice()->accessBitmap(true).getAddr32(
- check_rect.x() - plugin_rect_.x(), y - plugin_rect_.y());
- if (memcmp(hdc_row_start, canvas_row_start, row_byte_size) != 0)
+ uint32_t* background_row_start = background.getAddr32(
+ rect.x() - plugin_rect_.x(), y - plugin_rect_.y());
+ if (memcmp(page_row_start, background_row_start, row_byte_size) != 0)
return true;
}
-#else
-#if defined(OS_MACOSX)
- // If there is a translation on the content area context, we need to account
- // for it; the context may be a subset of the full content area with a
- // transform that makes the coordinates work out.
- CGAffineTransform transform = CGContextGetCTM(context);
- bool flipped = fabs(transform.d + 1) < 0.0001;
- CGFloat context_offset_x = -transform.tx;
- CGFloat context_offset_y = flipped ? transform.ty -
- CGBitmapContextGetHeight(context)
- : -transform.ty;
- gfx::Rect full_content_rect(context_offset_x, context_offset_y,
- CGBitmapContextGetWidth(context),
- CGBitmapContextGetHeight(context));
-#else
- cairo_surface_t* page_surface = cairo_get_target(context);
- DCHECK_EQ(cairo_surface_get_type(page_surface), CAIRO_SURFACE_TYPE_IMAGE);
- DCHECK_EQ(cairo_image_surface_get_format(page_surface), CAIRO_FORMAT_ARGB32);
-
- // Transform context coordinates into surface coordinates.
- double page_x_double = 0;
- double page_y_double = 0;
- cairo_device_to_user(context, &page_x_double, &page_y_double);
- gfx::Rect full_content_rect(static_cast<int>(page_x_double),
- static_cast<int>(page_y_double),
- cairo_image_surface_get_width(page_surface),
- cairo_image_surface_get_height(page_surface));
-#endif
- // According to comments in the Windows code, the damage rect that we're given
- // may project outside the image, so intersect their rects.
- gfx::Rect content_rect = gfx::IntersectRects(rect, full_content_rect);
-
-#if defined(OS_MACOSX)
- const unsigned char* page_bytes = static_cast<const unsigned char*>(
- CGBitmapContextGetData(context));
- int page_stride = CGBitmapContextGetBytesPerRow(context);
- int page_start_x = content_rect.x() - context_offset_x;
- int page_start_y = content_rect.y() - context_offset_y;
-
- skia::ScopedPlatformPaint scoped_platform_paint(
- background_store_.canvas.get());
- CGContextRef bg_context = scoped_platform_paint.GetPlatformSurface();
-
- DCHECK_EQ(CGBitmapContextGetBitsPerPixel(context),
- CGBitmapContextGetBitsPerPixel(bg_context));
- const unsigned char* bg_bytes = static_cast<const unsigned char*>(
- CGBitmapContextGetData(bg_context));
- int full_bg_width = CGBitmapContextGetWidth(bg_context);
- int full_bg_height = CGBitmapContextGetHeight(bg_context);
- int bg_stride = CGBitmapContextGetBytesPerRow(bg_context);
- int bg_last_row = CGBitmapContextGetHeight(bg_context) - 1;
-
- int bytes_per_pixel = CGBitmapContextGetBitsPerPixel(context) / 8;
-#else
- cairo_surface_flush(page_surface);
- const unsigned char* page_bytes = cairo_image_surface_get_data(page_surface);
- int page_stride = cairo_image_surface_get_stride(page_surface);
- int page_start_x = content_rect.x() - static_cast<int>(page_x_double);
- int page_start_y = content_rect.y() - static_cast<int>(page_y_double);
-
- skia::ScopedPlatformPaint scoped_platform_paint(
- background_store_.canvas.get());
- cairo_surface_t* bg_surface =cairo_get_target(
- scoped_platform_paint.GetPlatformSurface());
- DCHECK_EQ(cairo_surface_get_type(bg_surface), CAIRO_SURFACE_TYPE_IMAGE);
- DCHECK_EQ(cairo_image_surface_get_format(bg_surface), CAIRO_FORMAT_ARGB32);
- cairo_surface_flush(bg_surface);
- const unsigned char* bg_bytes = cairo_image_surface_get_data(bg_surface);
- int full_bg_width = cairo_image_surface_get_width(bg_surface);
- int full_bg_height = cairo_image_surface_get_height(bg_surface);
- int bg_stride = cairo_image_surface_get_stride(bg_surface);
-
- int bytes_per_pixel = 4; // ARGB32 = 4 bytes per pixel.
-#endif
-
- int damage_width = content_rect.width();
- int damage_height = content_rect.height();
-
- int bg_start_x = rect.x() - plugin_rect_.x();
- int bg_start_y = rect.y() - plugin_rect_.y();
- // The damage rect is supposed to have been intersected with the plugin rect;
- // double-check, since if it hasn't we'll walk off the end of the buffer.
- DCHECK_LE(bg_start_x + damage_width, full_bg_width);
- DCHECK_LE(bg_start_y + damage_height, full_bg_height);
-
- int bg_x_byte_offset = bg_start_x * bytes_per_pixel;
- int page_x_byte_offset = page_start_x * bytes_per_pixel;
- for (int row = 0; row < damage_height; ++row) {
- int page_offset = page_stride * (page_start_y + row) + page_x_byte_offset;
- int bg_y = bg_start_y + row;
-#if defined(OS_MACOSX)
- // The background buffer is upside down relative to the content.
- bg_y = bg_last_row - bg_y;
-#endif
- int bg_offset = bg_stride * bg_y + bg_x_byte_offset;
- if (memcmp(page_bytes + page_offset,
- bg_bytes + bg_offset,
- damage_width * bytes_per_pixel) != 0)
- return true;
- }
-#endif
-#endif // OS_ANDROID
-
return false;
}
« no previous file with comments | « content/renderer/webplugin_delegate_proxy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698