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

Side by Side Diff: chrome/renderer/webplugin_delegate_proxy.cc

Issue 417005: Add acknowledgement messages for PluginMsg_UpdateGeometry (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/renderer/webplugin_delegate_proxy.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/webplugin_delegate_proxy.h" 5 #include "chrome/renderer/webplugin_delegate_proxy.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "app/gfx/blit.h" 9 #include "app/gfx/blit.h"
10 #include "app/gfx/canvas.h" 10 #include "app/gfx/canvas.h"
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 IPC_MESSAGE_HANDLER(PluginHostMsg_MissingPluginStatus, 374 IPC_MESSAGE_HANDLER(PluginHostMsg_MissingPluginStatus,
375 OnMissingPluginStatus) 375 OnMissingPluginStatus)
376 IPC_MESSAGE_HANDLER(PluginHostMsg_URLRequest, OnHandleURLRequest) 376 IPC_MESSAGE_HANDLER(PluginHostMsg_URLRequest, OnHandleURLRequest)
377 IPC_MESSAGE_HANDLER(PluginHostMsg_GetCPBrowsingContext, 377 IPC_MESSAGE_HANDLER(PluginHostMsg_GetCPBrowsingContext,
378 OnGetCPBrowsingContext) 378 OnGetCPBrowsingContext)
379 IPC_MESSAGE_HANDLER(PluginHostMsg_CancelDocumentLoad, OnCancelDocumentLoad) 379 IPC_MESSAGE_HANDLER(PluginHostMsg_CancelDocumentLoad, OnCancelDocumentLoad)
380 IPC_MESSAGE_HANDLER(PluginHostMsg_InitiateHTTPRangeRequest, 380 IPC_MESSAGE_HANDLER(PluginHostMsg_InitiateHTTPRangeRequest,
381 OnInitiateHTTPRangeRequest) 381 OnInitiateHTTPRangeRequest)
382 IPC_MESSAGE_HANDLER(PluginHostMsg_DeferResourceLoading, 382 IPC_MESSAGE_HANDLER(PluginHostMsg_DeferResourceLoading,
383 OnDeferResourceLoading) 383 OnDeferResourceLoading)
384
385 #if defined(OS_MACOSX)
386 IPC_MESSAGE_HANDLER(PluginHostMsg_UpdateGeometry_ACK,
387 OnUpdateGeometry_ACK)
388 #endif
389
384 IPC_MESSAGE_UNHANDLED_ERROR() 390 IPC_MESSAGE_UNHANDLED_ERROR()
385 IPC_END_MESSAGE_MAP() 391 IPC_END_MESSAGE_MAP()
386 } 392 }
387 393
388 void WebPluginDelegateProxy::OnChannelError() { 394 void WebPluginDelegateProxy::OnChannelError() {
389 if (plugin_) { 395 if (plugin_) {
390 if (window_) { 396 if (window_) {
391 // The actual WebPluginDelegate never got a chance to tell the WebPlugin 397 // The actual WebPluginDelegate never got a chance to tell the WebPlugin
392 // its window was going away. Do it on its behalf. 398 // its window was going away. Do it on its behalf.
393 WillDestroyWindow(); 399 WillDestroyWindow();
394 } 400 }
395 plugin_->Invalidate(); 401 plugin_->Invalidate();
396 } 402 }
397 render_view_->PluginCrashed(info_.path); 403 render_view_->PluginCrashed(info_.path);
398 } 404 }
399 405
400 void WebPluginDelegateProxy::UpdateGeometry(const gfx::Rect& window_rect, 406 void WebPluginDelegateProxy::UpdateGeometry(const gfx::Rect& window_rect,
401 const gfx::Rect& clip_rect) { 407 const gfx::Rect& clip_rect) {
402 plugin_rect_ = window_rect; 408 plugin_rect_ = window_rect;
403 409
404 bool bitmaps_changed = false; 410 bool bitmaps_changed = false;
405 411
412 PluginMsg_UpdateGeometry_Param param;
413 #if defined(OS_MACOSX)
414 param.ack_key = -1;
415 #endif
416
406 if (windowless_) { 417 if (windowless_) {
407 if (!backing_store_canvas_.get() || 418 if (!backing_store_canvas_.get() ||
408 (window_rect.width() != backing_store_canvas_->getDevice()->width() || 419 (window_rect.width() != backing_store_canvas_->getDevice()->width() ||
409 window_rect.height() != backing_store_canvas_->getDevice()->height())) { 420 window_rect.height() != backing_store_canvas_->getDevice()->height()))
421 {
410 bitmaps_changed = true; 422 bitmaps_changed = true;
423
424 #if defined(OS_MACOSX)
425 if (backing_store_.get()) {
426 // ResetWindowlessBitmaps inserts the old TransportDIBs into
427 // old_transport_dibs_ using the backing store's file descriptor as
428 // the key. The constraints on the keys are that -1 is reserved
429 // to mean "no ACK required," and in-flight keys must be unique.
430 // File descriptors will never be -1, and because they won't be closed
431 // until receipt of the ACK, they're unique.
432 param.ack_key = backing_store_->handle().fd;
433 }
434 #endif
435
411 // Create a shared memory section that the plugin paints into 436 // Create a shared memory section that the plugin paints into
412 // asynchronously. 437 // asynchronously.
413 ResetWindowlessBitmaps(); 438 ResetWindowlessBitmaps();
414 if (!window_rect.IsEmpty()) { 439 if (!window_rect.IsEmpty()) {
415 if (!CreateBitmap(&backing_store_, &backing_store_canvas_) || 440 if (!CreateBitmap(&backing_store_, &backing_store_canvas_) ||
416 !CreateBitmap(&transport_store_, &transport_store_canvas_) || 441 !CreateBitmap(&transport_store_, &transport_store_canvas_) ||
417 (transparent_ && 442 (transparent_ &&
418 !CreateBitmap(&background_store_, &background_store_canvas_))) { 443 !CreateBitmap(&background_store_, &background_store_canvas_))) {
419 DCHECK(false); 444 DCHECK(false);
420 ResetWindowlessBitmaps(); 445 ResetWindowlessBitmaps();
421 return; 446 return;
422 } 447 }
423 } 448 }
424 } 449 }
425 } 450 }
426 451
427 PluginMsg_UpdateGeometry_Param param;
428 param.window_rect = window_rect; 452 param.window_rect = window_rect;
429 param.clip_rect = clip_rect; 453 param.clip_rect = clip_rect;
430 param.windowless_buffer = TransportDIB::DefaultHandleValue(); 454 param.windowless_buffer = TransportDIB::DefaultHandleValue();
431 param.background_buffer = TransportDIB::DefaultHandleValue(); 455 param.background_buffer = TransportDIB::DefaultHandleValue();
432 456
433 #if defined(OS_POSIX) 457 #if defined(OS_POSIX)
434 // If we're using POSIX mmap'd TransportDIBs, sending the handle across 458 // If we're using POSIX mmap'd TransportDIBs, sending the handle across
435 // IPC establishes a new mapping rather than just sending a window ID, 459 // IPC establishes a new mapping rather than just sending a window ID,
436 // so only do so if we've actually recreated the shared memory bitmaps. 460 // so only do so if we've actually recreated the shared memory bitmaps.
437 if (bitmaps_changed) 461 if (bitmaps_changed)
438 #endif 462 #endif
439 { 463 {
440 if (transport_store_.get()) 464 if (transport_store_.get())
441 param.windowless_buffer = transport_store_->handle(); 465 param.windowless_buffer = transport_store_->handle();
442 466
443 if (background_store_.get()) 467 if (background_store_.get())
444 param.background_buffer = background_store_->handle(); 468 param.background_buffer = background_store_->handle();
445 } 469 }
446 470
447 IPC::Message* msg; 471 IPC::Message* msg;
448 #if defined (OS_WIN) 472 #if defined (OS_WIN)
449 std::wstring filename = StringToLowerASCII(info_.path.BaseName().value());
450 if (info_.name.find(L"Windows Media Player") != std::wstring::npos) { 473 if (info_.name.find(L"Windows Media Player") != std::wstring::npos) {
451 // Need to update geometry synchronously with WMP, otherwise if a site 474 // Need to update geometry synchronously with WMP, otherwise if a site
452 // scripts the plugin to start playing while it's in the middle of handling 475 // scripts the plugin to start playing while it's in the middle of handling
453 // an update geometry message, videos don't play. See urls in bug 20260. 476 // an update geometry message, videos don't play. See urls in bug 20260.
454 msg = new PluginMsg_UpdateGeometrySync(instance_id_, param); 477 msg = new PluginMsg_UpdateGeometrySync(instance_id_, param);
455 } 478 }
456 else 479 else
457 #endif 480 #endif
458 { 481 {
459 msg = new PluginMsg_UpdateGeometry(instance_id_, param); 482 msg = new PluginMsg_UpdateGeometry(instance_id_, param);
460 msg->set_unblock(true); 483 msg->set_unblock(true);
461 } 484 }
462 485
463 Send(msg); 486 Send(msg);
464 } 487 }
465 488
466 #if defined(OS_MACOSX) 489 #if defined(OS_MACOSX)
467 static void ReleaseTransportDIB(TransportDIB *dib) { 490 static void ReleaseTransportDIB(TransportDIB *dib) {
468 if (dib) { 491 if (dib) {
469 IPC::Message* msg = new ViewHostMsg_FreeTransportDIB(dib->id()); 492 IPC::Message* msg = new ViewHostMsg_FreeTransportDIB(dib->id());
470 RenderThread::current()->Send(msg); 493 RenderThread::current()->Send(msg);
471 } 494 }
472 } 495 }
473 #endif 496 #endif
474 497
475 void WebPluginDelegateProxy::ResetWindowlessBitmaps() { 498 void WebPluginDelegateProxy::ResetWindowlessBitmaps() {
476 #if defined(OS_MACOSX) 499 #if defined(OS_MACOSX)
477 // tell the browser to relase these TransportDIBs 500 if (backing_store_.get()) {
478 ReleaseTransportDIB(backing_store_.get()); 501 int ack_key = backing_store_->handle().fd;
479 ReleaseTransportDIB(transport_store_.get()); 502
480 ReleaseTransportDIB(background_store_.get()); 503 DCHECK_NE(ack_key, -1);
504
505 // DCHECK_EQ does not work with base::hash_map.
506 DCHECK(old_transport_dibs_.find(ack_key) == old_transport_dibs_.end());
507
508 // Stash the old TransportDIBs in the map. They'll be released when an
509 // ACK message comes in.
510 RelatedTransportDIBs old_dibs;
511 old_dibs.backing_store =
512 linked_ptr<TransportDIB>(backing_store_.release());
513 old_dibs.transport_store =
514 linked_ptr<TransportDIB>(transport_store_.release());
515 old_dibs.background_store =
516 linked_ptr<TransportDIB>(background_store_.release());
517
518 old_transport_dibs_[ack_key] = old_dibs;
519 } else {
520 DCHECK(!transport_store_.get());
521 DCHECK(!background_store_.get());
522 }
523 #else
524 backing_store_.reset();
525 transport_store_.reset();
526 background_store_.reset();
481 #endif 527 #endif
482 528
483 backing_store_.reset();
484 transport_store_.reset();
485 backing_store_canvas_.reset(); 529 backing_store_canvas_.reset();
486 transport_store_canvas_.reset(); 530 transport_store_canvas_.reset();
487 background_store_.reset();
488 background_store_canvas_.release(); 531 background_store_canvas_.release();
489 backing_store_painted_ = gfx::Rect(); 532 backing_store_painted_ = gfx::Rect();
490 } 533 }
491 534
492 bool WebPluginDelegateProxy::CreateBitmap( 535 bool WebPluginDelegateProxy::CreateBitmap(
493 scoped_ptr<TransportDIB>* memory, 536 scoped_ptr<TransportDIB>* memory,
494 scoped_ptr<skia::PlatformCanvas>* canvas) { 537 scoped_ptr<skia::PlatformCanvas>* canvas) {
495 int width = plugin_rect_.width(); 538 int width = plugin_rect_.width();
496 int height = plugin_rect_.height(); 539 int height = plugin_rect_.height();
497 const size_t stride = skia::PlatformCanvas::StrideForWidth(width); 540 const size_t stride = skia::PlatformCanvas::StrideForWidth(width);
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 intptr_t existing_stream, bool notify_needed, intptr_t notify_data) { 1145 intptr_t existing_stream, bool notify_needed, intptr_t notify_data) {
1103 plugin_->InitiateHTTPRangeRequest(url.c_str(), range_info.c_str(), 1146 plugin_->InitiateHTTPRangeRequest(url.c_str(), range_info.c_str(),
1104 existing_stream, notify_needed, 1147 existing_stream, notify_needed,
1105 notify_data); 1148 notify_data);
1106 } 1149 }
1107 1150
1108 void WebPluginDelegateProxy::OnDeferResourceLoading(int resource_id, 1151 void WebPluginDelegateProxy::OnDeferResourceLoading(int resource_id,
1109 bool defer) { 1152 bool defer) {
1110 plugin_->SetDeferResourceLoading(resource_id, defer); 1153 plugin_->SetDeferResourceLoading(resource_id, defer);
1111 } 1154 }
1155
1156 #if defined(OS_MACOSX)
1157 void WebPluginDelegateProxy::OnUpdateGeometry_ACK(int ack_key) {
1158 DCHECK_NE(ack_key, -1);
1159
1160 OldTransportDIBMap::iterator iterator = old_transport_dibs_.find(ack_key);
1161
1162 // DCHECK_NE does not work with base::hash_map.
1163 DCHECK(iterator != old_transport_dibs_.end());
1164
1165 // Now that the ACK has been received, the TransportDIBs that were used
1166 // prior to the UpdateGeometry message now being acknowledged are known to
1167 // be no longer needed. Release them, and take the stale entry out of the
1168 // map.
1169 ReleaseTransportDIB(iterator->second.backing_store.get());
1170 ReleaseTransportDIB(iterator->second.transport_store.get());
1171 ReleaseTransportDIB(iterator->second.background_store.get());
1172
1173 old_transport_dibs_.erase(iterator);
1174 }
1175 #endif
OLDNEW
« no previous file with comments | « chrome/renderer/webplugin_delegate_proxy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698