| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/plugin/webplugin_proxy.h" | 5 #include "content/plugin/webplugin_proxy.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 #include "third_party/WebKit/public/web/WebBindings.h" | 25 #include "third_party/WebKit/public/web/WebBindings.h" |
| 26 #include "ui/gfx/blit.h" | 26 #include "ui/gfx/blit.h" |
| 27 #include "ui/gfx/canvas.h" | 27 #include "ui/gfx/canvas.h" |
| 28 | 28 |
| 29 #if defined(OS_MACOSX) | 29 #if defined(OS_MACOSX) |
| 30 #include "base/mac/mac_util.h" | 30 #include "base/mac/mac_util.h" |
| 31 #include "base/mac/scoped_cftyperef.h" | 31 #include "base/mac/scoped_cftyperef.h" |
| 32 #include "content/plugin/webplugin_accelerated_surface_proxy_mac.h" | 32 #include "content/plugin/webplugin_accelerated_surface_proxy_mac.h" |
| 33 #endif | 33 #endif |
| 34 | 34 |
| 35 #if defined(USE_X11) | |
| 36 #include "ui/base/x/x11_util_internal.h" | |
| 37 #endif | |
| 38 | |
| 39 #if defined(OS_WIN) | 35 #if defined(OS_WIN) |
| 40 #include "content/common/plugin_process_messages.h" | 36 #include "content/common/plugin_process_messages.h" |
| 41 #include "content/public/common/sandbox_init.h" | 37 #include "content/public/common/sandbox_init.h" |
| 42 #endif | 38 #endif |
| 43 | 39 |
| 44 using blink::WebBindings; | 40 using blink::WebBindings; |
| 45 | 41 |
| 46 namespace content { | 42 namespace content { |
| 47 | 43 |
| 48 WebPluginProxy::SharedTransportDIB::SharedTransportDIB(TransportDIB* dib) | 44 WebPluginProxy::SharedTransportDIB::SharedTransportDIB(TransportDIB* dib) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 60 : channel_(channel), | 56 : channel_(channel), |
| 61 route_id_(route_id), | 57 route_id_(route_id), |
| 62 window_npobject_(NULL), | 58 window_npobject_(NULL), |
| 63 plugin_element_(NULL), | 59 plugin_element_(NULL), |
| 64 delegate_(NULL), | 60 delegate_(NULL), |
| 65 waiting_for_paint_(false), | 61 waiting_for_paint_(false), |
| 66 page_url_(page_url), | 62 page_url_(page_url), |
| 67 windowless_buffer_index_(0), | 63 windowless_buffer_index_(0), |
| 68 host_render_view_routing_id_(host_render_view_routing_id), | 64 host_render_view_routing_id_(host_render_view_routing_id), |
| 69 weak_factory_(this) { | 65 weak_factory_(this) { |
| 70 #if defined(USE_X11) | |
| 71 windowless_shm_pixmaps_[0] = None; | |
| 72 windowless_shm_pixmaps_[1] = None; | |
| 73 use_shm_pixmap_ = false; | |
| 74 | |
| 75 // If the X server supports SHM pixmaps | |
| 76 // and the color depth and masks match, | |
| 77 // then consider using SHM pixmaps for windowless plugin painting. | |
| 78 XDisplay* display = gfx::GetXDisplay(); | |
| 79 if (ui::QuerySharedMemorySupport(display) == ui::SHARED_MEMORY_PIXMAP && | |
| 80 gfx::BitsPerPixelForPixmapDepth( | |
| 81 display, DefaultDepth(display, DefaultScreen(display))) == 32) { | |
| 82 Visual* vis = DefaultVisual(display, DefaultScreen(display)); | |
| 83 | |
| 84 if (vis->red_mask == 0xff0000 && | |
| 85 vis->green_mask == 0xff00 && | |
| 86 vis->blue_mask == 0xff) | |
| 87 use_shm_pixmap_ = true; | |
| 88 } | |
| 89 #endif | |
| 90 } | 66 } |
| 91 | 67 |
| 92 WebPluginProxy::~WebPluginProxy() { | 68 WebPluginProxy::~WebPluginProxy() { |
| 93 #if defined(USE_X11) | |
| 94 if (windowless_shm_pixmaps_[0] != None) | |
| 95 XFreePixmap(gfx::GetXDisplay(), windowless_shm_pixmaps_[0]); | |
| 96 if (windowless_shm_pixmaps_[1] != None) | |
| 97 XFreePixmap(gfx::GetXDisplay(), windowless_shm_pixmaps_[1]); | |
| 98 #endif | |
| 99 | |
| 100 #if defined(OS_MACOSX) | 69 #if defined(OS_MACOSX) |
| 101 // Destroy the surface early, since it may send messages during cleanup. | 70 // Destroy the surface early, since it may send messages during cleanup. |
| 102 if (accelerated_surface_) | 71 if (accelerated_surface_) |
| 103 accelerated_surface_.reset(); | 72 accelerated_surface_.reset(); |
| 104 #endif | 73 #endif |
| 105 | 74 |
| 106 if (plugin_element_) | 75 if (plugin_element_) |
| 107 WebBindings::releaseObject(plugin_element_); | 76 WebBindings::releaseObject(plugin_element_); |
| 108 if (window_npobject_) | 77 if (window_npobject_) |
| 109 WebBindings::releaseObject(window_npobject_); | 78 WebBindings::releaseObject(window_npobject_); |
| 110 } | 79 } |
| 111 | 80 |
| 112 bool WebPluginProxy::Send(IPC::Message* msg) { | 81 bool WebPluginProxy::Send(IPC::Message* msg) { |
| 113 return channel_->Send(msg); | 82 return channel_->Send(msg); |
| 114 } | 83 } |
| 115 | 84 |
| 116 void WebPluginProxy::SetWindow(gfx::PluginWindowHandle window) { | 85 void WebPluginProxy::SetWindow(gfx::PluginWindowHandle window) { |
| 117 Send(new PluginHostMsg_SetWindow(route_id_, window)); | 86 Send(new PluginHostMsg_SetWindow(route_id_, window)); |
| 118 } | 87 } |
| 119 | 88 |
| 120 void WebPluginProxy::SetAcceptsInputEvents(bool accepts) { | 89 void WebPluginProxy::SetAcceptsInputEvents(bool accepts) { |
| 121 NOTREACHED(); | 90 NOTREACHED(); |
| 122 } | 91 } |
| 123 | 92 |
| 124 void WebPluginProxy::WillDestroyWindow(gfx::PluginWindowHandle window) { | 93 void WebPluginProxy::WillDestroyWindow(gfx::PluginWindowHandle window) { |
| 125 #if defined(OS_WIN) | 94 #if defined(OS_WIN) |
| 126 PluginThread::current()->Send( | 95 PluginThread::current()->Send( |
| 127 new PluginProcessHostMsg_PluginWindowDestroyed( | 96 new PluginProcessHostMsg_PluginWindowDestroyed( |
| 128 window, ::GetParent(window))); | 97 window, ::GetParent(window))); |
| 129 #elif defined(USE_X11) | |
| 130 // Nothing to do. | |
| 131 #else | 98 #else |
| 132 NOTIMPLEMENTED(); | 99 NOTIMPLEMENTED(); |
| 133 #endif | 100 #endif |
| 134 } | 101 } |
| 135 | 102 |
| 136 #if defined(OS_WIN) | 103 #if defined(OS_WIN) |
| 137 void WebPluginProxy::SetWindowlessData( | 104 void WebPluginProxy::SetWindowlessData( |
| 138 HANDLE pump_messages_event, gfx::NativeViewId dummy_activation_window) { | 105 HANDLE pump_messages_event, gfx::NativeViewId dummy_activation_window) { |
| 139 HANDLE pump_messages_event_for_renderer = NULL; | 106 HANDLE pump_messages_event_for_renderer = NULL; |
| 140 BrokerDuplicateHandle(pump_messages_event, channel_->peer_pid(), | 107 BrokerDuplicateHandle(pump_messages_event, channel_->peer_pid(), |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 // TODO(caryclark): This is a temporary workaround to allow the Darwin / Skia | 344 // TODO(caryclark): This is a temporary workaround to allow the Darwin / Skia |
| 378 // port to share code with the Darwin / CG port. All ports will eventually use | 345 // port to share code with the Darwin / CG port. All ports will eventually use |
| 379 // the common code below. | 346 // the common code below. |
| 380 delegate_->CGPaint(windowless_context(), rect); | 347 delegate_->CGPaint(windowless_context(), rect); |
| 381 if (windowless_contexts_[saved_index].get() == saved_context_weak) | 348 if (windowless_contexts_[saved_index].get() == saved_context_weak) |
| 382 CGContextRestoreGState(windowless_contexts_[saved_index]); | 349 CGContextRestoreGState(windowless_contexts_[saved_index]); |
| 383 #else | 350 #else |
| 384 // See above comment about windowless_context_ changing. | 351 // See above comment about windowless_context_ changing. |
| 385 // http::/crbug.com/139462 | 352 // http::/crbug.com/139462 |
| 386 skia::RefPtr<skia::PlatformCanvas> saved_canvas = windowless_canvas(); | 353 skia::RefPtr<skia::PlatformCanvas> saved_canvas = windowless_canvas(); |
| 387 #if defined(USE_X11) | |
| 388 scoped_refptr<SharedTransportDIB> local_dib_ref( | |
| 389 windowless_dibs_[windowless_buffer_index_]); | |
| 390 #endif | |
| 391 | 354 |
| 392 saved_canvas->save(); | 355 saved_canvas->save(); |
| 393 | 356 |
| 394 // The given clip rect is relative to the plugin coordinate system. | 357 // The given clip rect is relative to the plugin coordinate system. |
| 395 SkRect sk_rect = { SkIntToScalar(rect.x()), | 358 SkRect sk_rect = { SkIntToScalar(rect.x()), |
| 396 SkIntToScalar(rect.y()), | 359 SkIntToScalar(rect.y()), |
| 397 SkIntToScalar(rect.right()), | 360 SkIntToScalar(rect.right()), |
| 398 SkIntToScalar(rect.bottom()) }; | 361 SkIntToScalar(rect.bottom()) }; |
| 399 saved_canvas->clipRect(sk_rect); | 362 saved_canvas->clipRect(sk_rect); |
| 400 | 363 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 430 // synchronous calls that lead to nested UpdateGeometry calls. | 393 // synchronous calls that lead to nested UpdateGeometry calls. |
| 431 if (TransportDIB::is_valid_handle(windowless_buffer0)) { | 394 if (TransportDIB::is_valid_handle(windowless_buffer0)) { |
| 432 // The plugin's rect changed, so now we have new buffers to draw into. | 395 // The plugin's rect changed, so now we have new buffers to draw into. |
| 433 SetWindowlessBuffers(windowless_buffer0, | 396 SetWindowlessBuffers(windowless_buffer0, |
| 434 windowless_buffer1, | 397 windowless_buffer1, |
| 435 window_rect); | 398 window_rect); |
| 436 } | 399 } |
| 437 | 400 |
| 438 DCHECK(0 <= windowless_buffer_index && windowless_buffer_index <= 1); | 401 DCHECK(0 <= windowless_buffer_index && windowless_buffer_index <= 1); |
| 439 windowless_buffer_index_ = windowless_buffer_index; | 402 windowless_buffer_index_ = windowless_buffer_index; |
| 440 #if defined(USE_X11) | |
| 441 delegate_->SetWindowlessShmPixmap(windowless_shm_pixmap()); | |
| 442 #endif | |
| 443 | 403 |
| 444 #if defined(OS_MACOSX) | 404 #if defined(OS_MACOSX) |
| 445 delegate_->UpdateGeometryAndContext( | 405 delegate_->UpdateGeometryAndContext( |
| 446 window_rect, clip_rect, windowless_context()); | 406 window_rect, clip_rect, windowless_context()); |
| 447 #else | 407 #else |
| 448 delegate_->UpdateGeometry(window_rect, clip_rect); | 408 delegate_->UpdateGeometry(window_rect, clip_rect); |
| 449 #endif | 409 #endif |
| 450 | 410 |
| 451 // Send over any pending invalidates which occured when the plugin was | 411 // Send over any pending invalidates which occured when the plugin was |
| 452 // off screen. | 412 // off screen. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 CreateDIBAndCGContextFromHandle(windowless_buffer0, | 486 CreateDIBAndCGContextFromHandle(windowless_buffer0, |
| 527 window_rect, | 487 window_rect, |
| 528 &windowless_dibs_[0], | 488 &windowless_dibs_[0], |
| 529 &windowless_contexts_[0]); | 489 &windowless_contexts_[0]); |
| 530 CreateDIBAndCGContextFromHandle(windowless_buffer1, | 490 CreateDIBAndCGContextFromHandle(windowless_buffer1, |
| 531 window_rect, | 491 window_rect, |
| 532 &windowless_dibs_[1], | 492 &windowless_dibs_[1], |
| 533 &windowless_contexts_[1]); | 493 &windowless_contexts_[1]); |
| 534 } | 494 } |
| 535 | 495 |
| 536 #elif defined(TOOLKIT_GTK) | |
| 537 | |
| 538 void WebPluginProxy::CreateDIBAndCanvasFromHandle( | |
| 539 const TransportDIB::Handle& dib_handle, | |
| 540 const gfx::Rect& window_rect, | |
| 541 scoped_refptr<SharedTransportDIB>* dib_out, | |
| 542 skia::RefPtr<skia::PlatformCanvas>* canvas) { | |
| 543 TransportDIB* dib = TransportDIB::Map(dib_handle); | |
| 544 // dib may be NULL if the renderer has already destroyed the TransportDIB by | |
| 545 // the time we receive the handle, e.g. in case of multiple resizes. | |
| 546 if (dib) { | |
| 547 *canvas = skia::AdoptRef( | |
| 548 dib->GetPlatformCanvas(window_rect.width(), window_rect.height())); | |
| 549 } else { | |
| 550 canvas->clear(); | |
| 551 } | |
| 552 *dib_out = new SharedTransportDIB(dib); | |
| 553 } | |
| 554 | |
| 555 void WebPluginProxy::CreateShmPixmapFromDIB( | |
| 556 TransportDIB* dib, | |
| 557 const gfx::Rect& window_rect, | |
| 558 XID* pixmap_out) { | |
| 559 if (dib) { | |
| 560 XDisplay* display = gfx::GetXDisplay(); | |
| 561 XID root_window = ui::GetX11RootWindow(); | |
| 562 XShmSegmentInfo shminfo = {0}; | |
| 563 | |
| 564 if (*pixmap_out != None) | |
| 565 XFreePixmap(display, *pixmap_out); | |
| 566 | |
| 567 shminfo.shmseg = dib->MapToX(display); | |
| 568 // Create a shared memory pixmap based on the image buffer. | |
| 569 *pixmap_out = XShmCreatePixmap(display, root_window, | |
| 570 NULL, &shminfo, | |
| 571 window_rect.width(), window_rect.height(), | |
| 572 DefaultDepth(display, | |
| 573 DefaultScreen(display))); | |
| 574 } | |
| 575 } | |
| 576 | |
| 577 void WebPluginProxy::SetWindowlessBuffers( | |
| 578 const TransportDIB::Handle& windowless_buffer0, | |
| 579 const TransportDIB::Handle& windowless_buffer1, | |
| 580 const gfx::Rect& window_rect) { | |
| 581 CreateDIBAndCanvasFromHandle(windowless_buffer0, | |
| 582 window_rect, | |
| 583 &windowless_dibs_[0], | |
| 584 &windowless_canvases_[0]); | |
| 585 CreateDIBAndCanvasFromHandle(windowless_buffer1, | |
| 586 window_rect, | |
| 587 &windowless_dibs_[1], | |
| 588 &windowless_canvases_[1]); | |
| 589 | |
| 590 // If SHM pixmaps support is available, create SHM pixmaps to pass to the | |
| 591 // delegate for windowless plugin painting. | |
| 592 if (delegate_->IsWindowless() && use_shm_pixmap_) { | |
| 593 CreateShmPixmapFromDIB(windowless_dibs_[0]->dib(), | |
| 594 window_rect, | |
| 595 &windowless_shm_pixmaps_[0]); | |
| 596 CreateShmPixmapFromDIB(windowless_dibs_[1]->dib(), | |
| 597 window_rect, | |
| 598 &windowless_shm_pixmaps_[1]); | |
| 599 } | |
| 600 } | |
| 601 | |
| 602 #else | 496 #else |
| 603 | 497 |
| 604 void WebPluginProxy::SetWindowlessBuffers( | 498 void WebPluginProxy::SetWindowlessBuffers( |
| 605 const TransportDIB::Handle& windowless_buffer0, | 499 const TransportDIB::Handle& windowless_buffer0, |
| 606 const TransportDIB::Handle& windowless_buffer1, | 500 const TransportDIB::Handle& windowless_buffer1, |
| 607 const gfx::Rect& window_rect) { | 501 const gfx::Rect& window_rect) { |
| 608 NOTIMPLEMENTED(); | 502 NOTIMPLEMENTED(); |
| 609 } | 503 } |
| 610 | 504 |
| 611 #endif | 505 #endif |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 int input_type; | 611 int input_type; |
| 718 gfx::Rect caret_rect; | 612 gfx::Rect caret_rect; |
| 719 if (!delegate_->GetIMEStatus(&input_type, &caret_rect)) | 613 if (!delegate_->GetIMEStatus(&input_type, &caret_rect)) |
| 720 return; | 614 return; |
| 721 | 615 |
| 722 Send(new PluginHostMsg_NotifyIMEStatus(route_id_, input_type, caret_rect)); | 616 Send(new PluginHostMsg_NotifyIMEStatus(route_id_, input_type, caret_rect)); |
| 723 } | 617 } |
| 724 #endif | 618 #endif |
| 725 | 619 |
| 726 } // namespace content | 620 } // namespace content |
| OLD | NEW |