diff options
author | mark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-30 03:27:28 +0000 |
---|---|---|
committer | mark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-30 03:27:28 +0000 |
commit | 77993d1399524545b78eff8281ac483b9c067837 (patch) | |
tree | 5df5d6eb4b47b541be1b1d96c64676d0c95ab2c4 /chrome/renderer/webplugin_delegate_proxy.cc | |
parent | 6c7e007f28f871e84340727f948a4da10e979f80 (diff) | |
download | chromium_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/webplugin_delegate_proxy.cc')
-rw-r--r-- | chrome/renderer/webplugin_delegate_proxy.cc | 82 |
1 files changed, 73 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 |