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 |