OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "webkit/glue/plugins/pepper_device_context_2d.h" | 5 #include "webkit/glue/plugins/pepper_device_context_2d.h" |
6 | 6 |
7 #include <iterator> | 7 #include <iterator> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 static_cast<int64>(rect->size.height) > | 55 static_cast<int64>(rect->size.height) > |
56 static_cast<int64>(image_height)) | 56 static_cast<int64>(image_height)) |
57 return false; | 57 return false; |
58 | 58 |
59 *dest = gfx::Rect(rect->point.x, rect->point.y, | 59 *dest = gfx::Rect(rect->point.x, rect->point.y, |
60 rect->size.width, rect->size.height); | 60 rect->size.width, rect->size.height); |
61 } | 61 } |
62 return true; | 62 return true; |
63 } | 63 } |
64 | 64 |
65 PP_Resource Create(PP_Module module_id, int32_t width, int32_t height, | 65 PP_Resource Create(PP_Module module_id, |
| 66 const PP_Size* size, |
66 bool is_always_opaque) { | 67 bool is_always_opaque) { |
67 PluginModule* module = PluginModule::FromPPModule(module_id); | 68 PluginModule* module = PluginModule::FromPPModule(module_id); |
68 if (!module) | 69 if (!module) |
69 return NULL; | 70 return NULL; |
70 | 71 |
71 scoped_refptr<DeviceContext2D> context(new DeviceContext2D(module)); | 72 scoped_refptr<DeviceContext2D> context(new DeviceContext2D(module)); |
72 if (!context->Init(width, height, is_always_opaque)) | 73 if (!context->Init(size->width, size->height, is_always_opaque)) |
73 return NULL; | 74 return NULL; |
74 context->AddRef(); // AddRef for the caller. | 75 context->AddRef(); // AddRef for the caller. |
75 return context->GetResource(); | 76 return context->GetResource(); |
76 } | 77 } |
77 | 78 |
78 bool IsDeviceContext2D(PP_Resource resource) { | 79 bool IsDeviceContext2D(PP_Resource resource) { |
79 scoped_refptr<DeviceContext2D> context( | 80 scoped_refptr<DeviceContext2D> context( |
80 Resource::GetAs<DeviceContext2D>(resource)); | 81 Resource::GetAs<DeviceContext2D>(resource)); |
81 return !!context.get(); | 82 return !!context.get(); |
82 } | 83 } |
83 | 84 |
84 bool Describe(PP_Resource device_context, | 85 bool Describe(PP_Resource device_context, |
85 int32_t* width, int32_t* height, bool* is_always_opaque) { | 86 PP_Size* size, |
| 87 bool* is_always_opaque) { |
86 scoped_refptr<DeviceContext2D> context( | 88 scoped_refptr<DeviceContext2D> context( |
87 Resource::GetAs<DeviceContext2D>(device_context)); | 89 Resource::GetAs<DeviceContext2D>(device_context)); |
88 if (!context.get()) | 90 if (!context.get()) |
89 return false; | 91 return false; |
90 return context->Describe(width, height, is_always_opaque); | 92 return context->Describe(size, is_always_opaque); |
91 } | 93 } |
92 | 94 |
93 bool PaintImageData(PP_Resource device_context, | 95 bool PaintImageData(PP_Resource device_context, |
94 PP_Resource image, | 96 PP_Resource image, |
95 int32_t x, int32_t y, | 97 const PP_Point* top_left, |
96 const PP_Rect* src_rect) { | 98 const PP_Rect* src_rect) { |
97 scoped_refptr<DeviceContext2D> context( | 99 scoped_refptr<DeviceContext2D> context( |
98 Resource::GetAs<DeviceContext2D>(device_context)); | 100 Resource::GetAs<DeviceContext2D>(device_context)); |
99 if (!context.get()) | 101 if (!context.get()) |
100 return false; | 102 return false; |
101 return context->PaintImageData(image, x, y, src_rect); | 103 return context->PaintImageData(image, top_left, src_rect); |
102 } | 104 } |
103 | 105 |
104 bool Scroll(PP_Resource device_context, | 106 bool Scroll(PP_Resource device_context, |
105 const PP_Rect* clip_rect, | 107 const PP_Rect* clip_rect, |
106 int32_t dx, int32_t dy) { | 108 const PP_Point* amount) { |
107 scoped_refptr<DeviceContext2D> context( | 109 scoped_refptr<DeviceContext2D> context( |
108 Resource::GetAs<DeviceContext2D>(device_context)); | 110 Resource::GetAs<DeviceContext2D>(device_context)); |
109 if (!context.get()) | 111 if (!context.get()) |
110 return false; | 112 return false; |
111 return context->Scroll(clip_rect, dx, dy); | 113 return context->Scroll(clip_rect, amount); |
112 } | 114 } |
113 | 115 |
114 bool ReplaceContents(PP_Resource device_context, PP_Resource image) { | 116 bool ReplaceContents(PP_Resource device_context, PP_Resource image) { |
115 scoped_refptr<DeviceContext2D> context( | 117 scoped_refptr<DeviceContext2D> context( |
116 Resource::GetAs<DeviceContext2D>(device_context)); | 118 Resource::GetAs<DeviceContext2D>(device_context)); |
117 if (!context.get()) | 119 if (!context.get()) |
118 return false; | 120 return false; |
119 return context->ReplaceContents(image); | 121 return context->ReplaceContents(image); |
120 } | 122 } |
121 | 123 |
122 int32_t Flush(PP_Resource device_context, | 124 int32_t Flush(PP_Resource device_context, |
123 PP_CompletionCallback callback) { | 125 PP_CompletionCallback callback) { |
124 scoped_refptr<DeviceContext2D> context( | 126 scoped_refptr<DeviceContext2D> context( |
125 Resource::GetAs<DeviceContext2D>(device_context)); | 127 Resource::GetAs<DeviceContext2D>(device_context)); |
126 if (!context.get()) | 128 if (!context.get()) |
127 return PP_Error_BadResource; | 129 return PP_ERROR_BADRESOURCE; |
128 return context->Flush(callback); | 130 return context->Flush(callback); |
129 } | 131 } |
130 | 132 |
131 const PPB_DeviceContext2D ppb_devicecontext2d = { | 133 const PPB_DeviceContext2D ppb_devicecontext2d = { |
132 &Create, | 134 &Create, |
133 &IsDeviceContext2D, | 135 &IsDeviceContext2D, |
134 &Describe, | 136 &Describe, |
135 &PaintImageData, | 137 &PaintImageData, |
136 &Scroll, | 138 &Scroll, |
137 &ReplaceContents, | 139 &ReplaceContents, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 image_data_ = new ImageData(module()); | 192 image_data_ = new ImageData(module()); |
191 if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height, true) || | 193 if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height, true) || |
192 !image_data_->Map()) { | 194 !image_data_->Map()) { |
193 image_data_ = NULL; | 195 image_data_ = NULL; |
194 return false; | 196 return false; |
195 } | 197 } |
196 | 198 |
197 return true; | 199 return true; |
198 } | 200 } |
199 | 201 |
200 bool DeviceContext2D::Describe(int32_t* width, int32_t* height, | 202 bool DeviceContext2D::Describe(PP_Size* size, bool* is_always_opaque) { |
201 bool* is_always_opaque) { | 203 if (!size || !is_always_opaque) |
202 *width = image_data_->width(); | 204 return false; |
203 *height = image_data_->height(); | 205 |
| 206 size->width = image_data_->width(); |
| 207 size->height = image_data_->height(); |
204 *is_always_opaque = false; // TODO(brettw) implement this. | 208 *is_always_opaque = false; // TODO(brettw) implement this. |
205 return true; | 209 return true; |
206 } | 210 } |
207 | 211 |
208 bool DeviceContext2D::PaintImageData(PP_Resource image, | 212 bool DeviceContext2D::PaintImageData(PP_Resource image, |
209 int32_t x, int32_t y, | 213 const PP_Point* top_left, |
210 const PP_Rect* src_rect) { | 214 const PP_Rect* src_rect) { |
| 215 if (!top_left) |
| 216 return false; |
| 217 |
211 scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); | 218 scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); |
212 if (!image_resource.get()) | 219 if (!image_resource.get()) |
213 return false; | 220 return false; |
214 | 221 |
215 QueuedOperation operation(QueuedOperation::PAINT); | 222 QueuedOperation operation(QueuedOperation::PAINT); |
216 operation.paint_image = image_resource; | 223 operation.paint_image = image_resource; |
217 if (!ValidateAndConvertRect(src_rect, image_resource->width(), | 224 if (!ValidateAndConvertRect(src_rect, image_resource->width(), |
218 image_resource->height(), | 225 image_resource->height(), |
219 &operation.paint_src_rect)) | 226 &operation.paint_src_rect)) |
220 return false; | 227 return false; |
221 | 228 |
222 // Validate the bitmap position using the previously-validated rect, there | 229 // Validate the bitmap position using the previously-validated rect, there |
223 // should be no painted area outside of the image. | 230 // should be no painted area outside of the image. |
224 int64 x64 = static_cast<int64>(x), y64 = static_cast<int64>(y); | 231 int64 x64 = static_cast<int64>(top_left->x); |
| 232 int64 y64 = static_cast<int64>(top_left->y); |
225 if (x64 + static_cast<int64>(operation.paint_src_rect.x()) < 0 || | 233 if (x64 + static_cast<int64>(operation.paint_src_rect.x()) < 0 || |
226 x64 + static_cast<int64>(operation.paint_src_rect.right()) > | 234 x64 + static_cast<int64>(operation.paint_src_rect.right()) > |
227 image_data_->width()) | 235 image_data_->width()) |
228 return false; | 236 return false; |
229 if (y64 + static_cast<int64>(operation.paint_src_rect.y()) < 0 || | 237 if (y64 + static_cast<int64>(operation.paint_src_rect.y()) < 0 || |
230 y64 + static_cast<int64>(operation.paint_src_rect.bottom()) > | 238 y64 + static_cast<int64>(operation.paint_src_rect.bottom()) > |
231 image_data_->height()) | 239 image_data_->height()) |
232 return false; | 240 return false; |
233 operation.paint_x = x; | 241 operation.paint_x = top_left->x; |
234 operation.paint_y = y; | 242 operation.paint_y = top_left->y; |
235 | 243 |
236 queued_operations_.push_back(operation); | 244 queued_operations_.push_back(operation); |
237 return true; | 245 return true; |
238 } | 246 } |
239 | 247 |
240 bool DeviceContext2D::Scroll(const PP_Rect* clip_rect, | 248 bool DeviceContext2D::Scroll(const PP_Rect* clip_rect, |
241 int32_t dx, int32_t dy) { | 249 const PP_Point* amount) { |
| 250 if (!amount) |
| 251 return false; |
242 QueuedOperation operation(QueuedOperation::SCROLL); | 252 QueuedOperation operation(QueuedOperation::SCROLL); |
243 if (!ValidateAndConvertRect(clip_rect, | 253 if (!ValidateAndConvertRect(clip_rect, |
244 image_data_->width(), | 254 image_data_->width(), |
245 image_data_->height(), | 255 image_data_->height(), |
246 &operation.scroll_clip_rect)) | 256 &operation.scroll_clip_rect)) |
247 return false; | 257 return false; |
248 | 258 |
249 // If we're being asked to scroll by more than the clip rect size, just | 259 // If we're being asked to scroll by more than the clip rect size, just |
250 // ignore this scroll command and say it worked. | 260 // ignore this scroll command and say it worked. |
| 261 int32 dx = amount->x; |
| 262 int32 dy = amount->y; |
251 if (dx <= -image_data_->width() || dx >= image_data_->width() || | 263 if (dx <= -image_data_->width() || dx >= image_data_->width() || |
252 dx <= -image_data_->height() || dy >= image_data_->height()) | 264 dx <= -image_data_->height() || dy >= image_data_->height()) |
253 return true; | 265 return true; |
254 | 266 |
255 operation.scroll_dx = dx; | 267 operation.scroll_dx = dx; |
256 operation.scroll_dy = dy; | 268 operation.scroll_dy = dy; |
257 | 269 |
258 queued_operations_.push_back(operation); | 270 queued_operations_.push_back(operation); |
259 return false; | 271 return false; |
260 } | 272 } |
(...skipping 12 matching lines...) Expand all Loading... |
273 QueuedOperation operation(QueuedOperation::REPLACE); | 285 QueuedOperation operation(QueuedOperation::REPLACE); |
274 operation.replace_image = image_resource; | 286 operation.replace_image = image_resource; |
275 queued_operations_.push_back(operation); | 287 queued_operations_.push_back(operation); |
276 | 288 |
277 return true; | 289 return true; |
278 } | 290 } |
279 | 291 |
280 int32_t DeviceContext2D::Flush(const PP_CompletionCallback& callback) { | 292 int32_t DeviceContext2D::Flush(const PP_CompletionCallback& callback) { |
281 // Don't allow more than one pending flush at a time. | 293 // Don't allow more than one pending flush at a time. |
282 if (HasPendingFlush()) | 294 if (HasPendingFlush()) |
283 return PP_Error_InProgress; | 295 return PP_ERROR_INPROGRESS; |
284 | 296 |
285 // TODO(brettw) check that the current thread is not the main one and | 297 // TODO(brettw) check that the current thread is not the main one and |
286 // implement blocking flushes in this case. | 298 // implement blocking flushes in this case. |
287 if (!callback.func) | 299 if (!callback.func) |
288 return PP_Error_BadArgument; | 300 return PP_ERROR_BADARGUMENT; |
289 | 301 |
290 gfx::Rect changed_rect; | 302 gfx::Rect changed_rect; |
291 for (size_t i = 0; i < queued_operations_.size(); i++) { | 303 for (size_t i = 0; i < queued_operations_.size(); i++) { |
292 QueuedOperation& operation = queued_operations_[i]; | 304 QueuedOperation& operation = queued_operations_[i]; |
293 gfx::Rect op_rect; | 305 gfx::Rect op_rect; |
294 switch (operation.type) { | 306 switch (operation.type) { |
295 case QueuedOperation::PAINT: | 307 case QueuedOperation::PAINT: |
296 ExecutePaintImageData(operation.paint_image.get(), | 308 ExecutePaintImageData(operation.paint_image.get(), |
297 operation.paint_x, operation.paint_y, | 309 operation.paint_x, operation.paint_y, |
298 operation.paint_src_rect, | 310 operation.paint_src_rect, |
(...skipping 22 matching lines...) Expand all Loading... |
321 visible_changed_rect = bound_instance_->clip().Intersect(changed_rect); | 333 visible_changed_rect = bound_instance_->clip().Intersect(changed_rect); |
322 | 334 |
323 if (bound_instance_ && !visible_changed_rect.IsEmpty()) { | 335 if (bound_instance_ && !visible_changed_rect.IsEmpty()) { |
324 unpainted_flush_callback_.Set(callback); | 336 unpainted_flush_callback_.Set(callback); |
325 bound_instance_->InvalidateRect(visible_changed_rect); | 337 bound_instance_->InvalidateRect(visible_changed_rect); |
326 } else { | 338 } else { |
327 // There's nothing visible to invalidate so just schedule the callback to | 339 // There's nothing visible to invalidate so just schedule the callback to |
328 // execute in the next round of the message loop. | 340 // execute in the next round of the message loop. |
329 ScheduleOffscreenCallback(FlushCallbackData(callback)); | 341 ScheduleOffscreenCallback(FlushCallbackData(callback)); |
330 } | 342 } |
331 return PP_Error_WouldBlock; | 343 return PP_ERROR_WOULDBLOCK; |
332 } | 344 } |
333 | 345 |
334 bool DeviceContext2D::ReadImageData(PP_Resource image, int32_t x, int32_t y) { | 346 bool DeviceContext2D::ReadImageData(PP_Resource image, |
| 347 const PP_Point* top_left) { |
335 // Get and validate the image object to paint into. | 348 // Get and validate the image object to paint into. |
336 scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); | 349 scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); |
337 if (!image_resource.get()) | 350 if (!image_resource.get()) |
338 return false; | 351 return false; |
339 if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) | 352 if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) |
340 return false; // Must be in the right format. | 353 return false; // Must be in the right format. |
341 | 354 |
342 // Validate the bitmap position. | 355 // Validate the bitmap position. |
| 356 if (!top_left) |
| 357 return false; |
| 358 int x = top_left->x; |
343 if (x < 0 || | 359 if (x < 0 || |
344 static_cast<int64>(x) + static_cast<int64>(image_resource->width()) > | 360 static_cast<int64>(x) + static_cast<int64>(image_resource->width()) > |
345 image_data_->width()) | 361 image_data_->width()) |
346 return false; | 362 return false; |
| 363 int y = top_left->y; |
347 if (y < 0 || | 364 if (y < 0 || |
348 static_cast<int64>(y) + static_cast<int64>(image_resource->height()) > | 365 static_cast<int64>(y) + static_cast<int64>(image_resource->height()) > |
349 image_data_->height()) | 366 image_data_->height()) |
350 return false; | 367 return false; |
351 | 368 |
352 ImageDataAutoMapper auto_mapper(image_resource.get()); | 369 ImageDataAutoMapper auto_mapper(image_resource.get()); |
353 if (!auto_mapper.is_valid()) | 370 if (!auto_mapper.is_valid()) |
354 return false; | 371 return false; |
355 skia::PlatformCanvas* dest_canvas = image_resource->mapped_canvas(); | 372 skia::PlatformCanvas* dest_canvas = image_resource->mapped_canvas(); |
356 | 373 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 data.Execute(PP_OK); | 551 data.Execute(PP_OK); |
535 } | 552 } |
536 | 553 |
537 bool DeviceContext2D::HasPendingFlush() const { | 554 bool DeviceContext2D::HasPendingFlush() const { |
538 return !unpainted_flush_callback_.is_null() || | 555 return !unpainted_flush_callback_.is_null() || |
539 !painted_flush_callback_.is_null() || | 556 !painted_flush_callback_.is_null() || |
540 offscreen_flush_pending_; | 557 offscreen_flush_pending_; |
541 } | 558 } |
542 | 559 |
543 } // namespace pepper | 560 } // namespace pepper |
OLD | NEW |