summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authormark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-30 03:27:28 +0000
committermark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-30 03:27:28 +0000
commit77993d1399524545b78eff8281ac483b9c067837 (patch)
tree5df5d6eb4b47b541be1b1d96c64676d0c95ab2c4 /chrome/renderer
parent6c7e007f28f871e84340727f948a4da10e979f80 (diff)
downloadchromium_src-77993d1399524545b78eff8281ac483b9c067837.zip
chromium_src-77993d1399524545b78eff8281ac483b9c067837.tar.gz
chromium_src-77993d1399524545b78eff8281ac483b9c067837.tar.bz2
Add acknowledgement messages for PluginMsg_UpdateGeometry. On the Mac, use
these acknowledgements to know when it's safe to dump old TransportDIBs in the renderer process. The Mac TransportDIB implementation uses base::SharedMemory, which cannot be disposed of if an in-flight UpdateGeometry message refers to the shared memory file descriptor. BUG=27510, 26754 TEST=1. From bug 25710: a. Visit http://www.dkmsoftware.com/Yubotu.htm b. Click "Play Now" c. Resize vigorously. Expect: no sad plug-in icon. 2. Test case from bug 26754 (affected machines only): a. Visit http://news.google.com/ b. Click the [+] to the left of a YouTube link. On affected machines, you'll get a sad plug-in icon. c. Click the [+] to the left of a different YouTube link. Expect: no crash. 3. Test case from bug 26754 comment 9 (affected machines only): a. Have lots of bookmarks (import Safari defaults) b. Right-click on bookmark bar, and choose "Open All Bookmarks" Expect: no crash. This change may not actually fix the third test case. Review URL: http://codereview.chromium.org/417005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33264 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc82
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.h27
2 files changed, 100 insertions, 9 deletions
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index e2c27a6..823080c 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -381,6 +381,12 @@ void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) {
OnInitiateHTTPRangeRequest)
IPC_MESSAGE_HANDLER(PluginHostMsg_DeferResourceLoading,
OnDeferResourceLoading)
+
+#if defined(OS_MACOSX)
+ IPC_MESSAGE_HANDLER(PluginHostMsg_UpdateGeometry_ACK,
+ OnUpdateGeometry_ACK)
+#endif
+
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
}
@@ -403,11 +409,30 @@ void WebPluginDelegateProxy::UpdateGeometry(const gfx::Rect& window_rect,
bool bitmaps_changed = false;
+ PluginMsg_UpdateGeometry_Param param;
+#if defined(OS_MACOSX)
+ param.ack_key = -1;
+#endif
+
if (windowless_) {
if (!backing_store_canvas_.get() ||
(window_rect.width() != backing_store_canvas_->getDevice()->width() ||
- window_rect.height() != backing_store_canvas_->getDevice()->height())) {
+ window_rect.height() != backing_store_canvas_->getDevice()->height()))
+ {
bitmaps_changed = true;
+
+#if defined(OS_MACOSX)
+ if (backing_store_.get()) {
+ // ResetWindowlessBitmaps inserts the old TransportDIBs into
+ // old_transport_dibs_ using the backing store's file descriptor as
+ // the key. The constraints on the keys are that -1 is reserved
+ // to mean "no ACK required," and in-flight keys must be unique.
+ // File descriptors will never be -1, and because they won't be closed
+ // until receipt of the ACK, they're unique.
+ param.ack_key = backing_store_->handle().fd;
+ }
+#endif
+
// Create a shared memory section that the plugin paints into
// asynchronously.
ResetWindowlessBitmaps();
@@ -424,7 +449,6 @@ void WebPluginDelegateProxy::UpdateGeometry(const gfx::Rect& window_rect,
}
}
- PluginMsg_UpdateGeometry_Param param;
param.window_rect = window_rect;
param.clip_rect = clip_rect;
param.windowless_buffer = TransportDIB::DefaultHandleValue();
@@ -446,7 +470,6 @@ void WebPluginDelegateProxy::UpdateGeometry(const gfx::Rect& window_rect,
IPC::Message* msg;
#if defined (OS_WIN)
- std::wstring filename = StringToLowerASCII(info_.path.BaseName().value());
if (info_.name.find(L"Windows Media Player") != std::wstring::npos) {
// Need to update geometry synchronously with WMP, otherwise if a site
// scripts the plugin to start playing while it's in the middle of handling
@@ -474,17 +497,37 @@ static void ReleaseTransportDIB(TransportDIB *dib) {
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
+ if (backing_store_.get()) {
+ int ack_key = backing_store_->handle().fd;
+
+ DCHECK_NE(ack_key, -1);
+
+ // DCHECK_EQ does not work with base::hash_map.
+ DCHECK(old_transport_dibs_.find(ack_key) == old_transport_dibs_.end());
+ // Stash the old TransportDIBs in the map. They'll be released when an
+ // ACK message comes in.
+ RelatedTransportDIBs old_dibs;
+ old_dibs.backing_store =
+ linked_ptr<TransportDIB>(backing_store_.release());
+ old_dibs.transport_store =
+ linked_ptr<TransportDIB>(transport_store_.release());
+ old_dibs.background_store =
+ linked_ptr<TransportDIB>(background_store_.release());
+
+ old_transport_dibs_[ack_key] = old_dibs;
+ } else {
+ DCHECK(!transport_store_.get());
+ DCHECK(!background_store_.get());
+ }
+#else
backing_store_.reset();
transport_store_.reset();
+ background_store_.reset();
+#endif
+
backing_store_canvas_.reset();
transport_store_canvas_.reset();
- background_store_.reset();
background_store_canvas_.release();
backing_store_painted_ = gfx::Rect();
}
@@ -1109,3 +1152,24 @@ void WebPluginDelegateProxy::OnDeferResourceLoading(int resource_id,
bool defer) {
plugin_->SetDeferResourceLoading(resource_id, defer);
}
+
+#if defined(OS_MACOSX)
+void WebPluginDelegateProxy::OnUpdateGeometry_ACK(int ack_key) {
+ DCHECK_NE(ack_key, -1);
+
+ OldTransportDIBMap::iterator iterator = old_transport_dibs_.find(ack_key);
+
+ // DCHECK_NE does not work with base::hash_map.
+ DCHECK(iterator != old_transport_dibs_.end());
+
+ // Now that the ACK has been received, the TransportDIBs that were used
+ // prior to the UpdateGeometry message now being acknowledged are known to
+ // be no longer needed. Release them, and take the stale entry out of the
+ // map.
+ ReleaseTransportDIB(iterator->second.backing_store.get());
+ ReleaseTransportDIB(iterator->second.transport_store.get());
+ ReleaseTransportDIB(iterator->second.background_store.get());
+
+ old_transport_dibs_.erase(iterator);
+}
+#endif
diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h
index d9cb3b3..02dd644 100644
--- a/chrome/renderer/webplugin_delegate_proxy.h
+++ b/chrome/renderer/webplugin_delegate_proxy.h
@@ -22,6 +22,11 @@
#include "webkit/glue/webplugininfo.h"
#include "webkit/glue/webplugin_delegate.h"
+#if defined(OS_MACOSX)
+#include "base/hash_tables.h"
+#include "base/linked_ptr.h"
+#endif
+
struct NPObject;
class NPObjectStub;
struct NPVariant_Param;
@@ -133,6 +138,10 @@ class WebPluginDelegateProxy
intptr_t notify_data);
void OnDeferResourceLoading(int resource_id, bool defer);
+#if defined(OS_MACOSX)
+ void OnUpdateGeometry_ACK(int ack_key);
+#endif
+
// Draw a graphic indicating a crashed plugin.
void PaintSadPlugin(WebKit::WebCanvas* canvas, const gfx::Rect& rect);
@@ -156,6 +165,24 @@ class WebPluginDelegateProxy
// point the window has already been destroyed).
void WillDestroyWindow();
+#if defined(OS_MACOSX)
+ // The Mac TransportDIB implementation uses base::SharedMemory, which
+ // cannot be disposed of if an in-flight UpdateGeometry message refers to
+ // the shared memory file descriptor. The old_transport_dibs_ map holds
+ // old TransportDIBs waiting to die. It's keyed by the |ack_key| values
+ // used in UpdateGeometry messages. When an UpdateGeometry_ACK message
+ // arrives, the associated RelatedTransportDIBs can be released.
+ struct RelatedTransportDIBs {
+ linked_ptr<TransportDIB> backing_store;
+ linked_ptr<TransportDIB> transport_store;
+ linked_ptr<TransportDIB> background_store;
+ };
+
+ typedef base::hash_map<int, RelatedTransportDIBs> OldTransportDIBMap;
+
+ OldTransportDIBMap old_transport_dibs_;
+#endif // OS_MACOSX
+
base::WeakPtr<RenderView> render_view_;
webkit_glue::WebPlugin* plugin_;
bool windowless_;