| 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_graphics_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" |
| 11 #include "base/task.h" | 11 #include "base/task.h" |
| 12 #include "gfx/blit.h" | 12 #include "gfx/blit.h" |
| 13 #include "gfx/point.h" | 13 #include "gfx/point.h" |
| 14 #include "gfx/rect.h" | 14 #include "gfx/rect.h" |
| 15 #include "skia/ext/platform_canvas.h" | 15 #include "skia/ext/platform_canvas.h" |
| 16 #include "third_party/ppapi/c/pp_errors.h" | 16 #include "third_party/ppapi/c/pp_errors.h" |
| 17 #include "third_party/ppapi/c/pp_module.h" | 17 #include "third_party/ppapi/c/pp_module.h" |
| 18 #include "third_party/ppapi/c/pp_rect.h" | 18 #include "third_party/ppapi/c/pp_rect.h" |
| 19 #include "third_party/ppapi/c/pp_resource.h" | 19 #include "third_party/ppapi/c/pp_resource.h" |
| 20 #include "third_party/ppapi/c/ppb_device_context_2d.h" | 20 #include "third_party/ppapi/c/ppb_graphics_2d.h" |
| 21 #include "third_party/skia/include/core/SkBitmap.h" | 21 #include "third_party/skia/include/core/SkBitmap.h" |
| 22 #include "webkit/glue/plugins/pepper_image_data.h" | 22 #include "webkit/glue/plugins/pepper_image_data.h" |
| 23 #include "webkit/glue/plugins/pepper_plugin_instance.h" | 23 #include "webkit/glue/plugins/pepper_plugin_instance.h" |
| 24 #include "webkit/glue/plugins/pepper_plugin_module.h" | 24 #include "webkit/glue/plugins/pepper_plugin_module.h" |
| 25 | 25 |
| 26 #if defined(OS_MACOSX) | 26 #if defined(OS_MACOSX) |
| 27 #include "base/mac_util.h" | 27 #include "base/mac_util.h" |
| 28 #include "base/scoped_cftyperef.h" | 28 #include "base/scoped_cftyperef.h" |
| 29 #endif | 29 #endif |
| 30 | 30 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 return true; | 63 return true; |
| 64 } | 64 } |
| 65 | 65 |
| 66 PP_Resource Create(PP_Module module_id, | 66 PP_Resource Create(PP_Module module_id, |
| 67 const PP_Size* size, | 67 const PP_Size* size, |
| 68 bool is_always_opaque) { | 68 bool is_always_opaque) { |
| 69 PluginModule* module = PluginModule::FromPPModule(module_id); | 69 PluginModule* module = PluginModule::FromPPModule(module_id); |
| 70 if (!module) | 70 if (!module) |
| 71 return 0; | 71 return 0; |
| 72 | 72 |
| 73 scoped_refptr<DeviceContext2D> context(new DeviceContext2D(module)); | 73 scoped_refptr<Graphics2D> context(new Graphics2D(module)); |
| 74 if (!context->Init(size->width, size->height, is_always_opaque)) | 74 if (!context->Init(size->width, size->height, is_always_opaque)) |
| 75 return 0; | 75 return 0; |
| 76 return context->GetReference(); | 76 return context->GetReference(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 bool IsDeviceContext2D(PP_Resource resource) { | 79 bool IsGraphics2D(PP_Resource resource) { |
| 80 return !!Resource::GetAs<DeviceContext2D>(resource); | 80 return !!Resource::GetAs<Graphics2D>(resource); |
| 81 } | 81 } |
| 82 | 82 |
| 83 bool Describe(PP_Resource device_context, | 83 bool Describe(PP_Resource device_context, |
| 84 PP_Size* size, | 84 PP_Size* size, |
| 85 bool* is_always_opaque) { | 85 bool* is_always_opaque) { |
| 86 scoped_refptr<DeviceContext2D> context( | 86 scoped_refptr<Graphics2D> context( |
| 87 Resource::GetAs<DeviceContext2D>(device_context)); | 87 Resource::GetAs<Graphics2D>(device_context)); |
| 88 if (!context) | 88 if (!context) |
| 89 return false; | 89 return false; |
| 90 return context->Describe(size, is_always_opaque); | 90 return context->Describe(size, is_always_opaque); |
| 91 } | 91 } |
| 92 | 92 |
| 93 bool PaintImageData(PP_Resource device_context, | 93 bool PaintImageData(PP_Resource device_context, |
| 94 PP_Resource image, | 94 PP_Resource image, |
| 95 const PP_Point* top_left, | 95 const PP_Point* top_left, |
| 96 const PP_Rect* src_rect) { | 96 const PP_Rect* src_rect) { |
| 97 scoped_refptr<DeviceContext2D> context( | 97 scoped_refptr<Graphics2D> context( |
| 98 Resource::GetAs<DeviceContext2D>(device_context)); | 98 Resource::GetAs<Graphics2D>(device_context)); |
| 99 if (!context) | 99 if (!context) |
| 100 return false; | 100 return false; |
| 101 return context->PaintImageData(image, top_left, src_rect); | 101 return context->PaintImageData(image, top_left, src_rect); |
| 102 } | 102 } |
| 103 | 103 |
| 104 bool Scroll(PP_Resource device_context, | 104 bool Scroll(PP_Resource device_context, |
| 105 const PP_Rect* clip_rect, | 105 const PP_Rect* clip_rect, |
| 106 const PP_Point* amount) { | 106 const PP_Point* amount) { |
| 107 scoped_refptr<DeviceContext2D> context( | 107 scoped_refptr<Graphics2D> context( |
| 108 Resource::GetAs<DeviceContext2D>(device_context)); | 108 Resource::GetAs<Graphics2D>(device_context)); |
| 109 if (!context) | 109 if (!context) |
| 110 return false; | 110 return false; |
| 111 return context->Scroll(clip_rect, amount); | 111 return context->Scroll(clip_rect, amount); |
| 112 } | 112 } |
| 113 | 113 |
| 114 bool ReplaceContents(PP_Resource device_context, PP_Resource image) { | 114 bool ReplaceContents(PP_Resource device_context, PP_Resource image) { |
| 115 scoped_refptr<DeviceContext2D> context( | 115 scoped_refptr<Graphics2D> context( |
| 116 Resource::GetAs<DeviceContext2D>(device_context)); | 116 Resource::GetAs<Graphics2D>(device_context)); |
| 117 if (!context) | 117 if (!context) |
| 118 return false; | 118 return false; |
| 119 return context->ReplaceContents(image); | 119 return context->ReplaceContents(image); |
| 120 } | 120 } |
| 121 | 121 |
| 122 int32_t Flush(PP_Resource device_context, | 122 int32_t Flush(PP_Resource device_context, |
| 123 PP_CompletionCallback callback) { | 123 PP_CompletionCallback callback) { |
| 124 scoped_refptr<DeviceContext2D> context( | 124 scoped_refptr<Graphics2D> context( |
| 125 Resource::GetAs<DeviceContext2D>(device_context)); | 125 Resource::GetAs<Graphics2D>(device_context)); |
| 126 if (!context) | 126 if (!context) |
| 127 return PP_ERROR_BADRESOURCE; | 127 return PP_ERROR_BADRESOURCE; |
| 128 return context->Flush(callback); | 128 return context->Flush(callback); |
| 129 } | 129 } |
| 130 | 130 |
| 131 const PPB_DeviceContext2D ppb_devicecontext2d = { | 131 const PPB_Graphics2D ppb_graphics_2d = { |
| 132 &Create, | 132 &Create, |
| 133 &IsDeviceContext2D, | 133 &IsGraphics2D, |
| 134 &Describe, | 134 &Describe, |
| 135 &PaintImageData, | 135 &PaintImageData, |
| 136 &Scroll, | 136 &Scroll, |
| 137 &ReplaceContents, | 137 &ReplaceContents, |
| 138 &Flush | 138 &Flush |
| 139 }; | 139 }; |
| 140 | 140 |
| 141 } // namespace | 141 } // namespace |
| 142 | 142 |
| 143 struct DeviceContext2D::QueuedOperation { | 143 struct Graphics2D::QueuedOperation { |
| 144 enum Type { | 144 enum Type { |
| 145 PAINT, | 145 PAINT, |
| 146 SCROLL, | 146 SCROLL, |
| 147 REPLACE | 147 REPLACE |
| 148 }; | 148 }; |
| 149 | 149 |
| 150 QueuedOperation(Type t) | 150 QueuedOperation(Type t) |
| 151 : type(t), | 151 : type(t), |
| 152 paint_x(0), | 152 paint_x(0), |
| 153 paint_y(0), | 153 paint_y(0), |
| 154 scroll_dx(0), | 154 scroll_dx(0), |
| 155 scroll_dy(0) { | 155 scroll_dy(0) { |
| 156 } | 156 } |
| 157 | 157 |
| 158 Type type; | 158 Type type; |
| 159 | 159 |
| 160 // Valid when type == PAINT. | 160 // Valid when type == PAINT. |
| 161 scoped_refptr<ImageData> paint_image; | 161 scoped_refptr<ImageData> paint_image; |
| 162 int paint_x, paint_y; | 162 int paint_x, paint_y; |
| 163 gfx::Rect paint_src_rect; | 163 gfx::Rect paint_src_rect; |
| 164 | 164 |
| 165 // Valid when type == SCROLL. | 165 // Valid when type == SCROLL. |
| 166 gfx::Rect scroll_clip_rect; | 166 gfx::Rect scroll_clip_rect; |
| 167 int scroll_dx, scroll_dy; | 167 int scroll_dx, scroll_dy; |
| 168 | 168 |
| 169 // Valid when type == REPLACE. | 169 // Valid when type == REPLACE. |
| 170 scoped_refptr<ImageData> replace_image; | 170 scoped_refptr<ImageData> replace_image; |
| 171 }; | 171 }; |
| 172 | 172 |
| 173 DeviceContext2D::DeviceContext2D(PluginModule* module) | 173 Graphics2D::Graphics2D(PluginModule* module) |
| 174 : Resource(module), | 174 : Resource(module), |
| 175 bound_instance_(NULL), | 175 bound_instance_(NULL), |
| 176 flushed_any_data_(false), | 176 flushed_any_data_(false), |
| 177 offscreen_flush_pending_(false) { | 177 offscreen_flush_pending_(false) { |
| 178 } | 178 } |
| 179 | 179 |
| 180 DeviceContext2D::~DeviceContext2D() { | 180 Graphics2D::~Graphics2D() { |
| 181 } | 181 } |
| 182 | 182 |
| 183 // static | 183 // static |
| 184 const PPB_DeviceContext2D* DeviceContext2D::GetInterface() { | 184 const PPB_Graphics2D* Graphics2D::GetInterface() { |
| 185 return &ppb_devicecontext2d; | 185 return &ppb_graphics_2d; |
| 186 } | 186 } |
| 187 | 187 |
| 188 bool DeviceContext2D::Init(int width, int height, bool is_always_opaque) { | 188 bool Graphics2D::Init(int width, int height, bool is_always_opaque) { |
| 189 // The underlying ImageData will validate the dimensions. | 189 // The underlying ImageData will validate the dimensions. |
| 190 image_data_ = new ImageData(module()); | 190 image_data_ = new ImageData(module()); |
| 191 if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height, true) || | 191 if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height, true) || |
| 192 !image_data_->Map()) { | 192 !image_data_->Map()) { |
| 193 image_data_ = NULL; | 193 image_data_ = NULL; |
| 194 return false; | 194 return false; |
| 195 } | 195 } |
| 196 | 196 |
| 197 return true; | 197 return true; |
| 198 } | 198 } |
| 199 | 199 |
| 200 bool DeviceContext2D::Describe(PP_Size* size, bool* is_always_opaque) { | 200 bool Graphics2D::Describe(PP_Size* size, bool* is_always_opaque) { |
| 201 size->width = image_data_->width(); | 201 size->width = image_data_->width(); |
| 202 size->height = image_data_->height(); | 202 size->height = image_data_->height(); |
| 203 *is_always_opaque = false; // TODO(brettw) implement this. | 203 *is_always_opaque = false; // TODO(brettw) implement this. |
| 204 return true; | 204 return true; |
| 205 } | 205 } |
| 206 | 206 |
| 207 bool DeviceContext2D::PaintImageData(PP_Resource image, | 207 bool Graphics2D::PaintImageData(PP_Resource image, |
| 208 const PP_Point* top_left, | 208 const PP_Point* top_left, |
| 209 const PP_Rect* src_rect) { | 209 const PP_Rect* src_rect) { |
| 210 if (!top_left) | 210 if (!top_left) |
| 211 return false; | 211 return false; |
| 212 | 212 |
| 213 scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); | 213 scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); |
| 214 if (!image_resource) | 214 if (!image_resource) |
| 215 return false; | 215 return false; |
| 216 | 216 |
| 217 QueuedOperation operation(QueuedOperation::PAINT); | 217 QueuedOperation operation(QueuedOperation::PAINT); |
| 218 operation.paint_image = image_resource; | 218 operation.paint_image = image_resource; |
| 219 if (!ValidateAndConvertRect(src_rect, image_resource->width(), | 219 if (!ValidateAndConvertRect(src_rect, image_resource->width(), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 233 y64 + static_cast<int64>(operation.paint_src_rect.bottom()) > | 233 y64 + static_cast<int64>(operation.paint_src_rect.bottom()) > |
| 234 image_data_->height()) | 234 image_data_->height()) |
| 235 return false; | 235 return false; |
| 236 operation.paint_x = top_left->x; | 236 operation.paint_x = top_left->x; |
| 237 operation.paint_y = top_left->y; | 237 operation.paint_y = top_left->y; |
| 238 | 238 |
| 239 queued_operations_.push_back(operation); | 239 queued_operations_.push_back(operation); |
| 240 return true; | 240 return true; |
| 241 } | 241 } |
| 242 | 242 |
| 243 bool DeviceContext2D::Scroll(const PP_Rect* clip_rect, | 243 bool Graphics2D::Scroll(const PP_Rect* clip_rect, const PP_Point* amount) { |
| 244 const PP_Point* amount) { | |
| 245 QueuedOperation operation(QueuedOperation::SCROLL); | 244 QueuedOperation operation(QueuedOperation::SCROLL); |
| 246 if (!ValidateAndConvertRect(clip_rect, | 245 if (!ValidateAndConvertRect(clip_rect, |
| 247 image_data_->width(), | 246 image_data_->width(), |
| 248 image_data_->height(), | 247 image_data_->height(), |
| 249 &operation.scroll_clip_rect)) | 248 &operation.scroll_clip_rect)) |
| 250 return false; | 249 return false; |
| 251 | 250 |
| 252 // If we're being asked to scroll by more than the clip rect size, just | 251 // If we're being asked to scroll by more than the clip rect size, just |
| 253 // ignore this scroll command and say it worked. | 252 // ignore this scroll command and say it worked. |
| 254 int32 dx = amount->x; | 253 int32 dx = amount->x; |
| 255 int32 dy = amount->y; | 254 int32 dy = amount->y; |
| 256 if (dx <= -image_data_->width() || dx >= image_data_->width() || | 255 if (dx <= -image_data_->width() || dx >= image_data_->width() || |
| 257 dx <= -image_data_->height() || dy >= image_data_->height()) | 256 dx <= -image_data_->height() || dy >= image_data_->height()) |
| 258 return true; | 257 return true; |
| 259 | 258 |
| 260 operation.scroll_dx = dx; | 259 operation.scroll_dx = dx; |
| 261 operation.scroll_dy = dy; | 260 operation.scroll_dy = dy; |
| 262 | 261 |
| 263 queued_operations_.push_back(operation); | 262 queued_operations_.push_back(operation); |
| 264 return false; | 263 return false; |
| 265 } | 264 } |
| 266 | 265 |
| 267 bool DeviceContext2D::ReplaceContents(PP_Resource image) { | 266 bool Graphics2D::ReplaceContents(PP_Resource image) { |
| 268 scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); | 267 scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); |
| 269 if (!image_resource) | 268 if (!image_resource) |
| 270 return false; | 269 return false; |
| 271 if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) | 270 if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) |
| 272 return false; | 271 return false; |
| 273 | 272 |
| 274 if (image_resource->width() != image_data_->width() || | 273 if (image_resource->width() != image_data_->width() || |
| 275 image_resource->height() != image_data_->height()) | 274 image_resource->height() != image_data_->height()) |
| 276 return false; | 275 return false; |
| 277 | 276 |
| 278 QueuedOperation operation(QueuedOperation::REPLACE); | 277 QueuedOperation operation(QueuedOperation::REPLACE); |
| 279 operation.replace_image = image_resource; | 278 operation.replace_image = image_resource; |
| 280 queued_operations_.push_back(operation); | 279 queued_operations_.push_back(operation); |
| 281 | 280 |
| 282 return true; | 281 return true; |
| 283 } | 282 } |
| 284 | 283 |
| 285 int32_t DeviceContext2D::Flush(const PP_CompletionCallback& callback) { | 284 int32_t Graphics2D::Flush(const PP_CompletionCallback& callback) { |
| 286 // Don't allow more than one pending flush at a time. | 285 // Don't allow more than one pending flush at a time. |
| 287 if (HasPendingFlush()) | 286 if (HasPendingFlush()) |
| 288 return PP_ERROR_INPROGRESS; | 287 return PP_ERROR_INPROGRESS; |
| 289 | 288 |
| 290 // TODO(brettw) check that the current thread is not the main one and | 289 // TODO(brettw) check that the current thread is not the main one and |
| 291 // implement blocking flushes in this case. | 290 // implement blocking flushes in this case. |
| 292 if (!callback.func) | 291 if (!callback.func) |
| 293 return PP_ERROR_BADARGUMENT; | 292 return PP_ERROR_BADARGUMENT; |
| 294 | 293 |
| 295 gfx::Rect changed_rect; | 294 gfx::Rect changed_rect; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 unpainted_flush_callback_.Set(callback); | 328 unpainted_flush_callback_.Set(callback); |
| 330 bound_instance_->InvalidateRect(visible_changed_rect); | 329 bound_instance_->InvalidateRect(visible_changed_rect); |
| 331 } else { | 330 } else { |
| 332 // There's nothing visible to invalidate so just schedule the callback to | 331 // There's nothing visible to invalidate so just schedule the callback to |
| 333 // execute in the next round of the message loop. | 332 // execute in the next round of the message loop. |
| 334 ScheduleOffscreenCallback(FlushCallbackData(callback)); | 333 ScheduleOffscreenCallback(FlushCallbackData(callback)); |
| 335 } | 334 } |
| 336 return PP_ERROR_WOULDBLOCK; | 335 return PP_ERROR_WOULDBLOCK; |
| 337 } | 336 } |
| 338 | 337 |
| 339 bool DeviceContext2D::ReadImageData(PP_Resource image, | 338 bool Graphics2D::ReadImageData(PP_Resource image, |
| 340 const PP_Point* top_left) { | 339 const PP_Point* top_left) { |
| 341 // Get and validate the image object to paint into. | 340 // Get and validate the image object to paint into. |
| 342 scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); | 341 scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); |
| 343 if (!image_resource) | 342 if (!image_resource) |
| 344 return false; | 343 return false; |
| 345 if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) | 344 if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) |
| 346 return false; // Must be in the right format. | 345 return false; // Must be in the right format. |
| 347 | 346 |
| 348 // Validate the bitmap position. | 347 // Validate the bitmap position. |
| 349 int x = top_left->x; | 348 int x = top_left->x; |
| 350 if (x < 0 || | 349 if (x < 0 || |
| (...skipping 20 matching lines...) Expand all Loading... |
| 371 SkIntToScalar(image_resource->height()) }; | 370 SkIntToScalar(image_resource->height()) }; |
| 372 | 371 |
| 373 // We want to replace the contents of the bitmap rather than blend. | 372 // We want to replace the contents of the bitmap rather than blend. |
| 374 SkPaint paint; | 373 SkPaint paint; |
| 375 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 374 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 376 dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(), | 375 dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(), |
| 377 &src_irect, dest_rect, &paint); | 376 &src_irect, dest_rect, &paint); |
| 378 return true; | 377 return true; |
| 379 } | 378 } |
| 380 | 379 |
| 381 bool DeviceContext2D::BindToInstance(PluginInstance* new_instance) { | 380 bool Graphics2D::BindToInstance(PluginInstance* new_instance) { |
| 382 if (bound_instance_ == new_instance) | 381 if (bound_instance_ == new_instance) |
| 383 return true; // Rebinding the same device, nothing to do. | 382 return true; // Rebinding the same device, nothing to do. |
| 384 if (bound_instance_ && new_instance) | 383 if (bound_instance_ && new_instance) |
| 385 return false; // Can't change a bound device. | 384 return false; // Can't change a bound device. |
| 386 | 385 |
| 387 if (!new_instance) { | 386 if (!new_instance) { |
| 388 // When the device is detached, we'll not get any more paint callbacks so | 387 // When the device is detached, we'll not get any more paint callbacks so |
| 389 // we need to clear the list, but we still want to issue any pending | 388 // we need to clear the list, but we still want to issue any pending |
| 390 // callbacks to the plugin. | 389 // callbacks to the plugin. |
| 391 if (!unpainted_flush_callback_.is_null()) { | 390 if (!unpainted_flush_callback_.is_null()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 405 // actually painted something. By not bothering to schedule an invalidate | 404 // actually painted something. By not bothering to schedule an invalidate |
| 406 // when an empty device is initially bound, we can save an extra paint for | 405 // when an empty device is initially bound, we can save an extra paint for |
| 407 // many plugins during the critical page initialization phase. | 406 // many plugins during the critical page initialization phase. |
| 408 new_instance->InvalidateRect(gfx::Rect()); | 407 new_instance->InvalidateRect(gfx::Rect()); |
| 409 } | 408 } |
| 410 | 409 |
| 411 bound_instance_ = new_instance; | 410 bound_instance_ = new_instance; |
| 412 return true; | 411 return true; |
| 413 } | 412 } |
| 414 | 413 |
| 415 void DeviceContext2D::Paint(WebKit::WebCanvas* canvas, | 414 void Graphics2D::Paint(WebKit::WebCanvas* canvas, |
| 416 const gfx::Rect& plugin_rect, | 415 const gfx::Rect& plugin_rect, |
| 417 const gfx::Rect& paint_rect) { | 416 const gfx::Rect& paint_rect) { |
| 418 // We're guaranteed to have a mapped canvas since we mapped it in Init(). | 417 // We're guaranteed to have a mapped canvas since we mapped it in Init(). |
| 419 const SkBitmap& backing_bitmap = *image_data_->GetMappedBitmap(); | 418 const SkBitmap& backing_bitmap = *image_data_->GetMappedBitmap(); |
| 420 | 419 |
| 421 #if defined(OS_MACOSX) | 420 #if defined(OS_MACOSX) |
| 422 SkAutoLockPixels lock(backing_bitmap); | 421 SkAutoLockPixels lock(backing_bitmap); |
| 423 | 422 |
| 424 scoped_cftyperef<CGDataProviderRef> data_provider( | 423 scoped_cftyperef<CGDataProviderRef> data_provider( |
| 425 CGDataProviderCreateWithData( | 424 CGDataProviderCreateWithData( |
| 426 NULL, backing_bitmap.getAddr32(0, 0), | 425 NULL, backing_bitmap.getAddr32(0, 0), |
| 427 backing_bitmap.rowBytes() * backing_bitmap.height(), NULL)); | 426 backing_bitmap.rowBytes() * backing_bitmap.height(), NULL)); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 449 CGContextDrawImage(canvas, bounds, image); | 448 CGContextDrawImage(canvas, bounds, image); |
| 450 CGContextRestoreGState(canvas); | 449 CGContextRestoreGState(canvas); |
| 451 #else | 450 #else |
| 452 gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y()); | 451 gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y()); |
| 453 canvas->drawBitmap(backing_bitmap, | 452 canvas->drawBitmap(backing_bitmap, |
| 454 SkIntToScalar(plugin_rect.origin().x()), | 453 SkIntToScalar(plugin_rect.origin().x()), |
| 455 SkIntToScalar(plugin_rect.origin().y())); | 454 SkIntToScalar(plugin_rect.origin().y())); |
| 456 #endif | 455 #endif |
| 457 } | 456 } |
| 458 | 457 |
| 459 void DeviceContext2D::ViewInitiatedPaint() { | 458 void Graphics2D::ViewInitiatedPaint() { |
| 460 // Move any "unpainted" callback to the painted state. See | 459 // Move any "unpainted" callback to the painted state. See |
| 461 // |unpainted_flush_callback_| in the header for more. | 460 // |unpainted_flush_callback_| in the header for more. |
| 462 if (!unpainted_flush_callback_.is_null()) { | 461 if (!unpainted_flush_callback_.is_null()) { |
| 463 DCHECK(painted_flush_callback_.is_null()); | 462 DCHECK(painted_flush_callback_.is_null()); |
| 464 std::swap(painted_flush_callback_, unpainted_flush_callback_); | 463 std::swap(painted_flush_callback_, unpainted_flush_callback_); |
| 465 } | 464 } |
| 466 } | 465 } |
| 467 | 466 |
| 468 void DeviceContext2D::ViewFlushedPaint() { | 467 void Graphics2D::ViewFlushedPaint() { |
| 469 // Notify any "painted" callback. See |unpainted_flush_callback_| in the | 468 // Notify any "painted" callback. See |unpainted_flush_callback_| in the |
| 470 // header for more. | 469 // header for more. |
| 471 if (!painted_flush_callback_.is_null()) { | 470 if (!painted_flush_callback_.is_null()) { |
| 472 // We must clear this variable before issuing the callback. It will be | 471 // We must clear this variable before issuing the callback. It will be |
| 473 // common for the plugin to issue another invalidate in response to a flush | 472 // common for the plugin to issue another invalidate in response to a flush |
| 474 // callback, and we don't want to think that a callback is already pending. | 473 // callback, and we don't want to think that a callback is already pending. |
| 475 FlushCallbackData callback; | 474 FlushCallbackData callback; |
| 476 std::swap(callback, painted_flush_callback_); | 475 std::swap(callback, painted_flush_callback_); |
| 477 callback.Execute(PP_OK); | 476 callback.Execute(PP_OK); |
| 478 } | 477 } |
| 479 } | 478 } |
| 480 | 479 |
| 481 void DeviceContext2D::ExecutePaintImageData(ImageData* image, | 480 void Graphics2D::ExecutePaintImageData(ImageData* image, |
| 482 int x, int y, | 481 int x, int y, |
| 483 const gfx::Rect& src_rect, | 482 const gfx::Rect& src_rect, |
| 484 gfx::Rect* invalidated_rect) { | 483 gfx::Rect* invalidated_rect) { |
| 485 // Ensure the source image is mapped to read from it. | 484 // Ensure the source image is mapped to read from it. |
| 486 ImageDataAutoMapper auto_mapper(image); | 485 ImageDataAutoMapper auto_mapper(image); |
| 487 if (!auto_mapper.is_valid()) | 486 if (!auto_mapper.is_valid()) |
| 488 return; | 487 return; |
| 489 | 488 |
| 490 // Portion within the source image to cut out. | 489 // Portion within the source image to cut out. |
| 491 SkIRect src_irect = { src_rect.x(), src_rect.y(), | 490 SkIRect src_irect = { src_rect.x(), src_rect.y(), |
| 492 src_rect.right(), src_rect.bottom() }; | 491 src_rect.right(), src_rect.bottom() }; |
| 493 | 492 |
| 494 // Location within the backing store to copy to. | 493 // Location within the backing store to copy to. |
| 495 *invalidated_rect = src_rect; | 494 *invalidated_rect = src_rect; |
| 496 invalidated_rect->Offset(x, y); | 495 invalidated_rect->Offset(x, y); |
| 497 SkRect dest_rect = { SkIntToScalar(invalidated_rect->x()), | 496 SkRect dest_rect = { SkIntToScalar(invalidated_rect->x()), |
| 498 SkIntToScalar(invalidated_rect->y()), | 497 SkIntToScalar(invalidated_rect->y()), |
| 499 SkIntToScalar(invalidated_rect->right()), | 498 SkIntToScalar(invalidated_rect->right()), |
| 500 SkIntToScalar(invalidated_rect->bottom()) }; | 499 SkIntToScalar(invalidated_rect->bottom()) }; |
| 501 | 500 |
| 502 // We're guaranteed to have a mapped canvas since we mapped it in Init(). | 501 // We're guaranteed to have a mapped canvas since we mapped it in Init(). |
| 503 skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas(); | 502 skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas(); |
| 504 | 503 |
| 505 // We want to replace the contents of the bitmap rather than blend. | 504 // We want to replace the contents of the bitmap rather than blend. |
| 506 SkPaint paint; | 505 SkPaint paint; |
| 507 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 506 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 508 backing_canvas->drawBitmapRect(*image->GetMappedBitmap(), | 507 backing_canvas->drawBitmapRect(*image->GetMappedBitmap(), |
| 509 &src_irect, dest_rect, &paint); | 508 &src_irect, dest_rect, &paint); |
| 510 } | 509 } |
| 511 | 510 |
| 512 void DeviceContext2D::ExecuteScroll(const gfx::Rect& clip, int dx, int dy, | 511 void Graphics2D::ExecuteScroll(const gfx::Rect& clip, int dx, int dy, |
| 513 gfx::Rect* invalidated_rect) { | 512 gfx::Rect* invalidated_rect) { |
| 514 gfx::ScrollCanvas(image_data_->mapped_canvas(), | 513 gfx::ScrollCanvas(image_data_->mapped_canvas(), |
| 515 clip, gfx::Point(dx, dy)); | 514 clip, gfx::Point(dx, dy)); |
| 516 *invalidated_rect = clip; | 515 *invalidated_rect = clip; |
| 517 } | 516 } |
| 518 | 517 |
| 519 void DeviceContext2D::ExecuteReplaceContents(ImageData* image, | 518 void Graphics2D::ExecuteReplaceContents(ImageData* image, |
| 520 gfx::Rect* invalidated_rect) { | 519 gfx::Rect* invalidated_rect) { |
| 521 image_data_->Swap(image); | 520 image_data_->Swap(image); |
| 522 *invalidated_rect = gfx::Rect(0, 0, | 521 *invalidated_rect = gfx::Rect(0, 0, |
| 523 image_data_->width(), image_data_->height()); | 522 image_data_->width(), image_data_->height()); |
| 524 } | 523 } |
| 525 | 524 |
| 526 void DeviceContext2D::ScheduleOffscreenCallback( | 525 void Graphics2D::ScheduleOffscreenCallback(const FlushCallbackData& callback) { |
| 527 const FlushCallbackData& callback) { | |
| 528 DCHECK(!HasPendingFlush()); | 526 DCHECK(!HasPendingFlush()); |
| 529 offscreen_flush_pending_ = true; | 527 offscreen_flush_pending_ = true; |
| 530 MessageLoop::current()->PostTask( | 528 MessageLoop::current()->PostTask( |
| 531 FROM_HERE, | 529 FROM_HERE, |
| 532 NewRunnableMethod(this, | 530 NewRunnableMethod(this, |
| 533 &DeviceContext2D::ExecuteOffscreenCallback, | 531 &Graphics2D::ExecuteOffscreenCallback, |
| 534 callback)); | 532 callback)); |
| 535 } | 533 } |
| 536 | 534 |
| 537 void DeviceContext2D::ExecuteOffscreenCallback(FlushCallbackData data) { | 535 void Graphics2D::ExecuteOffscreenCallback(FlushCallbackData data) { |
| 538 DCHECK(offscreen_flush_pending_); | 536 DCHECK(offscreen_flush_pending_); |
| 539 | 537 |
| 540 // We must clear this flag before issuing the callback. It will be | 538 // We must clear this flag before issuing the callback. It will be |
| 541 // common for the plugin to issue another invalidate in response to a flush | 539 // common for the plugin to issue another invalidate in response to a flush |
| 542 // callback, and we don't want to think that a callback is already pending. | 540 // callback, and we don't want to think that a callback is already pending. |
| 543 offscreen_flush_pending_ = false; | 541 offscreen_flush_pending_ = false; |
| 544 data.Execute(PP_OK); | 542 data.Execute(PP_OK); |
| 545 } | 543 } |
| 546 | 544 |
| 547 bool DeviceContext2D::HasPendingFlush() const { | 545 bool Graphics2D::HasPendingFlush() const { |
| 548 return !unpainted_flush_callback_.is_null() || | 546 return !unpainted_flush_callback_.is_null() || |
| 549 !painted_flush_callback_.is_null() || | 547 !painted_flush_callback_.is_null() || |
| 550 offscreen_flush_pending_; | 548 offscreen_flush_pending_; |
| 551 } | 549 } |
| 552 | 550 |
| 553 } // namespace pepper | 551 } // namespace pepper |
| OLD | NEW |