summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/scoped_handle.h8
-rw-r--r--chrome/common/plugin_messages_internal.h16
-rw-r--r--chrome/plugin/webplugin_delegate_stub.cc14
-rw-r--r--chrome/plugin/webplugin_delegate_stub.h7
-rw-r--r--chrome/plugin/webplugin_proxy.cc115
-rw-r--r--chrome/plugin/webplugin_proxy.h41
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc211
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.h36
-rw-r--r--webkit/glue/plugins/plugin_host.cc156
-rw-r--r--webkit/glue/plugins/plugin_host.h22
-rw-r--r--webkit/glue/plugins/plugin_instance.cc1
-rw-r--r--webkit/glue/plugins/plugin_instance.h9
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.cc5
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h1
-rw-r--r--webkit/glue/webplugin_delegate.h4
15 files changed, 343 insertions, 303 deletions
diff --git a/base/scoped_handle.h b/base/scoped_handle.h
index 5f12af1..654d6fd 100644
--- a/base/scoped_handle.h
+++ b/base/scoped_handle.h
@@ -112,6 +112,10 @@ class ScopedHDC {
Close();
}
+ HDC Get() {
+ return hdc_;
+ }
+
void Set(HDC h) {
Close();
hdc_ = h;
@@ -139,6 +143,10 @@ class ScopedBitmap {
Close();
}
+ HBITMAP Get() {
+ return hbitmap_;
+ }
+
void Set(HBITMAP h) {
Close();
hbitmap_ = h;
diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h
index 36cb1cd..146cd9c 100644
--- a/chrome/common/plugin_messages_internal.h
+++ b/chrome/common/plugin_messages_internal.h
@@ -102,6 +102,14 @@ IPC_BEGIN_MESSAGES(Plugin, 5)
PluginMsg_Init_Params,
bool /* result */)
+ // Used to synchronously request a paint for windowless plugins.
+ IPC_SYNC_MESSAGE_ROUTED1_0(PluginMsg_Paint,
+ gfx::Rect /* damaged_rect */)
+
+ // Sent by the renderer after it paints from its backing store so that the
+ // plugin knows it can send more invalidates.
+ IPC_MESSAGE_ROUTED0(PluginMsg_DidPaint)
+
IPC_SYNC_MESSAGE_ROUTED0_1(PluginMsg_Print,
PluginMsg_PrintResponse_Params /* params */)
@@ -112,12 +120,16 @@ IPC_BEGIN_MESSAGES(Plugin, 5)
IPC_SYNC_MESSAGE_ROUTED1_0(PluginMsg_DidFinishLoadWithReason,
int /* reason */)
+ // Updates the plugin location. For windowless plugins, windowless_buffer
+ // contains a buffer that the plugin draws into. background_buffer is used
+ // for transparent windowless plugins, and holds the background of the plugin
+ // rectangle.
IPC_MESSAGE_ROUTED5(PluginMsg_UpdateGeometry,
gfx::Rect /* window_rect */,
gfx::Rect /* clip_rect */,
bool /* visible */,
SharedMemoryHandle /* windowless_buffer */,
- SharedMemoryLock /* windowless_buffer_lock */)
+ SharedMemoryHandle /* background_buffer */)
IPC_SYNC_MESSAGE_ROUTED0_0(PluginMsg_SetFocus)
@@ -197,8 +209,6 @@ IPC_BEGIN_MESSAGES(PluginHost, 6)
IPC_SYNC_MESSAGE_ROUTED1_0(PluginHostMsg_CancelResource,
int /* id */)
- IPC_MESSAGE_ROUTED0(PluginHostMsg_Invalidate)
-
IPC_MESSAGE_ROUTED1(PluginHostMsg_InvalidateRect,
gfx::Rect /* rect */)
diff --git a/chrome/plugin/webplugin_delegate_stub.cc b/chrome/plugin/webplugin_delegate_stub.cc
index e2129f2..84bc069 100644
--- a/chrome/plugin/webplugin_delegate_stub.cc
+++ b/chrome/plugin/webplugin_delegate_stub.cc
@@ -80,6 +80,8 @@ void WebPluginDelegateStub::OnMessageReceived(const IPC::Message& msg) {
OnDidFinishLoadWithReason)
IPC_MESSAGE_HANDLER(PluginMsg_SetFocus, OnSetFocus)
IPC_MESSAGE_HANDLER(PluginMsg_HandleEvent, OnHandleEvent)
+ IPC_MESSAGE_HANDLER(PluginMsg_Paint, OnPaint)
+ IPC_MESSAGE_HANDLER(PluginMsg_DidPaint, OnDidPaint)
IPC_MESSAGE_HANDLER(PluginMsg_Print, OnPrint)
IPC_MESSAGE_HANDLER(PluginMsg_GetPluginScriptableObject,
OnGetPluginScriptableObject)
@@ -199,6 +201,14 @@ void WebPluginDelegateStub::OnHandleEvent(const NPEvent& event,
*handled = delegate_->HandleEvent(const_cast<NPEvent*>(&event), cursor);
}
+void WebPluginDelegateStub::OnPaint(const gfx::Rect& damaged_rect) {
+ webplugin_->Paint(damaged_rect);
+}
+
+void WebPluginDelegateStub::OnDidPaint() {
+ webplugin_->DidPaint();
+}
+
void WebPluginDelegateStub::OnPrint(PluginMsg_PrintResponse_Params* params) {
gfx::Emf emf;
if (!emf.CreateDc(NULL, NULL)) {
@@ -229,9 +239,9 @@ void WebPluginDelegateStub::OnUpdateGeometry(
const gfx::Rect& clip_rect,
bool visible,
const SharedMemoryHandle& windowless_buffer,
- const SharedMemoryLock& lock) {
+ const SharedMemoryHandle& background_buffer) {
webplugin_->UpdateGeometry(
- window_rect, clip_rect, visible, windowless_buffer, lock);
+ window_rect, clip_rect, visible, windowless_buffer, background_buffer);
}
void WebPluginDelegateStub::OnGetPluginScriptableObject(int* route_id,
diff --git a/chrome/plugin/webplugin_delegate_stub.h b/chrome/plugin/webplugin_delegate_stub.h
index cb242b4..78684bf 100644
--- a/chrome/plugin/webplugin_delegate_stub.h
+++ b/chrome/plugin/webplugin_delegate_stub.h
@@ -57,11 +57,16 @@ class WebPluginDelegateStub : public IPC::Channel::Listener,
void OnSetFocus();
void OnHandleEvent(const NPEvent& event, bool* handled,
WebCursor* cursor);
+
+ void OnPaint(const gfx::Rect& damaged_rect);
+ void OnDidPaint();
+
void OnPrint(PluginMsg_PrintResponse_Params* params);
+
void OnUpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect, bool visible,
const SharedMemoryHandle& windowless_buffer,
- const SharedMemoryLock& lock);
+ const SharedMemoryHandle& background_buffer);
void OnGetPluginScriptableObject(int* route_id, void** npobject_ptr);
void OnSendJavaScriptStream(const std::string& url,
const std::wstring& result,
diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc
index cc091a2..2abafb0 100644
--- a/chrome/plugin/webplugin_proxy.cc
+++ b/chrome/plugin/webplugin_proxy.cc
@@ -18,9 +18,6 @@
#include "chrome/plugin/npobject_util.h"
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
-// How many times per second we draw windowless plugins.
-static const int kWindowlessPaintFPS = 30;
-
typedef std::map<CPBrowsingContext, WebPluginProxy*> ContextMap;
static ContextMap& GetContextMap() {
return *Singleton<ContextMap>::get();
@@ -36,7 +33,8 @@ WebPluginProxy::WebPluginProxy(
cp_browsing_context_(0),
window_npobject_(NULL),
plugin_element_(NULL),
- delegate_(delegate) {
+ delegate_(delegate),
+ waiting_for_paint_(false) {
HANDLE event;
BOOL result = DuplicateHandle(channel->renderer_handle(),
@@ -81,14 +79,25 @@ void WebPluginProxy::CancelResource(int id) {
}
void WebPluginProxy::Invalidate() {
- Send(new PluginHostMsg_Invalidate(route_id_));
+ gfx::Rect rect(0, 0, delegate_->rect().width(), delegate_->rect().height());
+ InvalidateRect(rect);
}
void WebPluginProxy::InvalidateRect(const gfx::Rect& rect) {
+ // Ignore NPN_InvalidateRect calls with empty rects.
+ if (rect.IsEmpty())
+ return;
+
damaged_rect_ = damaged_rect_.Union(rect);
- if (!paint_timer_.IsRunning()) {
- paint_timer_.Start(TimeDelta::FromMilliseconds(1000 / kWindowlessPaintFPS),
- this, &WebPluginProxy::OnPaintTimerFired);
+ // Only send a single InvalidateRect message at a time. From DidPaint we
+ // will dispatch an additional InvalidateRect message if necessary.
+ if (!waiting_for_paint_) {
+ waiting_for_paint_ = true;
+ // Paint to the plugin bitmap and let the renderer know so it can update
+ // its backing store.
+ Paint(damaged_rect_);
+ Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect_));
+ damaged_rect_ = gfx::Rect();
}
}
@@ -190,6 +199,14 @@ WebPluginResourceClient* WebPluginProxy::GetResourceClient(int id) {
return iterator->second;
}
+void WebPluginProxy::DidPaint() {
+ // If we have an accumulated damaged rect, then check to see if we need to
+ // send out another InvalidateRect message.
+ waiting_for_paint_ = false;
+ if (!damaged_rect_.IsEmpty())
+ InvalidateRect(damaged_rect_);
+}
+
void WebPluginProxy::OnResourceCreated(int resource_id, HANDLE cookie) {
WebPluginResourceClient* resource_client =
reinterpret_cast<WebPluginResourceClient*>(cookie);
@@ -233,33 +250,26 @@ void WebPluginProxy::HandleURLRequest(const char *method,
Send(new PluginHostMsg_URLRequest(route_id_, params));
}
-void WebPluginProxy::OnPaintTimerFired() {
+void WebPluginProxy::Paint(const gfx::Rect& rect) {
if (!windowless_hdc_)
return;
- if (damaged_rect_.IsEmpty()) {
- paint_timer_.Stop();
- return;
- }
-
- DWORD wait_result = WaitForSingleObject(windowless_buffer_lock_, INFINITE);
- DCHECK(wait_result == WAIT_OBJECT_0);
-
// 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 = damaged_rect_;
- offset_rect.Offset(delegate_->rect().x(), delegate_->rect().y());
- FillRect(windowless_hdc_, &offset_rect.ToRECT(),
- static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
+ gfx::Rect offset_rect = rect;
+ offset_rect.Offset(delegate_->rect().x(), delegate_->rect().y());
+ if (!background_hdc_) {
+ FillRect(windowless_hdc_, &offset_rect.ToRECT(),
+ static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
+ } else {
+ BitBlt(windowless_hdc_, offset_rect.x(), offset_rect.y(),
+ offset_rect.width(), offset_rect.height(), background_hdc_,
+ rect.x(), rect.y(), SRCCOPY);
+ }
// Before we send the invalidate, paint so that renderer uses the updated
// bitmap.
- delegate_->Paint(windowless_hdc_, damaged_rect_);
- BOOL result = ReleaseMutex(windowless_buffer_lock_);
- DCHECK(result);
-
- Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect_));
- damaged_rect_ = gfx::Rect();
+ delegate_->Paint(windowless_hdc_, offset_rect);
}
void WebPluginProxy::UpdateGeometry(
@@ -267,33 +277,45 @@ void WebPluginProxy::UpdateGeometry(
const gfx::Rect& clip_rect,
bool visible,
const SharedMemoryHandle& windowless_buffer,
- const SharedMemoryLock& lock) {
+ const SharedMemoryHandle& background_buffer) {
+ gfx::Rect old = delegate_->rect();
bool moved = delegate_->rect().x() != window_rect.x() ||
delegate_->rect().y() != window_rect.y();
delegate_->UpdateGeometry(window_rect, clip_rect, visible);
if (windowless_buffer) {
// The plugin's rect changed, so now we have a new buffer to draw into.
- SetWindowlessBuffer(windowless_buffer, lock);
+ SetWindowlessBuffer(windowless_buffer, background_buffer);
} else if (moved) {
// The plugin moved, so update our world transform.
UpdateTransform();
}
}
-void WebPluginProxy::SetWindowlessBuffer(const SharedMemoryHandle& handle,
- const SharedMemoryLock& lock) {
+void WebPluginProxy::SetWindowlessBuffer(
+ const SharedMemoryHandle& windowless_buffer,
+ const SharedMemoryHandle& background_buffer) {
// Convert the shared memory handle to a handle that works in our process,
// and then use that to create an HDC.
- windowless_shared_section_.Set(win_util::GetSectionFromProcess(
- handle, channel_->renderer_handle(), false));
- if (!windowless_buffer_lock_) {
- HANDLE dup_handle = NULL;
- DuplicateHandle(channel_->renderer_handle(), lock, GetCurrentProcess(),
- &dup_handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
- windowless_buffer_lock_.Set(dup_handle);
+ ConvertBuffer(windowless_buffer,
+ &windowless_shared_section_,
+ &windowless_bitmap_,
+ &windowless_hdc_);
+ if (background_buffer) {
+ ConvertBuffer(background_buffer,
+ &background_shared_section_,
+ &background_bitmap_,
+ &background_hdc_);
}
+ UpdateTransform();
+}
- if (windowless_shared_section_ == NULL || windowless_buffer_lock_ == NULL) {
+void WebPluginProxy::ConvertBuffer(const 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;
}
@@ -304,24 +326,23 @@ void WebPluginProxy::SetWindowlessBuffer(const SharedMemoryHandle& handle,
gfx::CreateBitmapHeader(delegate_->rect().width(),
delegate_->rect().height(),
&bitmap_header);
- windowless_bitmap_.Set(CreateDIBSection(
+ bitmap->Set(CreateDIBSection(
screen_dc, reinterpret_cast<const BITMAPINFO*>(&bitmap_header),
- DIB_RGB_COLORS, &data, windowless_shared_section_, 0));
+ DIB_RGB_COLORS, &data, shared_section->Get(), 0));
ReleaseDC(NULL, screen_dc);
- if (windowless_bitmap_ == NULL) {
+ if (bitmap->Get() == NULL) {
NOTREACHED();
return;
}
- windowless_hdc_.Set(CreateCompatibleDC(NULL));
- if (windowless_hdc_ == NULL) {
+ hdc->Set(CreateCompatibleDC(NULL));
+ if (hdc->Get() == NULL) {
NOTREACHED();
return;
}
- gfx::PlatformDeviceWin::InitializeDC(windowless_hdc_);
- SelectObject(windowless_hdc_, windowless_bitmap_);
- UpdateTransform();
+ gfx::PlatformDeviceWin::InitializeDC(hdc->Get());
+ SelectObject(hdc->Get(), bitmap->Get());
}
void WebPluginProxy::UpdateTransform() {
diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h
index 9e1a051..ab50933 100644
--- a/chrome/plugin/webplugin_proxy.h
+++ b/chrome/plugin/webplugin_proxy.h
@@ -62,6 +62,12 @@ class WebPluginProxy : public WebPlugin {
// object with that id exists.
WebPluginResourceClient* GetResourceClient(int id);
+ // For windowless plugins, paints the given rectangle into the local buffer.
+ void Paint(const gfx::Rect& rect);
+
+ // Callback from the renderer to let us know that a paint occurred.
+ void DidPaint();
+
// Notification received on a plugin issued resource request
// creation.
void OnResourceCreated(int resource_id, HANDLE cookie);
@@ -77,7 +83,7 @@ class WebPluginProxy : public WebPlugin {
const gfx::Rect& clip_rect,
bool visible,
const SharedMemoryHandle& windowless_buffer,
- const SharedMemoryLock& lock);
+ const SharedMemoryHandle& background_buffer);
void CancelDocumentLoad();
@@ -90,12 +96,16 @@ class WebPluginProxy : public WebPlugin {
private:
bool Send(IPC::Message* msg);
- // Called periodically so that we can paint windowless plugins.
- void OnPaintTimerFired();
-
// Updates the shared memory section where windowless plugins paint.
- void SetWindowlessBuffer(const SharedMemoryHandle& handle,
- const SharedMemoryLock& lock);
+ void SetWindowlessBuffer(const SharedMemoryHandle& windowless_buffer,
+ const SharedMemoryHandle& background_buffer);
+
+ // Converts a shared memory section handle from the renderer process into a
+ // bitmap and hdc that are mapped to this process.
+ void ConvertBuffer(const SharedMemoryHandle& buffer,
+ ScopedHandle* shared_section,
+ ScopedBitmap* bitmap,
+ ScopedHDC* hdc);
// Called when a plugin's origin moves, so that we can update the world
// transform of the local HDC.
@@ -109,20 +119,23 @@ class WebPluginProxy : public WebPlugin {
NPObject* window_npobject_;
NPObject* plugin_element_;
WebPluginDelegateImpl* delegate_;
+ gfx::Rect damaged_rect_;
+ bool waiting_for_paint_;
uint32 cp_browsing_context_;
ScopedHandle modal_dialog_event_;
- // Used to desynchronize windowless painting. We accumulate invalidates and
- // paint into a shared buffer when our repeating timer fires. After painting
- // we tell the renderer asynchronously and it paints from the buffer. This
- // allows the renderer to paint without a blocking call, which improves
- // performance, and lets us control the frame rate at which we paint.
- gfx::Rect damaged_rect_;
- base::RepeatingTimer<WebPluginProxy> paint_timer_;
+ // 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_;
- ScopedHandle windowless_buffer_lock_;
+
+ // These hold the bitmap of the background image.
+ ScopedHandle background_shared_section_;
+ ScopedBitmap background_bitmap_;
+ ScopedHDC background_hdc_;
};
#endif // CHROME_PLUGIN_PLUGIN_WEBPLUGIN_PROXY_H__
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index 5670bf7..1d6e8d21 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -143,7 +143,9 @@ WebPluginDelegateProxy::WebPluginDelegateProxy(const std::string& mime_type,
send_deferred_update_geometry_(false),
visible_(false),
sad_plugin_(NULL),
- window_script_object_(NULL) {
+ window_script_object_(NULL),
+ transparent_(false),
+ invalidate_pending_(false) {
}
WebPluginDelegateProxy::~WebPluginDelegateProxy() {
@@ -222,6 +224,11 @@ bool WebPluginDelegateProxy::Initialize(const GURL& url, char** argn,
for (int i = 0; i < argc; ++i) {
params.arg_names.push_back(argn[i]);
params.arg_values.push_back(argv[i]);
+
+ if (LowerCaseEqualsASCII(params.arg_names.back(), "wmode") &&
+ LowerCaseEqualsASCII(params.arg_values.back(), "transparent")) {
+ transparent_ = true;
+ }
}
params.load_manually = load_manually;
params.modal_dialog_event = render_view_->modal_dialog_event();
@@ -299,7 +306,6 @@ void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) {
IPC_BEGIN_MESSAGE_MAP(WebPluginDelegateProxy, msg)
IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindow, OnSetWindow)
IPC_MESSAGE_HANDLER(PluginHostMsg_CancelResource, OnCancelResource)
- IPC_MESSAGE_HANDLER(PluginHostMsg_Invalidate, OnInvalidate)
IPC_MESSAGE_HANDLER(PluginHostMsg_InvalidateRect, OnInvalidateRect)
IPC_MESSAGE_HANDLER(PluginHostMsg_GetWindowScriptNPObject,
OnGetWindowScriptNPObject)
@@ -322,21 +328,14 @@ void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) {
}
void WebPluginDelegateProxy::OnChannelError() {
- OnInvalidate();
+ if (plugin_)
+ plugin_->Invalidate();
render_view_->PluginCrashed(plugin_path_);
}
-// Copied from render_widget.cc
-static size_t GetPaintBufSize(const gfx::Rect& rect) {
- // TODO(darin): protect against overflow
- return 4 * rect.width() * rect.height();
-}
-
void WebPluginDelegateProxy::UpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect,
bool visible) {
- bool moved = plugin_rect_.x() != window_rect.x() ||
- plugin_rect_.y() != window_rect.y();
plugin_rect_ = window_rect;
if (!windowless_) {
deferred_clip_rect_ = clip_rect;
@@ -345,43 +344,65 @@ void WebPluginDelegateProxy::UpdateGeometry(const gfx::Rect& window_rect,
return;
}
- HANDLE windowless_buffer_handle = NULL;
- if (!windowless_canvas_.get() ||
- (window_rect.width() != windowless_canvas_->getDevice()->width() ||
- window_rect.height() != windowless_canvas_->getDevice()->height())) {
- // Create a shared memory section that the plugin paints asynchronously.
- windowless_canvas_.reset();
- if (!windowless_buffer_lock_)
- windowless_buffer_lock_.Set(CreateMutex(NULL, FALSE, NULL));
- windowless_buffer_.reset(new SharedMemory());
- size_t size = GetPaintBufSize(plugin_rect_);
- if (!windowless_buffer_->Create(L"", false, true, size)) {
- DCHECK(false);
- windowless_buffer_.reset();
- return;
+ HANDLE transport_store_handle = NULL;
+ HANDLE background_store_handle = NULL;
+ if (!backing_store_canvas_.get() ||
+ (window_rect.width() != backing_store_canvas_->getDevice()->width() ||
+ window_rect.height() != backing_store_canvas_->getDevice()->height())) {
+ // Create a shared memory section that the plugin paints into
+ // asynchronously.
+ ResetWindowlessBitmaps();
+ if (!window_rect.IsEmpty()) {
+ if (!CreateBitmap(&backing_store_, &backing_store_canvas_) ||
+ !CreateBitmap(&transport_store_, &transport_store_canvas_) ||
+ (transparent_ &&
+ !CreateBitmap(&background_store_, &background_store_canvas_))) {
+ DCHECK(false);
+ ResetWindowlessBitmaps();
+ return;
+ }
+
+ transport_store_handle = transport_store_->handle();
+ if (background_store_.get())
+ background_store_handle = background_store_->handle();
}
-
- windowless_canvas_.reset(new gfx::PlatformCanvasWin(
- plugin_rect_.width(), plugin_rect_.height(), false,
- windowless_buffer_->handle()));
- windowless_canvas_->translate(static_cast<SkScalar>(-plugin_rect_.x()),
- static_cast<SkScalar>(-plugin_rect_.y()));
- windowless_canvas_->getTopPlatformDevice().accessBitmap(true).
- eraseARGB(0, 0, 0, 0);
- windowless_buffer_handle = windowless_buffer_->handle();
- } else if (moved) {
- windowless_canvas_->resetMatrix();
- windowless_canvas_->translate(static_cast<SkScalar>(-plugin_rect_.x()),
- static_cast<SkScalar>(-plugin_rect_.y()));
}
IPC::Message* msg = new PluginMsg_UpdateGeometry(
- instance_id_, window_rect, clip_rect, visible, windowless_buffer_handle,
- windowless_buffer_lock_);
+ instance_id_, window_rect, clip_rect, visible, transport_store_handle,
+ background_store_handle);
msg->set_unblock(true);
Send(msg);
}
+// Copied from render_widget.cc
+static size_t GetPaintBufSize(const gfx::Rect& rect) {
+ // TODO(darin): protect against overflow
+ return 4 * rect.width() * rect.height();
+}
+
+void WebPluginDelegateProxy::ResetWindowlessBitmaps() {
+ backing_store_.reset();
+ transport_store_.reset();
+ backing_store_canvas_.reset();
+ transport_store_canvas_.reset();
+ background_store_.reset();
+ background_store_canvas_.release();
+}
+
+bool WebPluginDelegateProxy::CreateBitmap(
+ scoped_ptr<SharedMemory>* memory,
+ scoped_ptr<gfx::PlatformCanvasWin>* canvas) {
+ size_t size = GetPaintBufSize(plugin_rect_);
+ memory->reset(new SharedMemory());
+ if (!(*memory)->Create(L"", false, true, size))
+ return false;
+
+ canvas->reset(new gfx::PlatformCanvasWin(
+ plugin_rect_.width(), plugin_rect_.height(), true, (*memory)->handle()));
+ return true;
+}
+
void WebPluginDelegateProxy::Paint(HDC hdc, const gfx::Rect& damaged_rect) {
// If the plugin is no longer connected (channel crashed) draw a crashed
// plugin bitmap
@@ -398,32 +419,84 @@ void WebPluginDelegateProxy::Paint(HDC hdc, const gfx::Rect& damaged_rect) {
// We shall use PrintWindow() to draw the window.
return;
}
- first_paint_ = false;
// We got a paint before the plugin's coordinates, so there's no buffer to
// copy from.
- if (!windowless_buffer_.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_);
- DWORD wait_result = WaitForSingleObject(windowless_buffer_lock_, INFINITE);
- DCHECK(wait_result == WAIT_OBJECT_0);
+ bool background_changed = false;
+ if (background_store_canvas_.get() && BackgroundChanged(hdc, rect)) {
+ background_changed = true;
+ HDC background_hdc =
+ background_store_canvas_->getTopPlatformDevice().getBitmapDC();
+ BitBlt(background_hdc, rect.x()-plugin_rect_.x(), rect.y()-plugin_rect_.y(),
+ rect.width(), rect.height(), hdc, rect.x(), rect.y(), SRCCOPY);
+ }
+
+ if (first_paint_ || background_changed) {
+ gfx::Rect offset_rect = rect;
+ offset_rect.Offset(-plugin_rect_.x(), -plugin_rect_.y());
+ Send(new PluginMsg_Paint(instance_id_, offset_rect));
+ CopyFromTransportToBacking(offset_rect);
+ }
+
+ first_paint_ = false;
+ HDC backing_hdc = backing_store_canvas_->getTopPlatformDevice().getBitmapDC();
+ BitBlt(hdc, rect.x(), rect.y(), rect.width(), rect.height(), backing_hdc,
+ rect.x()-plugin_rect_.x(), rect.y()-plugin_rect_.y(), SRCCOPY);
+
+ if (invalidate_pending_) {
+ // Only send the PaintAck message if this paint is in response to an
+ // invalidate from the plugin, since this message acts as an access token
+ // to ensure only one process is using the transport dib at a time.
+ invalidate_pending_ = false;
+ Send(new PluginMsg_DidPaint(instance_id_));
+ }
+}
+
+bool WebPluginDelegateProxy::BackgroundChanged(
+ HDC hdc,
+ const gfx::Rect& rect) {
+ HBITMAP hbitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
+ if (hbitmap == NULL) {
+ NOTREACHED();
+ return true;
+ }
+
+ BITMAP bitmap = { 0 };
+ int result = GetObject(hbitmap, sizeof(bitmap), &bitmap);
+ if (!result) {
+ NOTREACHED();
+ return true;
+ }
- BLENDFUNCTION m_bf;
- m_bf.BlendOp = AC_SRC_OVER;
- m_bf.BlendFlags = 0;
- m_bf.SourceConstantAlpha = 255;
- m_bf.AlphaFormat = AC_SRC_ALPHA;
+ XFORM xf;
+ if (!GetWorldTransform(hdc, &xf)) {
+ NOTREACHED();
+ return true;
+ }
- HDC new_hdc = windowless_canvas_->getTopPlatformDevice().getBitmapDC();
- AlphaBlend(hdc, rect.x(), rect.y(), rect.width(), rect.height(),
- new_hdc, rect.x(), rect.y(), rect.width(), rect.height(), m_bf);
+ int row_byte_size = rect.width() * (bitmap.bmBitsPixel / 8);
+ for (int y = rect.y(); y < rect.bottom(); y++) {
+ char* hdc_row_start = static_cast<char*>(bitmap.bmBits) +
+ (y + static_cast<int>(xf.eDy)) * bitmap.bmWidthBytes +
+ (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(
+ rect.x() - plugin_rect_.x(), y - plugin_rect_.y());
+ if (memcmp(hdc_row_start, canvas_row_start, row_byte_size) != 0)
+ return true;
+ }
- BOOL result = ReleaseMutex(windowless_buffer_lock_);
- DCHECK(result);
+ return false;
}
void WebPluginDelegateProxy::Print(HDC hdc) {
@@ -488,11 +561,6 @@ int WebPluginDelegateProxy::GetProcessId() {
return channel_host_->peer_pid();
}
-HWND WebPluginDelegateProxy::GetWindowHandle() {
- NOTREACHED() << "GetWindowHandle can't be called on the proxy.";
- return NULL;
-}
-
void WebPluginDelegateProxy::OnSetWindow(
HWND window, HANDLE modal_loop_pump_messages_event) {
windowless_ = window == NULL;
@@ -508,14 +576,13 @@ void WebPluginDelegateProxy::OnCancelResource(int id) {
plugin_->CancelResource(id);
}
-void WebPluginDelegateProxy::OnInvalidate() {
- if (plugin_)
- plugin_->Invalidate();
-}
-
void WebPluginDelegateProxy::OnInvalidateRect(const gfx::Rect& rect) {
- if (plugin_)
- plugin_->InvalidateRect(rect);
+ if (!plugin_)
+ return;
+
+ invalidate_pending_ = true;
+ CopyFromTransportToBacking(rect);
+ plugin_->InvalidateRect(rect);
}
void WebPluginDelegateProxy::OnGetWindowScriptNPObject(
@@ -616,6 +683,18 @@ void WebPluginDelegateProxy::PaintSadPlugin(HDC hdc, const gfx::Rect& rect) {
return;
}
+void WebPluginDelegateProxy::CopyFromTransportToBacking(const gfx::Rect& rect) {
+ if (!backing_store_canvas_.get())
+ return;
+
+ // 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);
+}
+
void WebPluginDelegateProxy::OnHandleURLRequest(
const PluginHostMsg_URLRequest_Params& params) {
const char* data = NULL;
diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h
index c457f90..7a7da77 100644
--- a/chrome/renderer/webplugin_delegate_proxy.h
+++ b/chrome/renderer/webplugin_delegate_proxy.h
@@ -60,7 +60,6 @@ class WebPluginDelegateProxy : public WebPluginDelegate,
virtual void SetFocus();
virtual bool HandleEvent(NPEvent* event, WebCursor* cursor);
virtual int GetProcessId();
- virtual HWND GetWindowHandle();
// IPC::Channel::Listener implementation:
virtual void OnMessageReceived(const IPC::Message& msg);
@@ -110,7 +109,6 @@ class WebPluginDelegateProxy : public WebPluginDelegate,
bool* result);
void OnHandleURLRequest(const PluginHostMsg_URLRequest_Params& params);
void OnCancelResource(int id);
- void OnInvalidate();
void OnInvalidateRect(const gfx::Rect& rect);
void OnGetWindowScriptNPObject(int route_id, bool* success, void** npobject_ptr);
void OnGetPluginElement(int route_id, bool* success, void** npobject_ptr);
@@ -133,6 +131,20 @@ class WebPluginDelegateProxy : public WebPluginDelegate,
// Draw a graphic indicating a crashed plugin.
void PaintSadPlugin(HDC hdc, const gfx::Rect& rect);
+ // Returns true if the given rectangle is different in the hdc and the
+ // current background bitmap.
+ bool BackgroundChanged(HDC hdc, const gfx::Rect& rect);
+
+ // Copies the given rectangle from the transport bitmap to the backing store.
+ void CopyFromTransportToBacking(const gfx::Rect& rect);
+
+ // Clears the shared memory section and canvases used for windowless plugins.
+ void ResetWindowlessBitmaps();
+
+ // Creates a shared memory section and canvas.
+ bool CreateBitmap(scoped_ptr<SharedMemory>* memory,
+ scoped_ptr<gfx::PlatformCanvasWin>* canvas);
+
RenderView* render_view_;
WebPlugin* plugin_;
bool windowless_;
@@ -158,11 +170,21 @@ class WebPluginDelegateProxy : public WebPluginDelegate,
// Bitmap for crashed plugin
SkBitmap* sad_plugin_;
- // Used for desynchronized windowless painting. See the comment in
- // webplugin_proxy.h for information about how this works.
- scoped_ptr<SharedMemory> windowless_buffer_;
- scoped_ptr<gfx::PlatformCanvasWin> windowless_canvas_;
- ScopedHandle windowless_buffer_lock_;
+ // True if we got an invalidate from the plugin and are waiting for a paint.
+ bool invalidate_pending_;
+
+ // Used to desynchronize windowless painting. When WebKit paints, we bitblt
+ // from our backing store of what the plugin rectangle looks like. The
+ // plugin paints into the transport store, and we copy that to our backing
+ // store when we get an invalidate from it. The background bitmap is used
+ // for transparent plugins, as they need the backgroud data during painting.
+ bool transparent_;
+ scoped_ptr<SharedMemory> backing_store_;
+ scoped_ptr<gfx::PlatformCanvasWin> backing_store_canvas_;
+ scoped_ptr<SharedMemory> transport_store_;
+ scoped_ptr<gfx::PlatformCanvasWin> transport_store_canvas_;
+ scoped_ptr<SharedMemory> background_store_;
+ scoped_ptr<gfx::PlatformCanvasWin> background_store_canvas_;
DISALLOW_EVIL_CONSTRUCTORS(WebPluginDelegateProxy);
};
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc
index 7993048..b793032 100644
--- a/webkit/glue/plugins/plugin_host.cc
+++ b/webkit/glue/plugins/plugin_host.cc
@@ -5,7 +5,6 @@
#include "webkit/glue/plugins/plugin_host.h"
#include "base/logging.h"
-#include "base/message_loop.h"
#include "base/string_util.h"
#include "webkit/default_plugin/default_plugin_shared.h"
#include "webkit/glue/glue_util.h"
@@ -17,29 +16,12 @@
#include "webkit/glue/plugins/plugin_stream_url.h"
#include "third_party/npapi/bindings/npruntime.h"
-extern "C" {
-
-// FindInstance()
-// Finds a PluginInstance from an NPP.
-// The caller must take a reference if needed.
-NPAPI::PluginInstance* FindInstance(NPP id) {
- if (id == NULL) {
- NOTREACHED();
- return NULL;
- }
-
- return (NPAPI::PluginInstance *)id->ndata;
-}
namespace NPAPI
{
scoped_refptr<PluginHost> PluginHost::singleton_;
-static const int kFlashMessageThrottleDelayMs = 10;
-
-PluginHost::PluginHost()
-#pragma warning(suppress: 4355) // can use this
- : throttle_factory_(this) {
+PluginHost::PluginHost() {
InitializeHostFuncs();
}
@@ -151,78 +133,6 @@ void PluginHost::PatchNPNetscapeFuncs(NPNetscapeFuncs* overrides) {
host_funcs_.enumerate = overrides->enumerate;
}
-void PluginHost::InvalidateRect(NPP id, NPRect* invalidRect) {
- if (!invalidRect) {
- NOTREACHED();
- return;
- }
-
- // Invalidates specified drawing area prior to repainting or refreshing a
- // windowless plugin
-
- // Before a windowless plugin can refresh part of its drawing area, it must
- // first invalidate it. This function causes the NPP_HandleEvent method to
- // pass an update event or a paint message to the plug-in. After calling
- // this method, the plug-in recieves a paint message asynchronously.
-
- // The browser redraws invalid areas of the document and any windowless
- // plug-ins at regularly timed intervals. To force a paint message, the
- // plug-in can call NPN_ForceRedraw after calling this method.
-
- scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id);
- DCHECK(plugin.get() != NULL);
-
- if (plugin.get() && plugin->webplugin()) {
- if (!plugin->windowless()) {
- RECT rect = {0};
- rect.left = invalidRect->left;
- rect.right = invalidRect->right;
- rect.top = invalidRect->top;
- rect.bottom = invalidRect->bottom;
- ::InvalidateRect(plugin->window_handle(), &rect, FALSE);
- return;
- }
-
- if (plugin->throttle_invalidate()) {
- // We need to track plugin invalidates on a per instance basis.
- ThrottledInvalidates plugin_instance_invalidates;
- InstanceThrottledInvalidatesMap::iterator invalidate_index =
- instance_throttled_invalidates_.find(id);
- if (invalidate_index != instance_throttled_invalidates_.end()) {
- plugin_instance_invalidates = (*invalidate_index).second;
- }
-
- bool throttle_active =
- (plugin_instance_invalidates.throttled_invalidates.size() > 0);
-
- gfx::Rect rect(invalidRect->left,
- invalidRect->top,
- invalidRect->right - invalidRect->left,
- invalidRect->bottom - invalidRect->top);
-
- plugin_instance_invalidates.throttled_invalidates.push_back(rect);
-
- if (!throttle_active) {
- // We hold a reference to the plugin instance to avoid race conditions
- // due to the instance being released before the OnInvalidateRect
- // function is invoked.
- plugin->AddRef();
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- throttle_factory_.NewRunnableMethod(&PluginHost::OnInvalidateRect,
- id, plugin.get()),
- kFlashMessageThrottleDelayMs);
- }
- instance_throttled_invalidates_[id] = plugin_instance_invalidates;
- } else {
- gfx::Rect rect(invalidRect->left,
- invalidRect->top,
- invalidRect->right - invalidRect->left,
- invalidRect->bottom - invalidRect->top);
- plugin->webplugin()->InvalidateRect(rect);
- }
- }
-}
-
bool PluginHost::SetPostData(const char *buf,
uint32 length,
std::vector<std::string>* names,
@@ -325,39 +235,22 @@ bool PluginHost::SetPostData(const char *buf,
return !err;
}
-void PluginHost::OnInvalidateRect(NPP id, PluginInstance* instance) {
- if (!instance) {
- NOTREACHED();
- return;
- }
-
- InstanceThrottledInvalidatesMap::iterator invalidate_index =
- instance_throttled_invalidates_.find(id);
- if (invalidate_index == instance_throttled_invalidates_.end()) {
- NOTREACHED();
- instance->Release();
- return;
- }
+} // namespace NPAPI
- ThrottledInvalidates plugin_instance_invalidates =
- (*invalidate_index).second;
+extern "C" {
- if (instance->webplugin()) {
- for (unsigned int throttle_index = 0;
- throttle_index <
- plugin_instance_invalidates.throttled_invalidates.size();
- throttle_index++) {
- instance->webplugin()->InvalidateRect(
- plugin_instance_invalidates.throttled_invalidates[throttle_index]);
- }
+// FindInstance()
+// Finds a PluginInstance from an NPP.
+// The caller must take a reference if needed.
+NPAPI::PluginInstance* FindInstance(NPP id) {
+ if (id == NULL) {
+ NOTREACHED();
+ return NULL;
}
- instance->Release();
- instance_throttled_invalidates_.erase(invalidate_index);
+ return (NPAPI::PluginInstance *)id->ndata;
}
-} // namespace NPAPI
-
// Allocates memory from the host's memory space.
void* NPN_MemAlloc(uint32 size) {
scoped_refptr<NPAPI::PluginHost> host = NPAPI::PluginHost::Singleton();
@@ -646,9 +539,30 @@ void NPN_Status(NPP id, const char* message) {
}
void NPN_InvalidateRect(NPP id, NPRect *invalidRect) {
- scoped_refptr<NPAPI::PluginHost> host = NPAPI::PluginHost::Singleton();
- if (host != NULL) {
- host->InvalidateRect(id, invalidRect);
+ // Invalidates specified drawing area prior to repainting or refreshing a
+ // windowless plugin
+
+ // Before a windowless plugin can refresh part of its drawing area, it must
+ // first invalidate it. This function causes the NPP_HandleEvent method to
+ // pass an update event or a paint message to the plug-in. After calling
+ // this method, the plug-in recieves a paint message asynchronously.
+
+ // The browser redraws invalid areas of the document and any windowless
+ // plug-ins at regularly timed intervals. To force a paint message, the
+ // plug-in can call NPN_ForceRedraw after calling this method.
+
+ scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id);
+ DCHECK(plugin.get() != NULL);
+ if (plugin.get() && plugin->webplugin()) {
+ if (invalidRect) {
+ gfx::Rect rect(invalidRect->left,
+ invalidRect->top,
+ invalidRect->right - invalidRect->left,
+ invalidRect->bottom - invalidRect->top);
+ plugin->webplugin()->InvalidateRect(rect);
+ } else {
+ plugin->webplugin()->Invalidate();
+ }
}
}
diff --git a/webkit/glue/plugins/plugin_host.h b/webkit/glue/plugins/plugin_host.h
index 0a90f29..be12d5e 100644
--- a/webkit/glue/plugins/plugin_host.h
+++ b/webkit/glue/plugins/plugin_host.h
@@ -9,11 +9,8 @@
#include <string>
#include <vector>
-#include <map>
#include "base/ref_counted.h"
-#include "base/gfx/rect.h"
-#include "base/task.h"
#include "webkit/glue/plugins/nphostapi.h"
#include "third_party/npapi/bindings/npapi.h"
@@ -50,31 +47,12 @@ class PluginHost : public base::RefCounted<PluginHost> {
void PatchNPNetscapeFuncs(NPNetscapeFuncs* overrides);
- // Handles invalidateRect requests for windowless plugins.
- void InvalidateRect(NPP id, NPRect* invalidRect);
-
private:
PluginHost();
void InitializeHostFuncs();
- // For certain plugins like flash we need to throttle invalidateRect
- // requests as they are made at a high frequency.
- void OnInvalidateRect(NPP id, PluginInstance* instance);
-
static scoped_refptr<PluginHost> singleton_;
NPNetscapeFuncs host_funcs_;
DISALLOW_EVIL_CONSTRUCTORS(PluginHost);
-
- // This structure keeps track of individual plugin instance invalidates.
- struct ThrottledInvalidates {
- std::vector<gfx::Rect> throttled_invalidates;
- };
-
- // We need to track throttled invalidate rects on a per plugin instance
- // basis.
- typedef std::map<NPP, ThrottledInvalidates> InstanceThrottledInvalidatesMap;
- InstanceThrottledInvalidatesMap instance_throttled_invalidates_;
-
- ScopedRunnableMethodFactory<PluginHost> throttle_factory_;
};
} // namespace NPAPI
diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc
index 0f81412..e6d5087 100644
--- a/webkit/glue/plugins/plugin_instance.cc
+++ b/webkit/glue/plugins/plugin_instance.cc
@@ -36,7 +36,6 @@ PluginInstance::PluginInstance(PluginLib *plugin, const std::string &mime_type)
use_mozilla_user_agent_(false),
message_loop_(MessageLoop::current()),
load_manually_(false),
- throttle_invalidate_(false),
get_notify_data_(NULL),
in_close_streams_(false) {
npp_ = new NPP_t();
diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h
index b6b1465..9765fef 100644
--- a/webkit/glue/plugins/plugin_instance.h
+++ b/webkit/glue/plugins/plugin_instance.h
@@ -142,11 +142,6 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
bool use_mozilla_user_agent() { return use_mozilla_user_agent_; }
void set_use_mozilla_user_agent() { use_mozilla_user_agent_ = true; }
- bool throttle_invalidate() const { return throttle_invalidate_; }
- void set_throttle_invalidate(bool throttle_invalidate) {
- throttle_invalidate_ = throttle_invalidate;
- }
-
// Helper that implements NPN_PluginThreadAsyncCall semantics
void PluginThreadAsyncCall(void (*func)(void *),
void *userData);
@@ -248,10 +243,6 @@ class PluginInstance : public base::RefCounted<PluginInstance> {
// webkit. if false indicates that the plugin should download the data.
bool load_manually_;
- // This flag indicates if the NPN_InvalidateRect calls made by the
- // plugin need to be throttled.
- bool throttle_invalidate_;
-
// Stack indicating if popups are to be enabled for the outgoing
// NPN_GetURL/NPN_GetURLNotify calls.
std::stack<bool> popups_enabled_stack_;
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc
index 29c69a87..4e1c713 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl.cc
@@ -144,7 +144,6 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
// Flash only requests windowless plugins if we return a Mozilla user
// agent.
instance_->set_use_mozilla_user_agent();
- instance_->set_throttle_invalidate(true);
quirks_ |= PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE;
} else if (plugin_info.name.find(L"Windows Media Player") !=
std::wstring::npos) {
@@ -304,10 +303,6 @@ int WebPluginDelegateImpl::GetProcessId() {
return ::GetCurrentProcessId();
}
-HWND WebPluginDelegateImpl::GetWindowHandle() {
- return instance()->window_handle();
-}
-
void WebPluginDelegateImpl::SendJavaScriptStream(const std::string& url,
const std::wstring& result,
bool success,
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index dc7374a..fe4743c 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -51,7 +51,6 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
virtual NPObject* GetPluginScriptableObject();
virtual void DidFinishLoadWithReason(NPReason reason);
virtual int GetProcessId();
- virtual HWND GetWindowHandle();
virtual void FlushGeometryUpdates() {
}
diff --git a/webkit/glue/webplugin_delegate.h b/webkit/glue/webplugin_delegate.h
index 2300986..40419bd 100644
--- a/webkit/glue/webplugin_delegate.h
+++ b/webkit/glue/webplugin_delegate.h
@@ -73,10 +73,6 @@ class WebPluginDelegate {
// Returns the process id of the process that is running the plugin.
virtual int GetProcessId() = 0;
- // Returns the window handle for this plugin if it's a windowed plugin,
- // or NULL otherwise.
- virtual gfx::ViewHandle GetWindowHandle() = 0;
-
virtual void FlushGeometryUpdates() = 0;
// The result of the script execution is returned via this function.