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 |