diff options
author | stuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-14 17:24:51 +0000 |
---|---|---|
committer | stuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-14 17:24:51 +0000 |
commit | ab7f2746760f15e5fab7dae6e107da26002b7d82 (patch) | |
tree | 1fce04333f2dfab22d587e471bbf84c62e6c8251 /chrome/renderer | |
parent | 64e10897fd89b86a2085ad0d47f374419ff4a9db (diff) | |
download | chromium_src-ab7f2746760f15e5fab7dae6e107da26002b7d82.zip chromium_src-ab7f2746760f15e5fab7dae6e107da26002b7d82.tar.gz chromium_src-ab7f2746760f15e5fab7dae6e107da26002b7d82.tar.bz2 |
Improve plugin performance on the Mac
This makes a few changes:
- Switch to memcpy instead of CG drawing to copy pixels from the transport bitmap to the backing bitmap (this is a substantial perf win).
- Send transparancy information to the WebPluginDelegate, since it's no longer equivalent to not having a background DIB on the Mac (and likely on the other platforms in the future).
- Don't clear the transport DIB for non-transparent plugins, since they will be drawing over whatever is there anyway.
BUG=41340
TEST=Both transparent and non-transparent plugins should continue to draw correctly. Framerates for large CG plugins (e.g., in-window Netflix streaming) should be higher.
Review URL: http://codereview.chromium.org/1629017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44490 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/webplugin_delegate_proxy.cc | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc index e11c848..5049bf4 100644 --- a/chrome/renderer/webplugin_delegate_proxy.cc +++ b/chrome/renderer/webplugin_delegate_proxy.cc @@ -533,6 +533,7 @@ void WebPluginDelegateProxy::UpdateGeometry(const gfx::Rect& window_rect, param.clip_rect = clip_rect; param.windowless_buffer = TransportDIB::DefaultHandleValue(); param.background_buffer = TransportDIB::DefaultHandleValue(); + param.transparent = transparent_; #if defined(OS_POSIX) // If we're using POSIX mmap'd TransportDIBs, sending the handle across @@ -1241,15 +1242,28 @@ void WebPluginDelegateProxy::CopyFromTransportToBacking(const gfx::Rect& rect) { } // Copy the damaged rect from the transport bitmap to the backing store. - gfx::Rect dest_rect = rect; #if defined(OS_MACOSX) - FlipRectVerticallyWithHeight(&dest_rect, plugin_rect_.height()); - gfx::NativeDrawingContext backing_context = - backing_store_canvas_.get()->getTopPlatformDevice().GetBitmapContext(); - CGContextClearRect(backing_context, dest_rect.ToCGRect()); -#endif - BlitCanvasToCanvas(backing_store_canvas_.get(), dest_rect, + // Blitting the bits directly is much faster than going through CG, and since + // since the goal is just to move the raw pixels between two bitmaps with the + // same pixel format (no compositing, color correction, etc.), it's safe. + const size_t stride = + skia::PlatformCanvas::StrideForWidth(plugin_rect_.width()); + const size_t chunk_size = 4 * rect.width(); + char* source_data = static_cast<char*>(transport_store_->memory()) + + rect.y() * stride + 4 * rect.x(); + // The two bitmaps are flipped relative to each other. + int dest_starting_row = plugin_rect_.height() - rect.y() - 1; + char* target_data = static_cast<char*>(backing_store_->memory()) + + dest_starting_row * stride + 4 * rect.x(); + for (int row = 0; row < rect.height(); ++row) { + memcpy(target_data, source_data, chunk_size); + source_data += stride; + target_data -= stride; + } +#else + BlitCanvasToCanvas(backing_store_canvas_.get(), rect, transport_store_canvas_.get(), rect.origin()); +#endif backing_store_painted_ = backing_store_painted_.Union(rect); } |