OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "base/gfx/gdi_util.h" | 7 #include "base/gfx/gdi_util.h" |
8 #include "base/gfx/platform_device_win.h" | 8 #include "base/gfx/platform_device_win.h" |
9 #include "base/scoped_handle.h" | 9 #include "base/scoped_handle.h" |
10 #include "base/shared_memory.h" | 10 #include "base/shared_memory.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 PluginChannel* channel, | 27 PluginChannel* channel, |
28 int route_id, | 28 int route_id, |
29 WebPluginDelegateImpl* delegate, | 29 WebPluginDelegateImpl* delegate, |
30 HANDLE modal_dialog_event) | 30 HANDLE modal_dialog_event) |
31 : channel_(channel), | 31 : channel_(channel), |
32 route_id_(route_id), | 32 route_id_(route_id), |
33 cp_browsing_context_(0), | 33 cp_browsing_context_(0), |
34 window_npobject_(NULL), | 34 window_npobject_(NULL), |
35 plugin_element_(NULL), | 35 plugin_element_(NULL), |
36 delegate_(delegate), | 36 delegate_(delegate), |
37 waiting_for_paint_(false) { | 37 waiting_for_paint_(false), |
| 38 #pragma warning(suppress: 4355) // can use this |
| 39 runnable_method_factory_(this) { |
38 | 40 |
39 HANDLE event; | 41 HANDLE event; |
40 BOOL result = DuplicateHandle(channel->renderer_handle(), | 42 BOOL result = DuplicateHandle(channel->renderer_handle(), |
41 modal_dialog_event, | 43 modal_dialog_event, |
42 GetCurrentProcess(), | 44 GetCurrentProcess(), |
43 &event, | 45 &event, |
44 SYNCHRONIZE, | 46 SYNCHRONIZE, |
45 FALSE, | 47 FALSE, |
46 0); | 48 0); |
47 DCHECK(result) << "Couldn't duplicate the modal dialog handle for the plugin."
; | 49 DCHECK(result) << "Couldn't duplicate the modal dialog handle for the plugin."
; |
(...skipping 29 matching lines...) Expand all Loading... |
77 Send(new PluginHostMsg_CancelResource(route_id_, id)); | 79 Send(new PluginHostMsg_CancelResource(route_id_, id)); |
78 resource_clients_.erase(id); | 80 resource_clients_.erase(id); |
79 } | 81 } |
80 | 82 |
81 void WebPluginProxy::Invalidate() { | 83 void WebPluginProxy::Invalidate() { |
82 gfx::Rect rect(0, 0, delegate_->rect().width(), delegate_->rect().height()); | 84 gfx::Rect rect(0, 0, delegate_->rect().width(), delegate_->rect().height()); |
83 InvalidateRect(rect); | 85 InvalidateRect(rect); |
84 } | 86 } |
85 | 87 |
86 void WebPluginProxy::InvalidateRect(const gfx::Rect& rect) { | 88 void WebPluginProxy::InvalidateRect(const gfx::Rect& rect) { |
| 89 damaged_rect_ = damaged_rect_.Union(rect); |
87 // Ignore NPN_InvalidateRect calls with empty rects. Also don't send an | 90 // Ignore NPN_InvalidateRect calls with empty rects. Also don't send an |
88 // invalidate if it's outside the clipping region, since if we did it won't | 91 // invalidate if it's outside the clipping region, since if we did it won't |
89 // lead to a paint and we'll be stuck waiting forever for a DidPaint response. | 92 // lead to a paint and we'll be stuck waiting forever for a DidPaint response. |
90 if (rect.IsEmpty() || !delegate_->clip_rect().Intersects(rect)) | 93 if (rect.IsEmpty() || !delegate_->clip_rect().Intersects(rect)) |
91 return; | 94 return; |
92 | 95 |
93 damaged_rect_ = damaged_rect_.Union(rect); | |
94 // Only send a single InvalidateRect message at a time. From DidPaint we | 96 // Only send a single InvalidateRect message at a time. From DidPaint we |
95 // will dispatch an additional InvalidateRect message if necessary. | 97 // will dispatch an additional InvalidateRect message if necessary. |
96 if (!waiting_for_paint_) { | 98 if (!waiting_for_paint_) { |
97 waiting_for_paint_ = true; | 99 waiting_for_paint_ = true; |
98 // Paint to the plugin bitmap and let the renderer know so it can update | 100 // Invalidates caused by calls to NPN_InvalidateRect/NPN_InvalidateRgn |
99 // its backing store. | 101 // need to be painted asynchronously as per the NPAPI spec. |
100 Paint(damaged_rect_); | 102 MessageLoop::current()->PostTask(FROM_HERE, |
101 Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect_)); | 103 runnable_method_factory_.NewRunnableMethod( |
| 104 &WebPluginProxy::OnPaint, damaged_rect_)); |
102 damaged_rect_ = gfx::Rect(); | 105 damaged_rect_ = gfx::Rect(); |
103 } | 106 } |
104 } | 107 } |
105 | 108 |
106 NPObject* WebPluginProxy::GetWindowScriptNPObject() { | 109 NPObject* WebPluginProxy::GetWindowScriptNPObject() { |
107 if (window_npobject_) | 110 if (window_npobject_) |
108 return NPN_RetainObject(window_npobject_); | 111 return NPN_RetainObject(window_npobject_); |
109 | 112 |
110 int npobject_route_id = channel_->GenerateRouteID(); | 113 int npobject_route_id = channel_->GenerateRouteID(); |
111 bool success = false; | 114 bool success = false; |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 } | 278 } |
276 | 279 |
277 void WebPluginProxy::UpdateGeometry( | 280 void WebPluginProxy::UpdateGeometry( |
278 const gfx::Rect& window_rect, | 281 const gfx::Rect& window_rect, |
279 const gfx::Rect& clip_rect, | 282 const gfx::Rect& clip_rect, |
280 const std::vector<gfx::Rect>& cutout_rects, | 283 const std::vector<gfx::Rect>& cutout_rects, |
281 bool visible, | 284 bool visible, |
282 const base::SharedMemoryHandle& windowless_buffer, | 285 const base::SharedMemoryHandle& windowless_buffer, |
283 const base::SharedMemoryHandle& background_buffer) { | 286 const base::SharedMemoryHandle& background_buffer) { |
284 gfx::Rect old = delegate_->rect(); | 287 gfx::Rect old = delegate_->rect(); |
| 288 gfx::Rect old_clip_rect = delegate_->clip_rect(); |
| 289 |
285 bool moved = delegate_->rect().x() != window_rect.x() || | 290 bool moved = delegate_->rect().x() != window_rect.x() || |
286 delegate_->rect().y() != window_rect.y(); | 291 delegate_->rect().y() != window_rect.y(); |
287 delegate_->UpdateGeometry(window_rect, clip_rect, cutout_rects, visible); | 292 delegate_->UpdateGeometry(window_rect, clip_rect, cutout_rects, visible); |
288 if (windowless_buffer) { | 293 if (windowless_buffer) { |
289 // The plugin's rect changed, so now we have a new buffer to draw into. | 294 // The plugin's rect changed, so now we have a new buffer to draw into. |
290 SetWindowlessBuffer(windowless_buffer, background_buffer); | 295 SetWindowlessBuffer(windowless_buffer, background_buffer); |
291 } else if (moved) { | 296 } else if (moved) { |
292 // The plugin moved, so update our world transform. | 297 // The plugin moved, so update our world transform. |
293 UpdateTransform(); | 298 UpdateTransform(); |
294 } | 299 } |
| 300 // Send over any pending invalidates which occured when the plugin was |
| 301 // off screen. |
| 302 if (visible && delegate_->windowless() && !clip_rect.IsEmpty() && |
| 303 old_clip_rect.IsEmpty() && !damaged_rect_.IsEmpty()) { |
| 304 InvalidateRect(damaged_rect_); |
| 305 } |
295 } | 306 } |
296 | 307 |
297 void WebPluginProxy::SetWindowlessBuffer( | 308 void WebPluginProxy::SetWindowlessBuffer( |
298 const base::SharedMemoryHandle& windowless_buffer, | 309 const base::SharedMemoryHandle& windowless_buffer, |
299 const base::SharedMemoryHandle& background_buffer) { | 310 const base::SharedMemoryHandle& background_buffer) { |
300 // Convert the shared memory handle to a handle that works in our process, | 311 // Convert the shared memory handle to a handle that works in our process, |
301 // and then use that to create an HDC. | 312 // and then use that to create an HDC. |
302 ConvertBuffer(windowless_buffer, | 313 ConvertBuffer(windowless_buffer, |
303 &windowless_shared_section_, | 314 &windowless_shared_section_, |
304 &windowless_bitmap_, | 315 &windowless_bitmap_, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 void WebPluginProxy::InitiateHTTPRangeRequest(const char* url, | 380 void WebPluginProxy::InitiateHTTPRangeRequest(const char* url, |
370 const char* range_info, | 381 const char* range_info, |
371 void* existing_stream, | 382 void* existing_stream, |
372 bool notify_needed, | 383 bool notify_needed, |
373 HANDLE notify_data) { | 384 HANDLE notify_data) { |
374 | 385 |
375 Send(new PluginHostMsg_InitiateHTTPRangeRequest(route_id_, url, | 386 Send(new PluginHostMsg_InitiateHTTPRangeRequest(route_id_, url, |
376 range_info, existing_stream, | 387 range_info, existing_stream, |
377 notify_needed, notify_data)); | 388 notify_needed, notify_data)); |
378 } | 389 } |
| 390 |
| 391 void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) { |
| 392 Paint(damaged_rect); |
| 393 Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect)); |
| 394 } |
OLD | NEW |