| 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 |