| 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/plugin/webplugin_proxy.h" | 5 #include "chrome/plugin/webplugin_proxy.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 | 8 |
| 9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
| 10 #include "app/win_util.h" | 10 #include "app/win_util.h" |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 const gfx::Rect& window_rect, | 478 const gfx::Rect& window_rect, |
| 479 const gfx::Rect& clip_rect, | 479 const gfx::Rect& clip_rect, |
| 480 const TransportDIB::Handle& windowless_buffer, | 480 const TransportDIB::Handle& windowless_buffer, |
| 481 const TransportDIB::Handle& background_buffer, | 481 const TransportDIB::Handle& background_buffer, |
| 482 bool transparent | 482 bool transparent |
| 483 #if defined(OS_MACOSX) | 483 #if defined(OS_MACOSX) |
| 484 , | 484 , |
| 485 int ack_key | 485 int ack_key |
| 486 #endif | 486 #endif |
| 487 ) { | 487 ) { |
| 488 TransportDIB::ScopedHandle scoped_windowless_handle(windowless_buffer); |
| 489 TransportDIB::ScopedHandle scoped_background_handle(background_buffer); |
| 488 gfx::Rect old = delegate_->GetRect(); | 490 gfx::Rect old = delegate_->GetRect(); |
| 489 gfx::Rect old_clip_rect = delegate_->GetClipRect(); | 491 gfx::Rect old_clip_rect = delegate_->GetClipRect(); |
| 490 transparent_ = transparent; | 492 transparent_ = transparent; |
| 491 | 493 |
| 492 // Update the buffers before doing anything that could call into plugin code, | 494 // Update the buffers before doing anything that could call into plugin code, |
| 493 // so that we don't process buffer changes out of order if plugins make | 495 // so that we don't process buffer changes out of order if plugins make |
| 494 // synchronous calls that lead to nested UpdateGeometry calls. | 496 // synchronous calls that lead to nested UpdateGeometry calls. |
| 495 if (TransportDIB::is_valid(windowless_buffer)) { | 497 if (TransportDIB::is_valid(windowless_buffer)) { |
| 496 // The plugin's rect changed, so now we have a new buffer to draw into. | 498 // The plugin's rect changed, so now we have a new buffer to draw into. |
| 497 SetWindowlessBuffer(windowless_buffer, background_buffer, window_rect); | 499 SetWindowlessBuffer(scoped_windowless_handle.release(), |
| 500 scoped_background_handle.release(), |
| 501 window_rect); |
| 498 } | 502 } |
| 499 | 503 |
| 500 #if defined(OS_MACOSX) | 504 #if defined(OS_MACOSX) |
| 501 delegate_->UpdateGeometryAndContext(window_rect, clip_rect, | 505 delegate_->UpdateGeometryAndContext(window_rect, clip_rect, |
| 502 windowless_context_); | 506 windowless_context_); |
| 503 #else | 507 #else |
| 504 delegate_->UpdateGeometry(window_rect, clip_rect); | 508 delegate_->UpdateGeometry(window_rect, clip_rect); |
| 505 #endif | 509 #endif |
| 506 | 510 |
| 507 // Send over any pending invalidates which occured when the plugin was | 511 // Send over any pending invalidates which occured when the plugin was |
| 508 // off screen. | 512 // off screen. |
| 509 if (delegate_->IsWindowless() && !clip_rect.IsEmpty() && | 513 if (delegate_->IsWindowless() && !clip_rect.IsEmpty() && |
| 510 !damaged_rect_.IsEmpty()) { | 514 !damaged_rect_.IsEmpty()) { |
| 511 InvalidateRect(damaged_rect_); | 515 InvalidateRect(damaged_rect_); |
| 512 } | 516 } |
| 513 | 517 |
| 514 #if defined(OS_MACOSX) | 518 #if defined(OS_MACOSX) |
| 515 // The renderer is expecting an ACK message if ack_key is not -1. | 519 // The renderer is expecting an ACK message if ack_key is not -1. |
| 516 if (ack_key != -1) { | 520 if (ack_key != -1) { |
| 517 Send(new PluginHostMsg_UpdateGeometry_ACK(route_id_, ack_key)); | 521 Send(new PluginHostMsg_UpdateGeometry_ACK(route_id_, ack_key)); |
| 518 } | 522 } |
| 519 #endif | 523 #endif |
| 520 } | 524 } |
| 521 | 525 |
| 522 #if defined(OS_WIN) | |
| 523 void WebPluginProxy::SetWindowlessBuffer( | |
| 524 const TransportDIB::Handle& windowless_buffer, | |
| 525 const TransportDIB::Handle& background_buffer, | |
| 526 const gfx::Rect& window_rect) { | |
| 527 // Create a canvas that will reference the shared bits. We have to handle | |
| 528 // errors here since we're mapping a large amount of memory that may not fit | |
| 529 // in our address space, or go wrong in some other way. | |
| 530 windowless_canvas_.reset(new skia::PlatformCanvas); | |
| 531 if (!windowless_canvas_->initialize( | |
| 532 window_rect.width(), | |
| 533 window_rect.height(), | |
| 534 true, | |
| 535 win_util::GetSectionFromProcess(windowless_buffer, | |
| 536 channel_->renderer_handle(), false))) { | |
| 537 windowless_canvas_.reset(); | |
| 538 background_canvas_.reset(); | |
| 539 return; | |
| 540 } | |
| 541 | |
| 542 if (background_buffer) { | |
| 543 background_canvas_.reset(new skia::PlatformCanvas); | |
| 544 if (!background_canvas_->initialize( | |
| 545 window_rect.width(), | |
| 546 window_rect.height(), | |
| 547 true, | |
| 548 win_util::GetSectionFromProcess(background_buffer, | |
| 549 channel_->renderer_handle(), false))) { | |
| 550 windowless_canvas_.reset(); | |
| 551 background_canvas_.reset(); | |
| 552 return; | |
| 553 } | |
| 554 } | |
| 555 } | |
| 556 | |
| 557 #elif defined(OS_MACOSX) | |
| 558 | |
| 559 void WebPluginProxy::SetWindowlessBuffer( | 526 void WebPluginProxy::SetWindowlessBuffer( |
| 560 const TransportDIB::Handle& windowless_buffer, | 527 const TransportDIB::Handle& windowless_buffer, |
| 561 const TransportDIB::Handle& background_buffer, | 528 const TransportDIB::Handle& background_buffer, |
| 562 const gfx::Rect& window_rect) { | 529 const gfx::Rect& window_rect) { |
| 563 // Convert the shared memory handle to a handle that works in our process, | 530 // We have to handle errors here since we're mapping a large amount of memory |
| 564 // and then use that to create a CGContextRef. | 531 // that may not fit in our address space. Also, the renderer may have already |
| 532 // destroyed the TransportDIB by the time we receive the handle, e.g. in case |
| 533 // of multiple resizes. |
| 534 #if defined(OS_MACOSX) |
| 565 windowless_dib_.reset(TransportDIB::Map(windowless_buffer)); | 535 windowless_dib_.reset(TransportDIB::Map(windowless_buffer)); |
| 566 background_dib_.reset(TransportDIB::Map(background_buffer)); | 536 background_dib_.reset(TransportDIB::Map(background_buffer)); |
| 567 windowless_context_.reset(CGBitmapContextCreate( | 537 if (windowless_dib_.get()) { |
| 568 windowless_dib_->memory(), | 538 windowless_context_.reset(CGBitmapContextCreate( |
| 569 window_rect.width(), | 539 windowless_dib_->memory(), |
| 570 window_rect.height(), | 540 window_rect.width(), |
| 571 8, 4 * window_rect.width(), | 541 window_rect.height(), |
| 572 mac_util::GetSystemColorSpace(), | 542 8, 4 * window_rect.width(), |
| 573 kCGImageAlphaPremultipliedFirst | | 543 mac_util::GetSystemColorSpace(), |
| 574 kCGBitmapByteOrder32Host)); | 544 kCGImageAlphaPremultipliedFirst | |
| 575 CGContextTranslateCTM(windowless_context_, 0, window_rect.height()); | 545 kCGBitmapByteOrder32Host)); |
| 576 CGContextScaleCTM(windowless_context_, 1, -1); | 546 CGContextTranslateCTM(windowless_context_, 0, window_rect.height()); |
| 547 CGContextScaleCTM(windowless_context_, 1, -1); |
| 548 } else { |
| 549 windowless_context_.reset(); |
| 550 } |
| 577 if (background_dib_.get()) { | 551 if (background_dib_.get()) { |
| 578 background_context_.reset(CGBitmapContextCreate( | 552 background_context_.reset(CGBitmapContextCreate( |
| 579 background_dib_->memory(), | 553 background_dib_->memory(), |
| 580 window_rect.width(), | 554 window_rect.width(), |
| 581 window_rect.height(), | 555 window_rect.height(), |
| 582 8, 4 * window_rect.width(), | 556 8, 4 * window_rect.width(), |
| 583 mac_util::GetSystemColorSpace(), | 557 mac_util::GetSystemColorSpace(), |
| 584 kCGImageAlphaPremultipliedFirst | | 558 kCGImageAlphaPremultipliedFirst | |
| 585 kCGBitmapByteOrder32Host)); | 559 kCGBitmapByteOrder32Host)); |
| 586 CGContextTranslateCTM(background_context_, 0, window_rect.height()); | 560 CGContextTranslateCTM(background_context_, 0, window_rect.height()); |
| 587 CGContextScaleCTM(background_context_, 1, -1); | 561 CGContextScaleCTM(background_context_, 1, -1); |
| 562 } else { |
| 563 background_context_.reset(); |
| 588 } | 564 } |
| 589 } | 565 #else |
| 590 | |
| 591 #elif defined(USE_X11) | |
| 592 | |
| 593 void WebPluginProxy::SetWindowlessBuffer( | |
| 594 const TransportDIB::Handle& windowless_buffer, | |
| 595 const TransportDIB::Handle& background_buffer, | |
| 596 const gfx::Rect& window_rect) { | |
| 597 int width = window_rect.width(); | 566 int width = window_rect.width(); |
| 598 int height = window_rect.height(); | 567 int height = window_rect.height(); |
| 599 windowless_dib_.reset(TransportDIB::Map(windowless_buffer)); | 568 windowless_dib_.reset(TransportDIB::CreateWithHandle(windowless_buffer)); |
| 600 if (windowless_dib_.get()) { | 569 background_dib_.reset(TransportDIB::CreateWithHandle(background_buffer)); |
| 601 windowless_canvas_.reset(windowless_dib_->GetPlatformCanvas(width, height)); | 570 windowless_canvas_.reset(windowless_dib_->GetPlatformCanvas(width, height)); |
| 602 } else { | 571 background_canvas_.reset(background_dib_->GetPlatformCanvas(width, height)); |
| 603 // This can happen if the renderer has already destroyed the TransportDIB | 572 if (!windowless_canvas_.get() || !background_canvas_.get()) { |
| 604 // by the time we receive the handle, e.g. in case of multiple resizes. | |
| 605 windowless_canvas_.reset(); | 573 windowless_canvas_.reset(); |
| 574 background_canvas_.reset(); |
| 575 // Destroy the TransportDIB if the canvas was not created successfully. |
| 576 // Otherwise we may have an unnecessary handle which is keeping the shared |
| 577 // memory open. |
| 578 windowless_dib_.reset(); |
| 579 background_dib_.reset(); |
| 606 } | 580 } |
| 607 background_dib_.reset(TransportDIB::Map(background_buffer)); | 581 #endif |
| 608 if (background_dib_.get()) { | |
| 609 background_canvas_.reset(background_dib_->GetPlatformCanvas(width, height)); | |
| 610 } else { | |
| 611 background_canvas_.reset(); | |
| 612 } | |
| 613 | 582 |
| 583 #if defined(USE_X11) |
| 614 // If SHM pixmaps support is available, create a SHM pixmap and | 584 // If SHM pixmaps support is available, create a SHM pixmap and |
| 615 // pass it to the delegate for windowless plugin painting. | 585 // pass it to the delegate for windowless plugin painting. |
| 616 if (delegate_->IsWindowless() && use_shm_pixmap_ && windowless_dib_.get()) { | 586 if (delegate_->IsWindowless() && use_shm_pixmap_ && windowless_dib_.get()) { |
| 617 Display* display = x11_util::GetXDisplay(); | 587 Display* display = x11_util::GetXDisplay(); |
| 618 XID root_window = x11_util::GetX11RootWindow(); | 588 XID root_window = x11_util::GetX11RootWindow(); |
| 619 XShmSegmentInfo shminfo = {0}; | 589 XShmSegmentInfo shminfo = {0}; |
| 620 | 590 |
| 621 if (windowless_shm_pixmap_ != None) | 591 if (windowless_shm_pixmap_ != None) |
| 622 XFreePixmap(display, windowless_shm_pixmap_); | 592 XFreePixmap(display, windowless_shm_pixmap_); |
| 623 | 593 |
| 624 shminfo.shmseg = windowless_dib_->MapToX(display); | 594 shminfo.shmseg = windowless_dib_->MapToX(display); |
| 625 // Create a shared memory pixmap based on the image buffer. | 595 // Create a shared memory pixmap based on the image buffer. |
| 626 windowless_shm_pixmap_ = XShmCreatePixmap(display, root_window, | 596 windowless_shm_pixmap_ = XShmCreatePixmap(display, root_window, |
| 627 NULL, &shminfo, | 597 NULL, &shminfo, |
| 628 width, height, | 598 width, height, |
| 629 DefaultDepth(display, 0)); | 599 DefaultDepth(display, 0)); |
| 630 | 600 |
| 631 delegate_->SetWindowlessShmPixmap(windowless_shm_pixmap_); | 601 delegate_->SetWindowlessShmPixmap(windowless_shm_pixmap_); |
| 632 } | 602 } |
| 603 #endif |
| 633 } | 604 } |
| 634 | 605 |
| 635 #endif | |
| 636 | |
| 637 void WebPluginProxy::CancelDocumentLoad() { | 606 void WebPluginProxy::CancelDocumentLoad() { |
| 638 Send(new PluginHostMsg_CancelDocumentLoad(route_id_)); | 607 Send(new PluginHostMsg_CancelDocumentLoad(route_id_)); |
| 639 } | 608 } |
| 640 | 609 |
| 641 void WebPluginProxy::InitiateHTTPRangeRequest( | 610 void WebPluginProxy::InitiateHTTPRangeRequest( |
| 642 const char* url, const char* range_info, int range_request_id) { | 611 const char* url, const char* range_info, int range_request_id) { |
| 643 Send(new PluginHostMsg_InitiateHTTPRangeRequest( | 612 Send(new PluginHostMsg_InitiateHTTPRangeRequest( |
| 644 route_id_, url, range_info, range_request_id)); | 613 route_id_, url, range_info, range_request_id)); |
| 645 } | 614 } |
| 646 | 615 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 while (index != resource_clients_.end()) { | 686 while (index != resource_clients_.end()) { |
| 718 WebPluginResourceClient* client = (*index).second; | 687 WebPluginResourceClient* client = (*index).second; |
| 719 | 688 |
| 720 if (client == resource_client) { | 689 if (client == resource_client) { |
| 721 resource_clients_.erase(index++); | 690 resource_clients_.erase(index++); |
| 722 } else { | 691 } else { |
| 723 index++; | 692 index++; |
| 724 } | 693 } |
| 725 } | 694 } |
| 726 } | 695 } |
| OLD | NEW |