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/renderer/pepper/pepper_graphics_2d_host.h" | 5 #include "content/renderer/pepper/pepper_graphics_2d_host.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 namespace content { | 49 namespace content { |
50 | 50 |
51 namespace { | 51 namespace { |
52 | 52 |
53 const int64 kOffscreenCallbackDelayMs = 1000 / 30; // 30 fps | 53 const int64 kOffscreenCallbackDelayMs = 1000 / 30; // 30 fps |
54 | 54 |
55 // Converts a rect inside an image of the given dimensions. The rect may be | 55 // Converts a rect inside an image of the given dimensions. The rect may be |
56 // NULL to indicate it should be the entire image. If the rect is outside of | 56 // NULL to indicate it should be the entire image. If the rect is outside of |
57 // the image, this will do nothing and return false. | 57 // the image, this will do nothing and return false. |
58 bool ValidateAndConvertRect(const PP_Rect* rect, | 58 bool ValidateAndConvertRect(const PP_Rect* rect, |
59 int image_width, int image_height, | 59 int image_width, |
| 60 int image_height, |
60 gfx::Rect* dest) { | 61 gfx::Rect* dest) { |
61 if (!rect) { | 62 if (!rect) { |
62 // Use the entire image area. | 63 // Use the entire image area. |
63 *dest = gfx::Rect(0, 0, image_width, image_height); | 64 *dest = gfx::Rect(0, 0, image_width, image_height); |
64 } else { | 65 } else { |
65 // Validate the passed-in area. | 66 // Validate the passed-in area. |
66 if (rect->point.x < 0 || rect->point.y < 0 || | 67 if (rect->point.x < 0 || rect->point.y < 0 || rect->size.width <= 0 || |
67 rect->size.width <= 0 || rect->size.height <= 0) | 68 rect->size.height <= 0) |
68 return false; | 69 return false; |
69 | 70 |
70 // Check the max bounds, being careful of overflow. | 71 // Check the max bounds, being careful of overflow. |
71 if (static_cast<int64>(rect->point.x) + | 72 if (static_cast<int64>(rect->point.x) + |
72 static_cast<int64>(rect->size.width) > | 73 static_cast<int64>(rect->size.width) > |
73 static_cast<int64>(image_width)) | 74 static_cast<int64>(image_width)) |
74 return false; | 75 return false; |
75 if (static_cast<int64>(rect->point.y) + | 76 if (static_cast<int64>(rect->point.y) + |
76 static_cast<int64>(rect->size.height) > | 77 static_cast<int64>(rect->size.height) > |
77 static_cast<int64>(image_height)) | 78 static_cast<int64>(image_height)) |
78 return false; | 79 return false; |
79 | 80 |
80 *dest = gfx::Rect(rect->point.x, rect->point.y, | 81 *dest = gfx::Rect( |
81 rect->size.width, rect->size.height); | 82 rect->point.x, rect->point.y, rect->size.width, rect->size.height); |
82 } | 83 } |
83 return true; | 84 return true; |
84 } | 85 } |
85 | 86 |
86 // Converts BGRA <-> RGBA. | 87 // Converts BGRA <-> RGBA. |
87 void ConvertBetweenBGRAandRGBA(const uint32_t* input, | 88 void ConvertBetweenBGRAandRGBA(const uint32_t* input, |
88 int pixel_length, | 89 int pixel_length, |
89 uint32_t* output) { | 90 uint32_t* output) { |
90 for (int i = 0; i < pixel_length; i++) { | 91 for (int i = 0; i < pixel_length; i++) { |
91 const unsigned char* pixel_in = | 92 const unsigned char* pixel_in = |
92 reinterpret_cast<const unsigned char*>(&input[i]); | 93 reinterpret_cast<const unsigned char*>(&input[i]); |
93 unsigned char* pixel_out = reinterpret_cast<unsigned char*>(&output[i]); | 94 unsigned char* pixel_out = reinterpret_cast<unsigned char*>(&output[i]); |
94 pixel_out[0] = pixel_in[2]; | 95 pixel_out[0] = pixel_in[2]; |
95 pixel_out[1] = pixel_in[1]; | 96 pixel_out[1] = pixel_in[1]; |
96 pixel_out[2] = pixel_in[0]; | 97 pixel_out[2] = pixel_in[0]; |
97 pixel_out[3] = pixel_in[3]; | 98 pixel_out[3] = pixel_in[3]; |
98 } | 99 } |
99 } | 100 } |
100 | 101 |
101 // Converts ImageData from PP_IMAGEDATAFORMAT_BGRA_PREMUL to | 102 // Converts ImageData from PP_IMAGEDATAFORMAT_BGRA_PREMUL to |
102 // PP_IMAGEDATAFORMAT_RGBA_PREMUL, or reverse. It's assumed that the | 103 // PP_IMAGEDATAFORMAT_RGBA_PREMUL, or reverse. It's assumed that the |
103 // destination image is always mapped (so will have non-NULL data). | 104 // destination image is always mapped (so will have non-NULL data). |
104 void ConvertImageData(PPB_ImageData_Impl* src_image, const SkIRect& src_rect, | 105 void ConvertImageData(PPB_ImageData_Impl* src_image, |
105 PPB_ImageData_Impl* dest_image, const SkRect& dest_rect) { | 106 const SkIRect& src_rect, |
| 107 PPB_ImageData_Impl* dest_image, |
| 108 const SkRect& dest_rect) { |
106 ImageDataAutoMapper auto_mapper(src_image); | 109 ImageDataAutoMapper auto_mapper(src_image); |
107 | 110 |
108 DCHECK(src_image->format() != dest_image->format()); | 111 DCHECK(src_image->format() != dest_image->format()); |
109 DCHECK(PPB_ImageData_Impl::IsImageDataFormatSupported(src_image->format())); | 112 DCHECK(PPB_ImageData_Impl::IsImageDataFormatSupported(src_image->format())); |
110 DCHECK(PPB_ImageData_Impl::IsImageDataFormatSupported(dest_image->format())); | 113 DCHECK(PPB_ImageData_Impl::IsImageDataFormatSupported(dest_image->format())); |
111 | 114 |
112 const SkBitmap* src_bitmap = src_image->GetMappedBitmap(); | 115 const SkBitmap* src_bitmap = src_image->GetMappedBitmap(); |
113 const SkBitmap* dest_bitmap = dest_image->GetMappedBitmap(); | 116 const SkBitmap* dest_bitmap = dest_image->GetMappedBitmap(); |
114 if (src_rect.width() == src_image->width() && | 117 if (src_rect.width() == src_image->width() && |
115 dest_rect.width() == dest_image->width()) { | 118 dest_rect.width() == dest_image->width()) { |
(...skipping 13 matching lines...) Expand all Loading... |
129 src_rect.width(), | 132 src_rect.width(), |
130 dest_bitmap->getAddr32(static_cast<int>(dest_rect.fLeft), | 133 dest_bitmap->getAddr32(static_cast<int>(dest_rect.fLeft), |
131 static_cast<int>(dest_rect.fTop + y))); | 134 static_cast<int>(dest_rect.fTop + y))); |
132 } | 135 } |
133 } | 136 } |
134 } | 137 } |
135 | 138 |
136 } // namespace | 139 } // namespace |
137 | 140 |
138 struct PepperGraphics2DHost::QueuedOperation { | 141 struct PepperGraphics2DHost::QueuedOperation { |
139 enum Type { | 142 enum Type { PAINT, SCROLL, REPLACE, }; |
140 PAINT, | |
141 SCROLL, | |
142 REPLACE, | |
143 }; | |
144 | 143 |
145 QueuedOperation(Type t) | 144 QueuedOperation(Type t) |
146 : type(t), | 145 : type(t), paint_x(0), paint_y(0), scroll_dx(0), scroll_dy(0) {} |
147 paint_x(0), | |
148 paint_y(0), | |
149 scroll_dx(0), | |
150 scroll_dy(0) { | |
151 } | |
152 | 146 |
153 Type type; | 147 Type type; |
154 | 148 |
155 // Valid when type == PAINT. | 149 // Valid when type == PAINT. |
156 scoped_refptr<PPB_ImageData_Impl> paint_image; | 150 scoped_refptr<PPB_ImageData_Impl> paint_image; |
157 int paint_x, paint_y; | 151 int paint_x, paint_y; |
158 gfx::Rect paint_src_rect; | 152 gfx::Rect paint_src_rect; |
159 | 153 |
160 // Valid when type == SCROLL. | 154 // Valid when type == SCROLL. |
161 gfx::Rect scroll_clip_rect; | 155 gfx::Rect scroll_clip_rect; |
162 int scroll_dx, scroll_dy; | 156 int scroll_dx, scroll_dy; |
163 | 157 |
164 // Valid when type == REPLACE. | 158 // Valid when type == REPLACE. |
165 scoped_refptr<PPB_ImageData_Impl> replace_image; | 159 scoped_refptr<PPB_ImageData_Impl> replace_image; |
166 }; | 160 }; |
167 | 161 |
168 // static | 162 // static |
169 PepperGraphics2DHost* PepperGraphics2DHost::Create( | 163 PepperGraphics2DHost* PepperGraphics2DHost::Create( |
170 RendererPpapiHost* host, | 164 RendererPpapiHost* host, |
171 PP_Instance instance, | 165 PP_Instance instance, |
172 PP_Resource resource, | 166 PP_Resource resource, |
173 const PP_Size& size, | 167 const PP_Size& size, |
174 PP_Bool is_always_opaque, | 168 PP_Bool is_always_opaque, |
175 scoped_refptr<PPB_ImageData_Impl> backing_store) { | 169 scoped_refptr<PPB_ImageData_Impl> backing_store) { |
176 PepperGraphics2DHost* resource_host = | 170 PepperGraphics2DHost* resource_host = |
177 new PepperGraphics2DHost(host, instance, resource); | 171 new PepperGraphics2DHost(host, instance, resource); |
178 if (!resource_host->Init(size.width, size.height, | 172 if (!resource_host->Init(size.width, |
| 173 size.height, |
179 PP_ToBool(is_always_opaque), | 174 PP_ToBool(is_always_opaque), |
180 backing_store)) { | 175 backing_store)) { |
181 delete resource_host; | 176 delete resource_host; |
182 return NULL; | 177 return NULL; |
183 } | 178 } |
184 return resource_host; | 179 return resource_host; |
185 } | 180 } |
186 | 181 |
187 PepperGraphics2DHost::PepperGraphics2DHost(RendererPpapiHost* host, | 182 PepperGraphics2DHost::PepperGraphics2DHost(RendererPpapiHost* host, |
188 PP_Instance instance, | 183 PP_Instance instance, |
(...skipping 15 matching lines...) Expand all Loading... |
204 } | 199 } |
205 | 200 |
206 bool PepperGraphics2DHost::Init( | 201 bool PepperGraphics2DHost::Init( |
207 int width, | 202 int width, |
208 int height, | 203 int height, |
209 bool is_always_opaque, | 204 bool is_always_opaque, |
210 scoped_refptr<PPB_ImageData_Impl> backing_store) { | 205 scoped_refptr<PPB_ImageData_Impl> backing_store) { |
211 // The underlying PPB_ImageData_Impl will validate the dimensions. | 206 // The underlying PPB_ImageData_Impl will validate the dimensions. |
212 image_data_ = backing_store; | 207 image_data_ = backing_store; |
213 if (!image_data_->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(), | 208 if (!image_data_->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(), |
214 width, height, true) || | 209 width, |
| 210 height, |
| 211 true) || |
215 !image_data_->Map()) { | 212 !image_data_->Map()) { |
216 image_data_ = NULL; | 213 image_data_ = NULL; |
217 return false; | 214 return false; |
218 } | 215 } |
219 is_always_opaque_ = is_always_opaque; | 216 is_always_opaque_ = is_always_opaque; |
220 scale_ = 1.0f; | 217 scale_ = 1.0f; |
221 return true; | 218 return true; |
222 } | 219 } |
223 | 220 |
224 int32_t PepperGraphics2DHost::OnResourceMessageReceived( | 221 int32_t PepperGraphics2DHost::OnResourceMessageReceived( |
225 const IPC::Message& msg, | 222 const IPC::Message& msg, |
226 ppapi::host::HostMessageContext* context) { | 223 ppapi::host::HostMessageContext* context) { |
227 IPC_BEGIN_MESSAGE_MAP(PepperGraphics2DHost, msg) | 224 IPC_BEGIN_MESSAGE_MAP(PepperGraphics2DHost, msg) |
228 PPAPI_DISPATCH_HOST_RESOURCE_CALL( | 225 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_PaintImageData, |
229 PpapiHostMsg_Graphics2D_PaintImageData, | 226 OnHostMsgPaintImageData) |
230 OnHostMsgPaintImageData) | 227 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_Scroll, |
231 PPAPI_DISPATCH_HOST_RESOURCE_CALL( | 228 OnHostMsgScroll) |
232 PpapiHostMsg_Graphics2D_Scroll, | 229 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_ReplaceContents, |
233 OnHostMsgScroll) | 230 OnHostMsgReplaceContents) |
234 PPAPI_DISPATCH_HOST_RESOURCE_CALL( | 231 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Graphics2D_Flush, |
235 PpapiHostMsg_Graphics2D_ReplaceContents, | 232 OnHostMsgFlush) |
236 OnHostMsgReplaceContents) | 233 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_SetScale, |
237 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( | 234 OnHostMsgSetScale) |
238 PpapiHostMsg_Graphics2D_Flush, | 235 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_ReadImageData, |
239 OnHostMsgFlush) | 236 OnHostMsgReadImageData) |
240 PPAPI_DISPATCH_HOST_RESOURCE_CALL( | |
241 PpapiHostMsg_Graphics2D_SetScale, | |
242 OnHostMsgSetScale) | |
243 PPAPI_DISPATCH_HOST_RESOURCE_CALL( | |
244 PpapiHostMsg_Graphics2D_ReadImageData, | |
245 OnHostMsgReadImageData) | |
246 IPC_END_MESSAGE_MAP() | 237 IPC_END_MESSAGE_MAP() |
247 return PP_ERROR_FAILED; | 238 return PP_ERROR_FAILED; |
248 } | 239 } |
249 | 240 |
250 bool PepperGraphics2DHost::IsGraphics2DHost() { | 241 bool PepperGraphics2DHost::IsGraphics2DHost() { return true; } |
251 return true; | |
252 } | |
253 | 242 |
254 bool PepperGraphics2DHost::ReadImageData(PP_Resource image, | 243 bool PepperGraphics2DHost::ReadImageData(PP_Resource image, |
255 const PP_Point* top_left) { | 244 const PP_Point* top_left) { |
256 // Get and validate the image object to paint into. | 245 // Get and validate the image object to paint into. |
257 EnterResourceNoLock<PPB_ImageData_API> enter(image, true); | 246 EnterResourceNoLock<PPB_ImageData_API> enter(image, true); |
258 if (enter.failed()) | 247 if (enter.failed()) |
259 return false; | 248 return false; |
260 PPB_ImageData_Impl* image_resource = | 249 PPB_ImageData_Impl* image_resource = |
261 static_cast<PPB_ImageData_Impl*>(enter.object()); | 250 static_cast<PPB_ImageData_Impl*>(enter.object()); |
262 if (!PPB_ImageData_Impl::IsImageDataFormatSupported( | 251 if (!PPB_ImageData_Impl::IsImageDataFormatSupported(image_resource->format())) |
263 image_resource->format())) | |
264 return false; // Must be in the right format. | 252 return false; // Must be in the right format. |
265 | 253 |
266 // Validate the bitmap position. | 254 // Validate the bitmap position. |
267 int x = top_left->x; | 255 int x = top_left->x; |
268 if (x < 0 || | 256 if (x < 0 || |
269 static_cast<int64>(x) + static_cast<int64>(image_resource->width()) > | 257 static_cast<int64>(x) + static_cast<int64>(image_resource->width()) > |
270 image_data_->width()) | 258 image_data_->width()) |
271 return false; | 259 return false; |
272 int y = top_left->y; | 260 int y = top_left->y; |
273 if (y < 0 || | 261 if (y < 0 || |
274 static_cast<int64>(y) + static_cast<int64>(image_resource->height()) > | 262 static_cast<int64>(y) + static_cast<int64>(image_resource->height()) > |
275 image_data_->height()) | 263 image_data_->height()) |
276 return false; | 264 return false; |
277 | 265 |
278 ImageDataAutoMapper auto_mapper(image_resource); | 266 ImageDataAutoMapper auto_mapper(image_resource); |
279 if (!auto_mapper.is_valid()) | 267 if (!auto_mapper.is_valid()) |
280 return false; | 268 return false; |
281 | 269 |
282 SkIRect src_irect = { x, y, | 270 SkIRect src_irect = {x, y, x + image_resource->width(), |
283 x + image_resource->width(), | 271 y + image_resource->height()}; |
284 y + image_resource->height() }; | 272 SkRect dest_rect = {SkIntToScalar(0), SkIntToScalar(0), |
285 SkRect dest_rect = { SkIntToScalar(0), | 273 SkIntToScalar(image_resource->width()), |
286 SkIntToScalar(0), | 274 SkIntToScalar(image_resource->height())}; |
287 SkIntToScalar(image_resource->width()), | |
288 SkIntToScalar(image_resource->height()) }; | |
289 | 275 |
290 if (image_resource->format() != image_data_->format()) { | 276 if (image_resource->format() != image_data_->format()) { |
291 // Convert the image data if the format does not match. | 277 // Convert the image data if the format does not match. |
292 ConvertImageData(image_data_.get(), src_irect, image_resource, dest_rect); | 278 ConvertImageData(image_data_.get(), src_irect, image_resource, dest_rect); |
293 } else { | 279 } else { |
294 SkCanvas* dest_canvas = image_resource->GetCanvas(); | 280 SkCanvas* dest_canvas = image_resource->GetCanvas(); |
295 | 281 |
296 // We want to replace the contents of the bitmap rather than blend. | 282 // We want to replace the contents of the bitmap rather than blend. |
297 SkPaint paint; | 283 SkPaint paint; |
298 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 284 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
299 dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(), | 285 dest_canvas->drawBitmapRect( |
300 &src_irect, dest_rect, &paint); | 286 *image_data_->GetMappedBitmap(), &src_irect, dest_rect, &paint); |
301 } | 287 } |
302 return true; | 288 return true; |
303 } | 289 } |
304 | 290 |
305 bool PepperGraphics2DHost::BindToInstance( | 291 bool PepperGraphics2DHost::BindToInstance( |
306 PepperPluginInstanceImpl* new_instance) { | 292 PepperPluginInstanceImpl* new_instance) { |
307 if (new_instance && new_instance->pp_instance() != pp_instance()) | 293 if (new_instance && new_instance->pp_instance() != pp_instance()) |
308 return false; // Can't bind other instance's contexts. | 294 return false; // Can't bind other instance's contexts. |
309 if (bound_instance_ == new_instance) | 295 if (bound_instance_ == new_instance) |
310 return true; // Rebinding the same device, nothing to do. | 296 return true; // Rebinding the same device, nothing to do. |
(...skipping 26 matching lines...) Expand all Loading... |
337 TRACE_EVENT0("pepper", "PepperGraphics2DHost::Paint"); | 323 TRACE_EVENT0("pepper", "PepperGraphics2DHost::Paint"); |
338 ImageDataAutoMapper auto_mapper(image_data_.get()); | 324 ImageDataAutoMapper auto_mapper(image_data_.get()); |
339 const SkBitmap& backing_bitmap = *image_data_->GetMappedBitmap(); | 325 const SkBitmap& backing_bitmap = *image_data_->GetMappedBitmap(); |
340 | 326 |
341 gfx::Rect invalidate_rect = plugin_rect; | 327 gfx::Rect invalidate_rect = plugin_rect; |
342 invalidate_rect.Intersect(paint_rect); | 328 invalidate_rect.Intersect(paint_rect); |
343 SkRect sk_invalidate_rect = gfx::RectToSkRect(invalidate_rect); | 329 SkRect sk_invalidate_rect = gfx::RectToSkRect(invalidate_rect); |
344 SkAutoCanvasRestore auto_restore(canvas, true); | 330 SkAutoCanvasRestore auto_restore(canvas, true); |
345 canvas->clipRect(sk_invalidate_rect); | 331 canvas->clipRect(sk_invalidate_rect); |
346 gfx::Size pixel_image_size(image_data_->width(), image_data_->height()); | 332 gfx::Size pixel_image_size(image_data_->width(), image_data_->height()); |
347 gfx::Size image_size = gfx::ToFlooredSize( | 333 gfx::Size image_size = |
348 gfx::ScaleSize(pixel_image_size, scale_)); | 334 gfx::ToFlooredSize(gfx::ScaleSize(pixel_image_size, scale_)); |
349 | 335 |
350 PepperPluginInstance* plugin_instance = | 336 PepperPluginInstance* plugin_instance = |
351 renderer_ppapi_host_->GetPluginInstance(pp_instance()); | 337 renderer_ppapi_host_->GetPluginInstance(pp_instance()); |
352 if (!plugin_instance) | 338 if (!plugin_instance) |
353 return; | 339 return; |
354 if (plugin_instance->IsFullPagePlugin()) { | 340 if (plugin_instance->IsFullPagePlugin()) { |
355 // When we're resizing a window with a full-frame plugin, the plugin may | 341 // When we're resizing a window with a full-frame plugin, the plugin may |
356 // not yet have bound a new device, which will leave parts of the | 342 // not yet have bound a new device, which will leave parts of the |
357 // background exposed if the window is getting larger. We want this to | 343 // background exposed if the window is getting larger. We want this to |
358 // show white (typically less jarring) rather than black or uninitialized. | 344 // show white (typically less jarring) rather than black or uninitialized. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 SkPoint pixel_origin = origin; | 376 SkPoint pixel_origin = origin; |
391 | 377 |
392 if (scale_ != 1.0f && scale_ > 0.0f) { | 378 if (scale_ != 1.0f && scale_ > 0.0f) { |
393 canvas->scale(scale_, scale_); | 379 canvas->scale(scale_, scale_); |
394 pixel_origin.set(pixel_origin.x() * (1.0f / scale_), | 380 pixel_origin.set(pixel_origin.x() * (1.0f / scale_), |
395 pixel_origin.y() * (1.0f / scale_)); | 381 pixel_origin.y() * (1.0f / scale_)); |
396 } | 382 } |
397 canvas->drawBitmap(image, pixel_origin.x(), pixel_origin.y(), &paint); | 383 canvas->drawBitmap(image, pixel_origin.x(), pixel_origin.y(), &paint); |
398 } | 384 } |
399 | 385 |
400 void PepperGraphics2DHost::ViewInitiatedPaint() { | 386 void PepperGraphics2DHost::ViewInitiatedPaint() {} |
401 } | |
402 | 387 |
403 void PepperGraphics2DHost::ViewFlushedPaint() { | 388 void PepperGraphics2DHost::ViewFlushedPaint() { |
404 TRACE_EVENT0("pepper", "PepperGraphics2DHost::ViewFlushedPaint"); | 389 TRACE_EVENT0("pepper", "PepperGraphics2DHost::ViewFlushedPaint"); |
405 if (need_flush_ack_) { | 390 if (need_flush_ack_) { |
406 SendFlushAck(); | 391 SendFlushAck(); |
407 need_flush_ack_ = false; | 392 need_flush_ack_ = false; |
408 } | 393 } |
409 } | 394 } |
410 | 395 |
411 void PepperGraphics2DHost::SetScale(float scale) { | 396 void PepperGraphics2DHost::SetScale(float scale) { scale_ = scale; } |
412 scale_ = scale; | |
413 } | |
414 | 397 |
415 float PepperGraphics2DHost::GetScale() const { | 398 float PepperGraphics2DHost::GetScale() const { return scale_; } |
416 return scale_; | |
417 } | |
418 | 399 |
419 bool PepperGraphics2DHost::IsAlwaysOpaque() const { | 400 bool PepperGraphics2DHost::IsAlwaysOpaque() const { return is_always_opaque_; } |
420 return is_always_opaque_; | |
421 } | |
422 | 401 |
423 PPB_ImageData_Impl* PepperGraphics2DHost::ImageData() { | 402 PPB_ImageData_Impl* PepperGraphics2DHost::ImageData() { |
424 return image_data_.get(); | 403 return image_data_.get(); |
425 } | 404 } |
426 | 405 |
427 gfx::Size PepperGraphics2DHost::Size() const { | 406 gfx::Size PepperGraphics2DHost::Size() const { |
428 if (!image_data_) | 407 if (!image_data_) |
429 return gfx::Size(); | 408 return gfx::Size(); |
430 return gfx::Size(image_data_->width(), image_data_->height()); | 409 return gfx::Size(image_data_->width(), image_data_->height()); |
431 } | 410 } |
(...skipping 18 matching lines...) Expand all Loading... |
450 image_resource->height(), | 429 image_resource->height(), |
451 &operation.paint_src_rect)) | 430 &operation.paint_src_rect)) |
452 return PP_ERROR_BADARGUMENT; | 431 return PP_ERROR_BADARGUMENT; |
453 | 432 |
454 // Validate the bitmap position using the previously-validated rect, there | 433 // Validate the bitmap position using the previously-validated rect, there |
455 // should be no painted area outside of the image. | 434 // should be no painted area outside of the image. |
456 int64 x64 = static_cast<int64>(top_left.x); | 435 int64 x64 = static_cast<int64>(top_left.x); |
457 int64 y64 = static_cast<int64>(top_left.y); | 436 int64 y64 = static_cast<int64>(top_left.y); |
458 if (x64 + static_cast<int64>(operation.paint_src_rect.x()) < 0 || | 437 if (x64 + static_cast<int64>(operation.paint_src_rect.x()) < 0 || |
459 x64 + static_cast<int64>(operation.paint_src_rect.right()) > | 438 x64 + static_cast<int64>(operation.paint_src_rect.right()) > |
460 image_data_->width()) | 439 image_data_->width()) |
461 return PP_ERROR_BADARGUMENT; | 440 return PP_ERROR_BADARGUMENT; |
462 if (y64 + static_cast<int64>(operation.paint_src_rect.y()) < 0 || | 441 if (y64 + static_cast<int64>(operation.paint_src_rect.y()) < 0 || |
463 y64 + static_cast<int64>(operation.paint_src_rect.bottom()) > | 442 y64 + static_cast<int64>(operation.paint_src_rect.bottom()) > |
464 image_data_->height()) | 443 image_data_->height()) |
465 return PP_ERROR_BADARGUMENT; | 444 return PP_ERROR_BADARGUMENT; |
466 operation.paint_x = top_left.x; | 445 operation.paint_x = top_left.x; |
467 operation.paint_y = top_left.y; | 446 operation.paint_y = top_left.y; |
468 | 447 |
469 queued_operations_.push_back(operation); | 448 queued_operations_.push_back(operation); |
470 return PP_OK; | 449 return PP_OK; |
471 } | 450 } |
472 | 451 |
473 int32_t PepperGraphics2DHost::OnHostMsgScroll( | 452 int32_t PepperGraphics2DHost::OnHostMsgScroll( |
474 ppapi::host::HostMessageContext* context, | 453 ppapi::host::HostMessageContext* context, |
(...skipping 25 matching lines...) Expand all Loading... |
500 int32_t PepperGraphics2DHost::OnHostMsgReplaceContents( | 479 int32_t PepperGraphics2DHost::OnHostMsgReplaceContents( |
501 ppapi::host::HostMessageContext* context, | 480 ppapi::host::HostMessageContext* context, |
502 const ppapi::HostResource& image_data) { | 481 const ppapi::HostResource& image_data) { |
503 EnterResourceNoLock<PPB_ImageData_API> enter(image_data.host_resource(), | 482 EnterResourceNoLock<PPB_ImageData_API> enter(image_data.host_resource(), |
504 true); | 483 true); |
505 if (enter.failed()) | 484 if (enter.failed()) |
506 return PP_ERROR_BADRESOURCE; | 485 return PP_ERROR_BADRESOURCE; |
507 PPB_ImageData_Impl* image_resource = | 486 PPB_ImageData_Impl* image_resource = |
508 static_cast<PPB_ImageData_Impl*>(enter.object()); | 487 static_cast<PPB_ImageData_Impl*>(enter.object()); |
509 | 488 |
510 if (!PPB_ImageData_Impl::IsImageDataFormatSupported( | 489 if (!PPB_ImageData_Impl::IsImageDataFormatSupported(image_resource->format())) |
511 image_resource->format())) | |
512 return PP_ERROR_BADARGUMENT; | 490 return PP_ERROR_BADARGUMENT; |
513 | 491 |
514 if (image_resource->width() != image_data_->width() || | 492 if (image_resource->width() != image_data_->width() || |
515 image_resource->height() != image_data_->height()) | 493 image_resource->height() != image_data_->height()) |
516 return PP_ERROR_BADARGUMENT; | 494 return PP_ERROR_BADARGUMENT; |
517 | 495 |
518 QueuedOperation operation(QueuedOperation::REPLACE); | 496 QueuedOperation operation(QueuedOperation::REPLACE); |
519 operation.replace_image = image_resource; | 497 operation.replace_image = image_resource; |
520 queued_operations_.push_back(operation); | 498 queued_operations_.push_back(operation); |
521 return PP_OK; | 499 return PP_OK; |
(...skipping 11 matching lines...) Expand all Loading... |
533 return Flush(NULL); | 511 return Flush(NULL); |
534 | 512 |
535 // Reuse image data when running out of process. | 513 // Reuse image data when running out of process. |
536 int32_t result = Flush(&old_image_data); | 514 int32_t result = Flush(&old_image_data); |
537 | 515 |
538 if (old_image_data) { | 516 if (old_image_data) { |
539 // If the Graphics2D has an old image data it's not using any more, send | 517 // If the Graphics2D has an old image data it's not using any more, send |
540 // it back to the plugin for possible re-use. See ppb_image_data_proxy.cc | 518 // it back to the plugin for possible re-use. See ppb_image_data_proxy.cc |
541 // for a description how this process works. | 519 // for a description how this process works. |
542 ppapi::HostResource old_image_data_host_resource; | 520 ppapi::HostResource old_image_data_host_resource; |
543 old_image_data_host_resource.SetHostResource(pp_instance(), | 521 old_image_data_host_resource.SetHostResource(pp_instance(), old_image_data); |
544 old_image_data); | |
545 host()->Send(new PpapiMsg_PPBImageData_NotifyUnusedImageData( | 522 host()->Send(new PpapiMsg_PPBImageData_NotifyUnusedImageData( |
546 ppapi::API_ID_PPB_IMAGE_DATA, old_image_data_host_resource)); | 523 ppapi::API_ID_PPB_IMAGE_DATA, old_image_data_host_resource)); |
547 } | 524 } |
548 | 525 |
549 return result; | 526 return result; |
550 } | 527 } |
551 | 528 |
552 int32_t PepperGraphics2DHost::OnHostMsgSetScale( | 529 int32_t PepperGraphics2DHost::OnHostMsgSetScale( |
553 ppapi::host::HostMessageContext* context, | 530 ppapi::host::HostMessageContext* context, |
554 float scale) { | 531 float scale) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 switch (operation.type) { | 588 switch (operation.type) { |
612 case QueuedOperation::PAINT: | 589 case QueuedOperation::PAINT: |
613 ExecutePaintImageData(operation.paint_image.get(), | 590 ExecutePaintImageData(operation.paint_image.get(), |
614 operation.paint_x, | 591 operation.paint_x, |
615 operation.paint_y, | 592 operation.paint_y, |
616 operation.paint_src_rect, | 593 operation.paint_src_rect, |
617 &op_rect); | 594 &op_rect); |
618 break; | 595 break; |
619 case QueuedOperation::SCROLL: | 596 case QueuedOperation::SCROLL: |
620 ExecuteScroll(operation.scroll_clip_rect, | 597 ExecuteScroll(operation.scroll_clip_rect, |
621 operation.scroll_dx, operation.scroll_dy, | 598 operation.scroll_dx, |
| 599 operation.scroll_dy, |
622 &op_rect); | 600 &op_rect); |
623 break; | 601 break; |
624 case QueuedOperation::REPLACE: | 602 case QueuedOperation::REPLACE: |
625 // Since the out parameter |old_image_data| takes ownership of the | 603 // Since the out parameter |old_image_data| takes ownership of the |
626 // reference, if there are more than one ReplaceContents calls queued | 604 // reference, if there are more than one ReplaceContents calls queued |
627 // the first |old_image_data| will get overwritten and leaked. So we | 605 // the first |old_image_data| will get overwritten and leaked. So we |
628 // only supply this for the first call. | 606 // only supply this for the first call. |
629 ExecuteReplaceContents(operation.replace_image.get(), | 607 ExecuteReplaceContents(operation.replace_image.get(), |
630 &op_rect, | 608 &op_rect, |
631 done_replace_contents ? NULL : old_image_data); | 609 done_replace_contents ? NULL : old_image_data); |
632 done_replace_contents = true; | 610 done_replace_contents = true; |
633 break; | 611 break; |
634 } | 612 } |
635 | 613 |
636 // For correctness with accelerated compositing, we must issue an invalidate | 614 // For correctness with accelerated compositing, we must issue an invalidate |
637 // on the full op_rect even if it is partially or completely off-screen. | 615 // on the full op_rect even if it is partially or completely off-screen. |
638 // However, if we issue an invalidate for a clipped-out region, WebKit will | 616 // However, if we issue an invalidate for a clipped-out region, WebKit will |
639 // do nothing and we won't get any ViewFlushedPaint calls, leaving our | 617 // do nothing and we won't get any ViewFlushedPaint calls, leaving our |
640 // callback stranded. So we still need to check whether the repainted area | 618 // callback stranded. So we still need to check whether the repainted area |
641 // is visible to determine how to deal with the callback. | 619 // is visible to determine how to deal with the callback. |
642 if (bound_instance_ && !op_rect.IsEmpty()) { | 620 if (bound_instance_ && !op_rect.IsEmpty()) { |
643 gfx::Point scroll_delta(operation.scroll_dx, operation.scroll_dy); | 621 gfx::Point scroll_delta(operation.scroll_dx, operation.scroll_dy); |
644 if (!ConvertToLogicalPixels(scale_, | 622 if (!ConvertToLogicalPixels(scale_, |
645 &op_rect, | 623 &op_rect, |
646 operation.type == QueuedOperation::SCROLL ? | 624 operation.type == QueuedOperation::SCROLL |
647 &scroll_delta : NULL)) { | 625 ? &scroll_delta |
| 626 : NULL)) { |
648 // Conversion requires falling back to InvalidateRect. | 627 // Conversion requires falling back to InvalidateRect. |
649 operation.type = QueuedOperation::PAINT; | 628 operation.type = QueuedOperation::PAINT; |
650 } | 629 } |
651 | 630 |
652 gfx::Rect clip = PP_ToGfxRect(bound_instance_->view_data().clip_rect); | 631 gfx::Rect clip = PP_ToGfxRect(bound_instance_->view_data().clip_rect); |
653 is_plugin_visible = !clip.IsEmpty(); | 632 is_plugin_visible = !clip.IsEmpty(); |
654 | 633 |
655 // Set |no_update_visible| to false if the change overlaps the visible | 634 // Set |no_update_visible| to false if the change overlaps the visible |
656 // area. | 635 // area. |
657 if (!gfx::IntersectRects(clip, op_rect).IsEmpty()) { | 636 if (!gfx::IntersectRects(clip, op_rect).IsEmpty()) { |
658 no_update_visible = false; | 637 no_update_visible = false; |
659 } | 638 } |
660 | 639 |
661 // Notify the plugin of the entire change (op_rect), even if it is | 640 // Notify the plugin of the entire change (op_rect), even if it is |
662 // partially or completely off-screen. | 641 // partially or completely off-screen. |
663 if (operation.type == QueuedOperation::SCROLL) { | 642 if (operation.type == QueuedOperation::SCROLL) { |
664 bound_instance_->ScrollRect(scroll_delta.x(), scroll_delta.y(), | 643 bound_instance_->ScrollRect( |
665 op_rect); | 644 scroll_delta.x(), scroll_delta.y(), op_rect); |
666 } else { | 645 } else { |
667 if (!op_rect.IsEmpty()) | 646 if (!op_rect.IsEmpty()) |
668 bound_instance_->InvalidateRect(op_rect); | 647 bound_instance_->InvalidateRect(op_rect); |
669 } | 648 } |
670 texture_mailbox_modified_ = true; | 649 texture_mailbox_modified_ = true; |
671 } | 650 } |
672 } | 651 } |
673 queued_operations_.clear(); | 652 queued_operations_.clear(); |
674 | 653 |
675 if (!bound_instance_) { | 654 if (!bound_instance_) { |
676 // As promised in the API, we always schedule callback when unbound. | 655 // As promised in the API, we always schedule callback when unbound. |
677 ScheduleOffscreenFlushAck(); | 656 ScheduleOffscreenFlushAck(); |
678 } else if (no_update_visible && is_plugin_visible && | 657 } else if (no_update_visible && is_plugin_visible && |
679 bound_instance_->view_data().is_page_visible) { | 658 bound_instance_->view_data().is_page_visible) { |
680 // There's nothing visible to invalidate so just schedule the callback to | 659 // There's nothing visible to invalidate so just schedule the callback to |
681 // execute in the next round of the message loop. | 660 // execute in the next round of the message loop. |
682 ScheduleOffscreenFlushAck(); | 661 ScheduleOffscreenFlushAck(); |
683 } else { | 662 } else { |
684 need_flush_ack_ = true; | 663 need_flush_ack_ = true; |
685 } | 664 } |
686 | 665 |
687 return PP_OK_COMPLETIONPENDING; | 666 return PP_OK_COMPLETIONPENDING; |
688 } | 667 } |
689 | 668 |
690 void PepperGraphics2DHost::ExecutePaintImageData(PPB_ImageData_Impl* image, | 669 void PepperGraphics2DHost::ExecutePaintImageData(PPB_ImageData_Impl* image, |
691 int x, int y, | 670 int x, |
692 const gfx::Rect& src_rect, | 671 int y, |
693 gfx::Rect* invalidated_rect) { | 672 const gfx::Rect& src_rect, |
| 673 gfx::Rect* invalidated_rect) { |
694 // Ensure the source image is mapped to read from it. | 674 // Ensure the source image is mapped to read from it. |
695 ImageDataAutoMapper auto_mapper(image); | 675 ImageDataAutoMapper auto_mapper(image); |
696 if (!auto_mapper.is_valid()) | 676 if (!auto_mapper.is_valid()) |
697 return; | 677 return; |
698 | 678 |
699 // Portion within the source image to cut out. | 679 // Portion within the source image to cut out. |
700 SkIRect src_irect = { src_rect.x(), src_rect.y(), | 680 SkIRect src_irect = {src_rect.x(), src_rect.y(), src_rect.right(), |
701 src_rect.right(), src_rect.bottom() }; | 681 src_rect.bottom()}; |
702 | 682 |
703 // Location within the backing store to copy to. | 683 // Location within the backing store to copy to. |
704 *invalidated_rect = src_rect; | 684 *invalidated_rect = src_rect; |
705 invalidated_rect->Offset(x, y); | 685 invalidated_rect->Offset(x, y); |
706 SkRect dest_rect = { SkIntToScalar(invalidated_rect->x()), | 686 SkRect dest_rect = {SkIntToScalar(invalidated_rect->x()), |
707 SkIntToScalar(invalidated_rect->y()), | 687 SkIntToScalar(invalidated_rect->y()), |
708 SkIntToScalar(invalidated_rect->right()), | 688 SkIntToScalar(invalidated_rect->right()), |
709 SkIntToScalar(invalidated_rect->bottom()) }; | 689 SkIntToScalar(invalidated_rect->bottom())}; |
710 | 690 |
711 if (image->format() != image_data_->format()) { | 691 if (image->format() != image_data_->format()) { |
712 // Convert the image data if the format does not match. | 692 // Convert the image data if the format does not match. |
713 ConvertImageData(image, src_irect, image_data_.get(), dest_rect); | 693 ConvertImageData(image, src_irect, image_data_.get(), dest_rect); |
714 } else { | 694 } else { |
715 // We're guaranteed to have a mapped canvas since we mapped it in Init(). | 695 // We're guaranteed to have a mapped canvas since we mapped it in Init(). |
716 SkCanvas* backing_canvas = image_data_->GetCanvas(); | 696 SkCanvas* backing_canvas = image_data_->GetCanvas(); |
717 | 697 |
718 // We want to replace the contents of the bitmap rather than blend. | 698 // We want to replace the contents of the bitmap rather than blend. |
719 SkPaint paint; | 699 SkPaint paint; |
720 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 700 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
721 backing_canvas->drawBitmapRect(*image->GetMappedBitmap(), | 701 backing_canvas->drawBitmapRect( |
722 &src_irect, dest_rect, &paint); | 702 *image->GetMappedBitmap(), &src_irect, dest_rect, &paint); |
723 } | 703 } |
724 } | 704 } |
725 | 705 |
726 void PepperGraphics2DHost::ExecuteScroll(const gfx::Rect& clip, | 706 void PepperGraphics2DHost::ExecuteScroll(const gfx::Rect& clip, |
727 int dx, int dy, | 707 int dx, |
728 gfx::Rect* invalidated_rect) { | 708 int dy, |
729 gfx::ScrollCanvas(image_data_->GetCanvas(), | 709 gfx::Rect* invalidated_rect) { |
730 clip, gfx::Vector2d(dx, dy)); | 710 gfx::ScrollCanvas(image_data_->GetCanvas(), clip, gfx::Vector2d(dx, dy)); |
731 *invalidated_rect = clip; | 711 *invalidated_rect = clip; |
732 } | 712 } |
733 | 713 |
734 void PepperGraphics2DHost::ExecuteReplaceContents(PPB_ImageData_Impl* image, | 714 void PepperGraphics2DHost::ExecuteReplaceContents(PPB_ImageData_Impl* image, |
735 gfx::Rect* invalidated_rect, | 715 gfx::Rect* invalidated_rect, |
736 PP_Resource* old_image_data) { | 716 PP_Resource* old_image_data) { |
737 if (image->format() != image_data_->format()) { | 717 if (image->format() != image_data_->format()) { |
738 DCHECK(image->width() == image_data_->width() && | 718 DCHECK(image->width() == image_data_->width() && |
739 image->height() == image_data_->height()); | 719 image->height() == image_data_->height()); |
740 // Convert the image data if the format does not match. | 720 // Convert the image data if the format does not match. |
741 SkIRect src_irect = { 0, 0, image->width(), image->height() }; | 721 SkIRect src_irect = {0, 0, image->width(), image->height()}; |
742 SkRect dest_rect = { SkIntToScalar(0), | 722 SkRect dest_rect = {SkIntToScalar(0), SkIntToScalar(0), |
743 SkIntToScalar(0), | 723 SkIntToScalar(image_data_->width()), |
744 SkIntToScalar(image_data_->width()), | 724 SkIntToScalar(image_data_->height())}; |
745 SkIntToScalar(image_data_->height()) }; | |
746 ConvertImageData(image, src_irect, image_data_.get(), dest_rect); | 725 ConvertImageData(image, src_irect, image_data_.get(), dest_rect); |
747 } else { | 726 } else { |
748 // The passed-in image may not be mapped in our process, and we need to | 727 // The passed-in image may not be mapped in our process, and we need to |
749 // guarantee that the current backing store is always mapped. | 728 // guarantee that the current backing store is always mapped. |
750 if (!image->Map()) | 729 if (!image->Map()) |
751 return; | 730 return; |
752 | 731 |
753 if (old_image_data) | 732 if (old_image_data) |
754 *old_image_data = image_data_->GetReference(); | 733 *old_image_data = image_data_->GetReference(); |
755 image_data_ = image; | 734 image_data_ = image; |
756 } | 735 } |
757 *invalidated_rect = gfx::Rect(0, 0, | 736 *invalidated_rect = |
758 image_data_->width(), image_data_->height()); | 737 gfx::Rect(0, 0, image_data_->width(), image_data_->height()); |
759 } | 738 } |
760 | 739 |
761 void PepperGraphics2DHost::SendFlushAck() { | 740 void PepperGraphics2DHost::SendFlushAck() { |
762 host()->SendReply(flush_reply_context_, | 741 host()->SendReply(flush_reply_context_, PpapiPluginMsg_Graphics2D_FlushAck()); |
763 PpapiPluginMsg_Graphics2D_FlushAck()); | |
764 } | 742 } |
765 | 743 |
766 void PepperGraphics2DHost::SendOffscreenFlushAck() { | 744 void PepperGraphics2DHost::SendOffscreenFlushAck() { |
767 DCHECK(offscreen_flush_pending_); | 745 DCHECK(offscreen_flush_pending_); |
768 | 746 |
769 // We must clear this flag before issuing the callback. It will be | 747 // We must clear this flag before issuing the callback. It will be |
770 // common for the plugin to issue another invalidate in response to a flush | 748 // common for the plugin to issue another invalidate in response to a flush |
771 // callback, and we don't want to think that a callback is already pending. | 749 // callback, and we don't want to think that a callback is already pending. |
772 offscreen_flush_pending_ = false; | 750 offscreen_flush_pending_ = false; |
773 SendFlushAck(); | 751 SendFlushAck(); |
774 } | 752 } |
775 | 753 |
776 void PepperGraphics2DHost::ScheduleOffscreenFlushAck() { | 754 void PepperGraphics2DHost::ScheduleOffscreenFlushAck() { |
777 offscreen_flush_pending_ = true; | 755 offscreen_flush_pending_ = true; |
778 base::MessageLoop::current()->PostDelayedTask( | 756 base::MessageLoop::current()->PostDelayedTask( |
779 FROM_HERE, | 757 FROM_HERE, |
780 base::Bind(&PepperGraphics2DHost::SendOffscreenFlushAck, | 758 base::Bind(&PepperGraphics2DHost::SendOffscreenFlushAck, AsWeakPtr()), |
781 AsWeakPtr()), | |
782 base::TimeDelta::FromMilliseconds(kOffscreenCallbackDelayMs)); | 759 base::TimeDelta::FromMilliseconds(kOffscreenCallbackDelayMs)); |
783 } | 760 } |
784 | 761 |
785 bool PepperGraphics2DHost::HasPendingFlush() const { | 762 bool PepperGraphics2DHost::HasPendingFlush() const { |
786 return need_flush_ack_ || offscreen_flush_pending_; | 763 return need_flush_ack_ || offscreen_flush_pending_; |
787 } | 764 } |
788 | 765 |
789 // static | 766 // static |
790 bool PepperGraphics2DHost::ConvertToLogicalPixels(float scale, | 767 bool PepperGraphics2DHost::ConvertToLogicalPixels(float scale, |
791 gfx::Rect* op_rect, | 768 gfx::Rect* op_rect, |
792 gfx::Point* delta) { | 769 gfx::Point* delta) { |
793 if (scale == 1.0f || scale <= 0.0f) | 770 if (scale == 1.0f || scale <= 0.0f) |
794 return true; | 771 return true; |
795 | 772 |
796 gfx::Rect original_rect = *op_rect; | 773 gfx::Rect original_rect = *op_rect; |
797 // Take the enclosing rectangle after scaling so a rectangle scaled down then | 774 // Take the enclosing rectangle after scaling so a rectangle scaled down then |
798 // scaled back up by the inverse scale would fully contain the entire area | 775 // scaled back up by the inverse scale would fully contain the entire area |
799 // affected by the original rectangle. | 776 // affected by the original rectangle. |
800 *op_rect = gfx::ToEnclosingRect(gfx::ScaleRect(*op_rect, scale)); | 777 *op_rect = gfx::ToEnclosingRect(gfx::ScaleRect(*op_rect, scale)); |
801 if (delta) { | 778 if (delta) { |
802 gfx::Point original_delta = *delta; | 779 gfx::Point original_delta = *delta; |
803 float inverse_scale = 1.0f / scale; | 780 float inverse_scale = 1.0f / scale; |
804 *delta = gfx::ToFlooredPoint(gfx::ScalePoint(*delta, scale)); | 781 *delta = gfx::ToFlooredPoint(gfx::ScalePoint(*delta, scale)); |
805 | 782 |
806 gfx::Rect inverse_scaled_rect = | 783 gfx::Rect inverse_scaled_rect = |
807 gfx::ToEnclosingRect(gfx::ScaleRect(*op_rect, inverse_scale)); | 784 gfx::ToEnclosingRect(gfx::ScaleRect(*op_rect, inverse_scale)); |
808 if (original_rect != inverse_scaled_rect) | 785 if (original_rect != inverse_scaled_rect) |
809 return false; | 786 return false; |
810 gfx::Point inverse_scaled_point = | 787 gfx::Point inverse_scaled_point = |
811 gfx::ToFlooredPoint(gfx::ScalePoint(*delta, inverse_scale)); | 788 gfx::ToFlooredPoint(gfx::ScalePoint(*delta, inverse_scale)); |
812 if (original_delta != inverse_scaled_point) | 789 if (original_delta != inverse_scaled_point) |
813 return false; | 790 return false; |
814 } | 791 } |
815 | 792 |
816 return true; | 793 return true; |
817 } | 794 } |
818 | 795 |
819 } // namespace content | 796 } // namespace content |
OLD | NEW |