| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |