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

Unified Diff: chrome/renderer/webplugin_delegate_proxy.cc

Issue 113637: Wire up windowless plugins. Mostly Mac related, some cross (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 months 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 | « chrome/renderer/webplugin_delegate_proxy.h ('k') | webkit/glue/plugins/plugin_host.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/renderer/webplugin_delegate_proxy.cc
===================================================================
--- chrome/renderer/webplugin_delegate_proxy.cc (revision 20445)
+++ chrome/renderer/webplugin_delegate_proxy.cc (working copy)
@@ -13,6 +13,7 @@
#include "app/gfx/canvas.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
+#include "base/file_util.h"
#include "base/logging.h"
#include "base/ref_counted.h"
#include "base/string_util.h"
@@ -43,6 +44,10 @@
#include "chrome/common/ipc_channel_posix.h"
#endif
+#if defined(OS_MACOSX)
+#include "base/scoped_cftyperef.h"
+#endif
+
using WebKit::WebCursorInfo;
using WebKit::WebInputEvent;
using WebKit::WebDragData;
@@ -389,17 +394,13 @@
const gfx::Rect& clip_rect) {
plugin_rect_ = window_rect;
- // Be careful to explicitly call the default constructors for these ids,
- // as they can be POD on some platforms and we want them initialized.
- TransportDIB::Id transport_store_id = TransportDIB::Id();
- TransportDIB::Id background_store_id = TransportDIB::Id();
+ bool bitmaps_changed = false;
if (windowless_) {
-#if defined(OS_WIN)
- // TODO(port): use TransportDIB instead of allocating these directly.
if (!backing_store_canvas_.get() ||
(window_rect.width() != backing_store_canvas_->getDevice()->width() ||
window_rect.height() != backing_store_canvas_->getDevice()->height())) {
+ bitmaps_changed = true;
// Create a shared memory section that the plugin paints into
// asynchronously.
ResetWindowlessBitmaps();
@@ -412,36 +413,52 @@
ResetWindowlessBitmaps();
return;
}
-
- // TODO(port): once we use TransportDIB we will properly fill in these
- // ids; for now we just fill in the HANDLE field.
- transport_store_id.handle = transport_store_->handle();
- if (background_store_.get())
- background_store_id.handle = background_store_->handle();
}
}
-#else
- // TODO(port): refactor our allocation of backing stores.
- NOTIMPLEMENTED();
+ }
+
+ IPC::Message* msg = NULL;
+#if defined(OS_POSIX)
+ // If we're using POSIX mmap'd TransportDIBs, sending the handle across
+ // IPC establishes a new mapping rather than just sending a window ID,
+ // so only do so if we've actually recreated the shared memory bitmaps.
+ if (!bitmaps_changed) {
+ msg = new PluginMsg_UpdateGeometry(instance_id_, window_rect, clip_rect,
+ TransportDIB::Handle(), TransportDIB::Handle());
+ } else
#endif
+ if (transport_store_.get() && background_store_.get()) {
+ msg = new PluginMsg_UpdateGeometry(instance_id_, window_rect, clip_rect,
+ transport_store_->handle(), background_store_->handle());
+ } else if (transport_store_.get()) {
+ msg = new PluginMsg_UpdateGeometry(instance_id_, window_rect, clip_rect,
+ transport_store_->handle(), TransportDIB::Handle());
+ } else {
+ msg = new PluginMsg_UpdateGeometry(instance_id_, window_rect, clip_rect,
+ TransportDIB::Handle(), TransportDIB::Handle());
}
- IPC::Message* msg = new PluginMsg_UpdateGeometry(
- instance_id_, window_rect, clip_rect,
- transport_store_id, background_store_id);
msg->set_unblock(true);
Send(msg);
}
-#if defined(OS_WIN)
-// Copied from render_widget.cc
-static size_t GetPaintBufSize(const gfx::Rect& rect) {
- // TODO(darin): protect against overflow
- return 4 * rect.width() * rect.height();
+#if defined(OS_MACOSX)
+static void ReleaseTransportDIB(TransportDIB *dib) {
+ if (dib) {
+ IPC::Message* msg = new ViewHostMsg_FreeTransportDIB(dib->id());
+ RenderThread::current()->Send(msg);
+ }
}
#endif
void WebPluginDelegateProxy::ResetWindowlessBitmaps() {
+#if defined(OS_MACOSX)
+ // tell the browser to relase these TransportDIBs
+ ReleaseTransportDIB(backing_store_.get());
+ ReleaseTransportDIB(transport_store_.get());
+ ReleaseTransportDIB(background_store_.get());
+#endif
+
backing_store_.reset();
transport_store_.reset();
backing_store_canvas_.reset();
@@ -452,28 +469,36 @@
}
bool WebPluginDelegateProxy::CreateBitmap(
- scoped_ptr<base::SharedMemory>* memory,
+ scoped_ptr<TransportDIB>* memory,
scoped_ptr<skia::PlatformCanvas>* canvas) {
-#if defined(OS_WIN)
- size_t size = GetPaintBufSize(plugin_rect_);
- scoped_ptr<base::SharedMemory> new_shared_memory(new base::SharedMemory());
- if (!new_shared_memory->Create(L"", false, true, size))
+ int width = plugin_rect_.width();
+ int height = plugin_rect_.height();
+ const size_t stride = skia::PlatformCanvas::StrideForWidth(width);
+ const size_t size = stride * height;
+#if defined(OS_LINUX)
+ static unsigned long max_size = 0;
+ if (max_size == 0) {
+ std::string contents;
+ file_util::ReadFileToString(FilePath("/proc/sys/kernel/shmmax"), &contents);
+ max_size = strtoul(contents.c_str(), NULL, 0);
+ }
+ if (size > max_size)
return false;
-
- scoped_ptr<skia::PlatformCanvas> new_canvas(new skia::PlatformCanvas);
- if (!new_canvas->initialize(plugin_rect_.width(), plugin_rect_.height(),
- true, new_shared_memory->handle())) {
+#endif
+#if defined(OS_MACOSX)
+ TransportDIB::Handle handle;
+ IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(size, &handle);
+ if (!RenderThread::current()->Send(msg))
return false;
- }
-
- memory->swap(new_shared_memory);
- canvas->swap(new_canvas);
- return true;
+ if (handle.fd < 0)
+ return false;
+ memory->reset(TransportDIB::Map(handle));
#else
- // TODO(port): use TransportDIB properly.
- NOTIMPLEMENTED();
- return false;
+ static uint32 sequence_number = 0;
+ memory->reset(TransportDIB::Create(size, sequence_number++));
#endif
+ canvas->reset((*memory)->GetPlatformCanvas(width, height));
+ return true;
}
void WebPluginDelegateProxy::Paint(gfx::NativeDrawingContext context,
@@ -489,36 +514,59 @@
if (!windowless_)
return;
- // TODO(port): side-stepping some windowless plugin code for now.
-#if defined(OS_WIN)
// 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;
+ }
// Limit the damaged rectangle to whatever is contained inside the plugin
// rectangle, as that's the rectangle that we'll bitblt to the hdc.
gfx::Rect rect = damaged_rect.Intersect(plugin_rect_);
+ gfx::Rect offset_rect = rect;
+ offset_rect.Offset(-plugin_rect_.x(), -plugin_rect_.y());
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, rect.x()-plugin_rect_.x(), rect.y()-plugin_rect_.y(),
+ 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
+ NOTIMPLEMENTED();
+#endif
}
- gfx::Rect offset_rect = rect;
- offset_rect.Offset(-plugin_rect_.x(), -plugin_rect_.y());
if (background_changed || !backing_store_painted_.Contains(offset_rect)) {
Send(new PluginMsg_Paint(instance_id_, offset_rect));
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,
- rect.x()-plugin_rect_.x(), rect.y()-plugin_rect_.y(), SRCCOPY);
+ 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
+ NOTIMPLEMENTED();
+#endif
if (invalidate_pending_) {
// Only send the PaintAck message if this paint is in response to an
@@ -527,18 +575,12 @@
invalidate_pending_ = false;
Send(new PluginMsg_DidPaint(instance_id_));
}
-#else
- // TODO(port): windowless plugin paint handling goes here.
- NOTIMPLEMENTED();
-#endif
}
-#if defined(OS_WIN)
-// TODO(port): this should be portable; just avoiding windowless plugins for
-// now.
bool WebPluginDelegateProxy::BackgroundChanged(
- HDC hdc,
+ gfx::NativeDrawingContext hdc,
const gfx::Rect& rect) {
+#if defined(OS_WIN)
HBITMAP hbitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
if (hbitmap == NULL) {
NOTREACHED();
@@ -578,9 +620,11 @@
return true;
}
+#else
+ NOTIMPLEMENTED();
+#endif
return false;
}
-#endif
void WebPluginDelegateProxy::Print(gfx::NativeDrawingContext context) {
base::SharedMemoryHandle shared_memory;
@@ -860,7 +904,7 @@
*context = render_view_ ? render_view_->GetCPBrowsingContext() : 0;
}
-void WebPluginDelegateProxy::PaintSadPlugin(gfx::NativeDrawingContext hdc,
+void WebPluginDelegateProxy::PaintSadPlugin(gfx::NativeDrawingContext context,
const gfx::Rect& rect) {
const int width = plugin_rect_.width();
const int height = plugin_rect_.height();
@@ -886,7 +930,7 @@
#if defined(OS_WIN)
skia::PlatformDevice& device = canvas.getTopPlatformDevice();
- device.drawToHDC(hdc, plugin_rect_.x(), plugin_rect_.y(), NULL);
+ device.drawToHDC(context, plugin_rect_.x(), plugin_rect_.y(), NULL);
#elif defined(OS_LINUX)
// Though conceptually we've been handed a cairo_surface_t* and we
// could've just hooked up the canvas to draw directly onto it, our
@@ -895,33 +939,46 @@
// TODO(evanm): revisit when we have printing hooked up, as that might
// change our usage of cairo.
skia::PlatformDevice& device = canvas.getTopPlatformDevice();
- cairo_t* cairo = cairo_create(hdc);
+ cairo_t* cairo = cairo_create(context);
cairo_surface_t* source_surface = device.beginPlatformPaint();
cairo_set_source_surface(cairo, source_surface, plugin_rect_.x(), plugin_rect_.y());
cairo_paint(cairo);
cairo_destroy(cairo);
// We have no endPlatformPaint() on the Linux PlatformDevice.
// The surface is owned by the device.
+#elif defined(OS_MACOSX)
+ canvas.getTopPlatformDevice().DrawToContext(
+ context, plugin_rect_.x(), plugin_rect_.y(), NULL);
#else
NOTIMPLEMENTED();
#endif
}
void WebPluginDelegateProxy::CopyFromTransportToBacking(const gfx::Rect& rect) {
- if (!backing_store_canvas_.get())
+ if (!backing_store_canvas_.get()) {
return;
+ }
+ // Copy the damaged rect from the transport bitmap to the backing store.
#if defined(OS_WIN)
- // Copy the damaged rect from the transport bitmap to the backing store.
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);
- backing_store_painted_ = backing_store_painted_.Union(rect);
+#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
// TODO(port): probably some new code in TransportDIB should go here.
NOTIMPLEMENTED();
#endif
+ backing_store_painted_ = backing_store_painted_.Union(rect);
}
void WebPluginDelegateProxy::OnHandleURLRequest(
« no previous file with comments | « chrome/renderer/webplugin_delegate_proxy.h ('k') | webkit/glue/plugins/plugin_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698