| 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_graphics_2d.h" | 5 #include "webkit/plugins/ppapi/ppb_graphics_2d_impl.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 "ppapi/c/pp_errors.h" | 16 #include "ppapi/c/pp_errors.h" |
| 17 #include "ppapi/c/pp_module.h" | 17 #include "ppapi/c/pp_module.h" |
| 18 #include "ppapi/c/pp_rect.h" | 18 #include "ppapi/c/pp_rect.h" |
| 19 #include "ppapi/c/pp_resource.h" | 19 #include "ppapi/c/pp_resource.h" |
| 20 #include "ppapi/c/ppb_graphics_2d.h" | 20 #include "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_common.h" | 22 #include "webkit/plugins/ppapi/common.h" |
| 23 #include "webkit/glue/plugins/pepper_image_data.h" | 23 #include "webkit/plugins/ppapi/plugin_instance.h" |
| 24 #include "webkit/glue/plugins/pepper_plugin_instance.h" | 24 #include "webkit/plugins/ppapi/plugin_module.h" |
| 25 #include "webkit/glue/plugins/pepper_plugin_module.h" | 25 #include "webkit/plugins/ppapi/ppb_image_data_impl.h" |
| 26 | 26 |
| 27 #if defined(OS_MACOSX) | 27 #if defined(OS_MACOSX) |
| 28 #include "base/mac_util.h" | 28 #include "base/mac_util.h" |
| 29 #include "base/mac/scoped_cftyperef.h" | 29 #include "base/mac/scoped_cftyperef.h" |
| 30 #endif | 30 #endif |
| 31 | 31 |
| 32 namespace pepper { | 32 namespace webkit { |
| 33 namespace plugins { |
| 34 namespace ppapi { |
| 33 | 35 |
| 34 namespace { | 36 namespace { |
| 35 | 37 |
| 36 // Converts a rect inside an image of the given dimensions. The rect may be | 38 // Converts a rect inside an image of the given dimensions. The rect may be |
| 37 // NULL to indicate it should be the entire image. If the rect is outside of | 39 // NULL to indicate it should be the entire image. If the rect is outside of |
| 38 // the image, this will do nothing and return false. | 40 // the image, this will do nothing and return false. |
| 39 bool ValidateAndConvertRect(const PP_Rect* rect, | 41 bool ValidateAndConvertRect(const PP_Rect* rect, |
| 40 int image_width, int image_height, | 42 int image_width, int image_height, |
| 41 gfx::Rect* dest) { | 43 gfx::Rect* dest) { |
| 42 if (!rect) { | 44 if (!rect) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 unsigned char* pixel_out = reinterpret_cast<unsigned char*>(&output[i]); | 76 unsigned char* pixel_out = reinterpret_cast<unsigned char*>(&output[i]); |
| 75 pixel_out[0] = pixel_in[2]; | 77 pixel_out[0] = pixel_in[2]; |
| 76 pixel_out[1] = pixel_in[1]; | 78 pixel_out[1] = pixel_in[1]; |
| 77 pixel_out[2] = pixel_in[0]; | 79 pixel_out[2] = pixel_in[0]; |
| 78 pixel_out[3] = pixel_in[3]; | 80 pixel_out[3] = pixel_in[3]; |
| 79 } | 81 } |
| 80 } | 82 } |
| 81 | 83 |
| 82 // Converts ImageData from PP_IMAGEDATAFORMAT_BGRA_PREMUL to | 84 // Converts ImageData from PP_IMAGEDATAFORMAT_BGRA_PREMUL to |
| 83 // PP_IMAGEDATAFORMAT_RGBA_PREMUL, or reverse. | 85 // PP_IMAGEDATAFORMAT_RGBA_PREMUL, or reverse. |
| 84 void ConvertImageData(ImageData* src_image, const SkIRect& src_rect, | 86 void ConvertImageData(PPB_ImageData_Impl* src_image, const SkIRect& src_rect, |
| 85 ImageData* dest_image, const SkRect& dest_rect) { | 87 PPB_ImageData_Impl* dest_image, const SkRect& dest_rect) { |
| 86 DCHECK(src_image->format() != dest_image->format()); | 88 DCHECK(src_image->format() != dest_image->format()); |
| 87 DCHECK(ImageData::IsImageDataFormatSupported(src_image->format())); | 89 DCHECK(PPB_ImageData_Impl::IsImageDataFormatSupported(src_image->format())); |
| 88 DCHECK(ImageData::IsImageDataFormatSupported(dest_image->format())); | 90 DCHECK(PPB_ImageData_Impl::IsImageDataFormatSupported(dest_image->format())); |
| 89 | 91 |
| 90 const SkBitmap* src_bitmap = src_image->GetMappedBitmap(); | 92 const SkBitmap* src_bitmap = src_image->GetMappedBitmap(); |
| 91 const SkBitmap* dest_bitmap = dest_image->GetMappedBitmap(); | 93 const SkBitmap* dest_bitmap = dest_image->GetMappedBitmap(); |
| 92 if (src_rect.width() == src_image->width() && | 94 if (src_rect.width() == src_image->width() && |
| 93 dest_rect.width() == dest_image->width()) { | 95 dest_rect.width() == dest_image->width()) { |
| 94 // Fast path if the full line needs to be converted. | 96 // Fast path if the full line needs to be converted. |
| 95 ConvertBetweenBGRAandRGBA( | 97 ConvertBetweenBGRAandRGBA( |
| 96 src_bitmap->getAddr32(static_cast<int>(src_rect.fLeft), | 98 src_bitmap->getAddr32(static_cast<int>(src_rect.fLeft), |
| 97 static_cast<int>(src_rect.fTop)), | 99 static_cast<int>(src_rect.fTop)), |
| 98 src_rect.width() * src_rect.height(), | 100 src_rect.width() * src_rect.height(), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 111 } | 113 } |
| 112 } | 114 } |
| 113 | 115 |
| 114 PP_Resource Create(PP_Module module_id, | 116 PP_Resource Create(PP_Module module_id, |
| 115 const PP_Size* size, | 117 const PP_Size* size, |
| 116 PP_Bool is_always_opaque) { | 118 PP_Bool is_always_opaque) { |
| 117 PluginModule* module = ResourceTracker::Get()->GetModule(module_id); | 119 PluginModule* module = ResourceTracker::Get()->GetModule(module_id); |
| 118 if (!module) | 120 if (!module) |
| 119 return 0; | 121 return 0; |
| 120 | 122 |
| 121 scoped_refptr<Graphics2D> context(new Graphics2D(module)); | 123 scoped_refptr<PPB_Graphics2D_Impl> context(new PPB_Graphics2D_Impl(module)); |
| 122 if (!context->Init(size->width, size->height, PPBoolToBool(is_always_opaque))) | 124 if (!context->Init(size->width, size->height, PPBoolToBool(is_always_opaque))) |
| 123 return 0; | 125 return 0; |
| 124 return context->GetReference(); | 126 return context->GetReference(); |
| 125 } | 127 } |
| 126 | 128 |
| 127 PP_Bool IsGraphics2D(PP_Resource resource) { | 129 PP_Bool IsGraphics2D(PP_Resource resource) { |
| 128 return BoolToPPBool(!!Resource::GetAs<Graphics2D>(resource)); | 130 return BoolToPPBool(!!Resource::GetAs<PPB_Graphics2D_Impl>(resource)); |
| 129 } | 131 } |
| 130 | 132 |
| 131 PP_Bool Describe(PP_Resource graphics_2d, | 133 PP_Bool Describe(PP_Resource graphics_2d, |
| 132 PP_Size* size, | 134 PP_Size* size, |
| 133 PP_Bool* is_always_opaque) { | 135 PP_Bool* is_always_opaque) { |
| 134 scoped_refptr<Graphics2D> context( | 136 scoped_refptr<PPB_Graphics2D_Impl> context( |
| 135 Resource::GetAs<Graphics2D>(graphics_2d)); | 137 Resource::GetAs<PPB_Graphics2D_Impl>(graphics_2d)); |
| 136 if (!context) | 138 if (!context) |
| 137 return PP_FALSE; | 139 return PP_FALSE; |
| 138 return context->Describe(size, is_always_opaque); | 140 return context->Describe(size, is_always_opaque); |
| 139 } | 141 } |
| 140 | 142 |
| 141 void PaintImageData(PP_Resource graphics_2d, | 143 void PaintImageData(PP_Resource graphics_2d, |
| 142 PP_Resource image_data, | 144 PP_Resource image_data, |
| 143 const PP_Point* top_left, | 145 const PP_Point* top_left, |
| 144 const PP_Rect* src_rect) { | 146 const PP_Rect* src_rect) { |
| 145 scoped_refptr<Graphics2D> context( | 147 scoped_refptr<PPB_Graphics2D_Impl> context( |
| 146 Resource::GetAs<Graphics2D>(graphics_2d)); | 148 Resource::GetAs<PPB_Graphics2D_Impl>(graphics_2d)); |
| 147 if (context) | 149 if (context) |
| 148 context->PaintImageData(image_data, top_left, src_rect); | 150 context->PaintImageData(image_data, top_left, src_rect); |
| 149 } | 151 } |
| 150 | 152 |
| 151 void Scroll(PP_Resource graphics_2d, | 153 void Scroll(PP_Resource graphics_2d, |
| 152 const PP_Rect* clip_rect, | 154 const PP_Rect* clip_rect, |
| 153 const PP_Point* amount) { | 155 const PP_Point* amount) { |
| 154 scoped_refptr<Graphics2D> context( | 156 scoped_refptr<PPB_Graphics2D_Impl> context( |
| 155 Resource::GetAs<Graphics2D>(graphics_2d)); | 157 Resource::GetAs<PPB_Graphics2D_Impl>(graphics_2d)); |
| 156 if (context) | 158 if (context) |
| 157 context->Scroll(clip_rect, amount); | 159 context->Scroll(clip_rect, amount); |
| 158 } | 160 } |
| 159 | 161 |
| 160 void ReplaceContents(PP_Resource graphics_2d, PP_Resource image_data) { | 162 void ReplaceContents(PP_Resource graphics_2d, PP_Resource image_data) { |
| 161 scoped_refptr<Graphics2D> context( | 163 scoped_refptr<PPB_Graphics2D_Impl> context( |
| 162 Resource::GetAs<Graphics2D>(graphics_2d)); | 164 Resource::GetAs<PPB_Graphics2D_Impl>(graphics_2d)); |
| 163 if (context) | 165 if (context) |
| 164 context->ReplaceContents(image_data); | 166 context->ReplaceContents(image_data); |
| 165 } | 167 } |
| 166 | 168 |
| 167 int32_t Flush(PP_Resource graphics_2d, | 169 int32_t Flush(PP_Resource graphics_2d, |
| 168 PP_CompletionCallback callback) { | 170 PP_CompletionCallback callback) { |
| 169 scoped_refptr<Graphics2D> context( | 171 scoped_refptr<PPB_Graphics2D_Impl> context( |
| 170 Resource::GetAs<Graphics2D>(graphics_2d)); | 172 Resource::GetAs<PPB_Graphics2D_Impl>(graphics_2d)); |
| 171 if (!context) | 173 if (!context) |
| 172 return PP_ERROR_BADRESOURCE; | 174 return PP_ERROR_BADRESOURCE; |
| 173 return context->Flush(callback); | 175 return context->Flush(callback); |
| 174 } | 176 } |
| 175 | 177 |
| 176 const PPB_Graphics2D ppb_graphics_2d = { | 178 const PPB_Graphics2D ppb_graphics_2d = { |
| 177 &Create, | 179 &Create, |
| 178 &IsGraphics2D, | 180 &IsGraphics2D, |
| 179 &Describe, | 181 &Describe, |
| 180 &PaintImageData, | 182 &PaintImageData, |
| 181 &Scroll, | 183 &Scroll, |
| 182 &ReplaceContents, | 184 &ReplaceContents, |
| 183 &Flush | 185 &Flush |
| 184 }; | 186 }; |
| 185 | 187 |
| 186 } // namespace | 188 } // namespace |
| 187 | 189 |
| 188 struct Graphics2D::QueuedOperation { | 190 struct PPB_Graphics2D_Impl::QueuedOperation { |
| 189 enum Type { | 191 enum Type { |
| 190 PAINT, | 192 PAINT, |
| 191 SCROLL, | 193 SCROLL, |
| 192 REPLACE | 194 REPLACE |
| 193 }; | 195 }; |
| 194 | 196 |
| 195 QueuedOperation(Type t) | 197 QueuedOperation(Type t) |
| 196 : type(t), | 198 : type(t), |
| 197 paint_x(0), | 199 paint_x(0), |
| 198 paint_y(0), | 200 paint_y(0), |
| 199 scroll_dx(0), | 201 scroll_dx(0), |
| 200 scroll_dy(0) { | 202 scroll_dy(0) { |
| 201 } | 203 } |
| 202 | 204 |
| 203 Type type; | 205 Type type; |
| 204 | 206 |
| 205 // Valid when type == PAINT. | 207 // Valid when type == PAINT. |
| 206 scoped_refptr<ImageData> paint_image; | 208 scoped_refptr<PPB_ImageData_Impl> paint_image; |
| 207 int paint_x, paint_y; | 209 int paint_x, paint_y; |
| 208 gfx::Rect paint_src_rect; | 210 gfx::Rect paint_src_rect; |
| 209 | 211 |
| 210 // Valid when type == SCROLL. | 212 // Valid when type == SCROLL. |
| 211 gfx::Rect scroll_clip_rect; | 213 gfx::Rect scroll_clip_rect; |
| 212 int scroll_dx, scroll_dy; | 214 int scroll_dx, scroll_dy; |
| 213 | 215 |
| 214 // Valid when type == REPLACE. | 216 // Valid when type == REPLACE. |
| 215 scoped_refptr<ImageData> replace_image; | 217 scoped_refptr<PPB_ImageData_Impl> replace_image; |
| 216 }; | 218 }; |
| 217 | 219 |
| 218 Graphics2D::Graphics2D(PluginModule* module) | 220 PPB_Graphics2D_Impl::PPB_Graphics2D_Impl(PluginModule* module) |
| 219 : Resource(module), | 221 : Resource(module), |
| 220 bound_instance_(NULL), | 222 bound_instance_(NULL), |
| 221 flushed_any_data_(false), | 223 flushed_any_data_(false), |
| 222 offscreen_flush_pending_(false), | 224 offscreen_flush_pending_(false), |
| 223 is_always_opaque_(false) { | 225 is_always_opaque_(false) { |
| 224 } | 226 } |
| 225 | 227 |
| 226 Graphics2D::~Graphics2D() { | 228 PPB_Graphics2D_Impl::~PPB_Graphics2D_Impl() { |
| 227 } | 229 } |
| 228 | 230 |
| 229 // static | 231 // static |
| 230 const PPB_Graphics2D* Graphics2D::GetInterface() { | 232 const PPB_Graphics2D* PPB_Graphics2D_Impl::GetInterface() { |
| 231 return &ppb_graphics_2d; | 233 return &ppb_graphics_2d; |
| 232 } | 234 } |
| 233 | 235 |
| 234 bool Graphics2D::Init(int width, int height, bool is_always_opaque) { | 236 bool PPB_Graphics2D_Impl::Init(int width, int height, bool is_always_opaque) { |
| 235 // The underlying ImageData will validate the dimensions. | 237 // The underlying PPB_ImageData_Impl will validate the dimensions. |
| 236 image_data_ = new ImageData(module()); | 238 image_data_ = new PPB_ImageData_Impl(module()); |
| 237 if (!image_data_->Init(ImageData::GetNativeImageDataFormat(), width, height, | 239 if (!image_data_->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(), |
| 238 true) || !image_data_->Map()) { | 240 width, height, true) || |
| 241 !image_data_->Map()) { |
| 239 image_data_ = NULL; | 242 image_data_ = NULL; |
| 240 return false; | 243 return false; |
| 241 } | 244 } |
| 242 is_always_opaque_ = is_always_opaque; | 245 is_always_opaque_ = is_always_opaque; |
| 243 return true; | 246 return true; |
| 244 } | 247 } |
| 245 | 248 |
| 246 PP_Bool Graphics2D::Describe(PP_Size* size, PP_Bool* is_always_opaque) { | 249 PPB_Graphics2D_Impl* PPB_Graphics2D_Impl::AsGraphics2D() { |
| 250 return this; |
| 251 } |
| 252 |
| 253 PP_Bool PPB_Graphics2D_Impl::Describe(PP_Size* size, PP_Bool* is_always_opaque)
{ |
| 247 size->width = image_data_->width(); | 254 size->width = image_data_->width(); |
| 248 size->height = image_data_->height(); | 255 size->height = image_data_->height(); |
| 249 *is_always_opaque = PP_FALSE; // TODO(brettw) implement this. | 256 *is_always_opaque = PP_FALSE; // TODO(brettw) implement this. |
| 250 return PP_TRUE; | 257 return PP_TRUE; |
| 251 } | 258 } |
| 252 | 259 |
| 253 void Graphics2D::PaintImageData(PP_Resource image_data, | 260 void PPB_Graphics2D_Impl::PaintImageData(PP_Resource image_data, |
| 254 const PP_Point* top_left, | 261 const PP_Point* top_left, |
| 255 const PP_Rect* src_rect) { | 262 const PP_Rect* src_rect) { |
| 256 if (!top_left) | 263 if (!top_left) |
| 257 return; | 264 return; |
| 258 | 265 |
| 259 scoped_refptr<ImageData> image_resource( | 266 scoped_refptr<PPB_ImageData_Impl> image_resource( |
| 260 Resource::GetAs<ImageData>(image_data)); | 267 Resource::GetAs<PPB_ImageData_Impl>(image_data)); |
| 261 if (!image_resource) | 268 if (!image_resource) |
| 262 return; | 269 return; |
| 263 | 270 |
| 264 QueuedOperation operation(QueuedOperation::PAINT); | 271 QueuedOperation operation(QueuedOperation::PAINT); |
| 265 operation.paint_image = image_resource; | 272 operation.paint_image = image_resource; |
| 266 if (!ValidateAndConvertRect(src_rect, image_resource->width(), | 273 if (!ValidateAndConvertRect(src_rect, image_resource->width(), |
| 267 image_resource->height(), | 274 image_resource->height(), |
| 268 &operation.paint_src_rect)) | 275 &operation.paint_src_rect)) |
| 269 return; | 276 return; |
| 270 | 277 |
| 271 // Validate the bitmap position using the previously-validated rect, there | 278 // Validate the bitmap position using the previously-validated rect, there |
| 272 // should be no painted area outside of the image. | 279 // should be no painted area outside of the image. |
| 273 int64 x64 = static_cast<int64>(top_left->x); | 280 int64 x64 = static_cast<int64>(top_left->x); |
| 274 int64 y64 = static_cast<int64>(top_left->y); | 281 int64 y64 = static_cast<int64>(top_left->y); |
| 275 if (x64 + static_cast<int64>(operation.paint_src_rect.x()) < 0 || | 282 if (x64 + static_cast<int64>(operation.paint_src_rect.x()) < 0 || |
| 276 x64 + static_cast<int64>(operation.paint_src_rect.right()) > | 283 x64 + static_cast<int64>(operation.paint_src_rect.right()) > |
| 277 image_data_->width()) | 284 image_data_->width()) |
| 278 return; | 285 return; |
| 279 if (y64 + static_cast<int64>(operation.paint_src_rect.y()) < 0 || | 286 if (y64 + static_cast<int64>(operation.paint_src_rect.y()) < 0 || |
| 280 y64 + static_cast<int64>(operation.paint_src_rect.bottom()) > | 287 y64 + static_cast<int64>(operation.paint_src_rect.bottom()) > |
| 281 image_data_->height()) | 288 image_data_->height()) |
| 282 return; | 289 return; |
| 283 operation.paint_x = top_left->x; | 290 operation.paint_x = top_left->x; |
| 284 operation.paint_y = top_left->y; | 291 operation.paint_y = top_left->y; |
| 285 | 292 |
| 286 queued_operations_.push_back(operation); | 293 queued_operations_.push_back(operation); |
| 287 } | 294 } |
| 288 | 295 |
| 289 void Graphics2D::Scroll(const PP_Rect* clip_rect, const PP_Point* amount) { | 296 void PPB_Graphics2D_Impl::Scroll(const PP_Rect* clip_rect, |
| 297 const PP_Point* amount) { |
| 290 QueuedOperation operation(QueuedOperation::SCROLL); | 298 QueuedOperation operation(QueuedOperation::SCROLL); |
| 291 if (!ValidateAndConvertRect(clip_rect, | 299 if (!ValidateAndConvertRect(clip_rect, |
| 292 image_data_->width(), | 300 image_data_->width(), |
| 293 image_data_->height(), | 301 image_data_->height(), |
| 294 &operation.scroll_clip_rect)) | 302 &operation.scroll_clip_rect)) |
| 295 return; | 303 return; |
| 296 | 304 |
| 297 // If we're being asked to scroll by more than the clip rect size, just | 305 // If we're being asked to scroll by more than the clip rect size, just |
| 298 // ignore this scroll command and say it worked. | 306 // ignore this scroll command and say it worked. |
| 299 int32 dx = amount->x; | 307 int32 dx = amount->x; |
| 300 int32 dy = amount->y; | 308 int32 dy = amount->y; |
| 301 if (dx <= -image_data_->width() || dx >= image_data_->width() || | 309 if (dx <= -image_data_->width() || dx >= image_data_->width() || |
| 302 dy <= -image_data_->height() || dy >= image_data_->height()) | 310 dy <= -image_data_->height() || dy >= image_data_->height()) |
| 303 return; | 311 return; |
| 304 | 312 |
| 305 operation.scroll_dx = dx; | 313 operation.scroll_dx = dx; |
| 306 operation.scroll_dy = dy; | 314 operation.scroll_dy = dy; |
| 307 | 315 |
| 308 queued_operations_.push_back(operation); | 316 queued_operations_.push_back(operation); |
| 309 } | 317 } |
| 310 | 318 |
| 311 void Graphics2D::ReplaceContents(PP_Resource image_data) { | 319 void PPB_Graphics2D_Impl::ReplaceContents(PP_Resource image_data) { |
| 312 scoped_refptr<ImageData> image_resource( | 320 scoped_refptr<PPB_ImageData_Impl> image_resource( |
| 313 Resource::GetAs<ImageData>(image_data)); | 321 Resource::GetAs<PPB_ImageData_Impl>(image_data)); |
| 314 if (!image_resource) | 322 if (!image_resource) |
| 315 return; | 323 return; |
| 316 if (!ImageData::IsImageDataFormatSupported(image_resource->format())) | 324 if (!PPB_ImageData_Impl::IsImageDataFormatSupported( |
| 325 image_resource->format())) |
| 317 return; | 326 return; |
| 318 | 327 |
| 319 if (image_resource->width() != image_data_->width() || | 328 if (image_resource->width() != image_data_->width() || |
| 320 image_resource->height() != image_data_->height()) | 329 image_resource->height() != image_data_->height()) |
| 321 return; | 330 return; |
| 322 | 331 |
| 323 QueuedOperation operation(QueuedOperation::REPLACE); | 332 QueuedOperation operation(QueuedOperation::REPLACE); |
| 324 operation.replace_image = image_resource; | 333 operation.replace_image = image_resource; |
| 325 queued_operations_.push_back(operation); | 334 queued_operations_.push_back(operation); |
| 326 } | 335 } |
| 327 | 336 |
| 328 int32_t Graphics2D::Flush(const PP_CompletionCallback& callback) { | 337 int32_t PPB_Graphics2D_Impl::Flush(const PP_CompletionCallback& callback) { |
| 329 // Don't allow more than one pending flush at a time. | 338 // Don't allow more than one pending flush at a time. |
| 330 if (HasPendingFlush()) | 339 if (HasPendingFlush()) |
| 331 return PP_ERROR_INPROGRESS; | 340 return PP_ERROR_INPROGRESS; |
| 332 | 341 |
| 333 // TODO(brettw) check that the current thread is not the main one and | 342 // TODO(brettw) check that the current thread is not the main one and |
| 334 // implement blocking flushes in this case. | 343 // implement blocking flushes in this case. |
| 335 if (!callback.func) | 344 if (!callback.func) |
| 336 return PP_ERROR_BADARGUMENT; | 345 return PP_ERROR_BADARGUMENT; |
| 337 | 346 |
| 338 bool nothing_visible = true; | 347 bool nothing_visible = true; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 if (nothing_visible) { | 389 if (nothing_visible) { |
| 381 // There's nothing visible to invalidate so just schedule the callback to | 390 // There's nothing visible to invalidate so just schedule the callback to |
| 382 // execute in the next round of the message loop. | 391 // execute in the next round of the message loop. |
| 383 ScheduleOffscreenCallback(FlushCallbackData(callback)); | 392 ScheduleOffscreenCallback(FlushCallbackData(callback)); |
| 384 } else { | 393 } else { |
| 385 unpainted_flush_callback_.Set(callback); | 394 unpainted_flush_callback_.Set(callback); |
| 386 } | 395 } |
| 387 return PP_ERROR_WOULDBLOCK; | 396 return PP_ERROR_WOULDBLOCK; |
| 388 } | 397 } |
| 389 | 398 |
| 390 bool Graphics2D::ReadImageData(PP_Resource image, | 399 bool PPB_Graphics2D_Impl::ReadImageData(PP_Resource image, |
| 391 const PP_Point* top_left) { | 400 const PP_Point* top_left) { |
| 392 // Get and validate the image object to paint into. | 401 // Get and validate the image object to paint into. |
| 393 scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); | 402 scoped_refptr<PPB_ImageData_Impl> image_resource( |
| 403 Resource::GetAs<PPB_ImageData_Impl>(image)); |
| 394 if (!image_resource) | 404 if (!image_resource) |
| 395 return false; | 405 return false; |
| 396 if (!ImageData::IsImageDataFormatSupported(image_resource->format())) | 406 if (!PPB_ImageData_Impl::IsImageDataFormatSupported( |
| 407 image_resource->format())) |
| 397 return false; // Must be in the right format. | 408 return false; // Must be in the right format. |
| 398 | 409 |
| 399 // Validate the bitmap position. | 410 // Validate the bitmap position. |
| 400 int x = top_left->x; | 411 int x = top_left->x; |
| 401 if (x < 0 || | 412 if (x < 0 || |
| 402 static_cast<int64>(x) + static_cast<int64>(image_resource->width()) > | 413 static_cast<int64>(x) + static_cast<int64>(image_resource->width()) > |
| 403 image_data_->width()) | 414 image_data_->width()) |
| 404 return false; | 415 return false; |
| 405 int y = top_left->y; | 416 int y = top_left->y; |
| 406 if (y < 0 || | 417 if (y < 0 || |
| (...skipping 22 matching lines...) Expand all Loading... |
| 429 | 440 |
| 430 // We want to replace the contents of the bitmap rather than blend. | 441 // We want to replace the contents of the bitmap rather than blend. |
| 431 SkPaint paint; | 442 SkPaint paint; |
| 432 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 443 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 433 dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(), | 444 dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(), |
| 434 &src_irect, dest_rect, &paint); | 445 &src_irect, dest_rect, &paint); |
| 435 } | 446 } |
| 436 return true; | 447 return true; |
| 437 } | 448 } |
| 438 | 449 |
| 439 bool Graphics2D::BindToInstance(PluginInstance* new_instance) { | 450 bool PPB_Graphics2D_Impl::BindToInstance(PluginInstance* new_instance) { |
| 440 if (bound_instance_ == new_instance) | 451 if (bound_instance_ == new_instance) |
| 441 return true; // Rebinding the same device, nothing to do. | 452 return true; // Rebinding the same device, nothing to do. |
| 442 if (bound_instance_ && new_instance) | 453 if (bound_instance_ && new_instance) |
| 443 return false; // Can't change a bound device. | 454 return false; // Can't change a bound device. |
| 444 | 455 |
| 445 if (!new_instance) { | 456 if (!new_instance) { |
| 446 // When the device is detached, we'll not get any more paint callbacks so | 457 // When the device is detached, we'll not get any more paint callbacks so |
| 447 // we need to clear the list, but we still want to issue any pending | 458 // we need to clear the list, but we still want to issue any pending |
| 448 // callbacks to the plugin. | 459 // callbacks to the plugin. |
| 449 if (!unpainted_flush_callback_.is_null()) { | 460 if (!unpainted_flush_callback_.is_null()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 463 // actually painted something. By not bothering to schedule an invalidate | 474 // actually painted something. By not bothering to schedule an invalidate |
| 464 // when an empty device is initially bound, we can save an extra paint for | 475 // when an empty device is initially bound, we can save an extra paint for |
| 465 // many plugins during the critical page initialization phase. | 476 // many plugins during the critical page initialization phase. |
| 466 new_instance->InvalidateRect(gfx::Rect()); | 477 new_instance->InvalidateRect(gfx::Rect()); |
| 467 } | 478 } |
| 468 | 479 |
| 469 bound_instance_ = new_instance; | 480 bound_instance_ = new_instance; |
| 470 return true; | 481 return true; |
| 471 } | 482 } |
| 472 | 483 |
| 473 void Graphics2D::Paint(WebKit::WebCanvas* canvas, | 484 void PPB_Graphics2D_Impl::Paint(WebKit::WebCanvas* canvas, |
| 474 const gfx::Rect& plugin_rect, | 485 const gfx::Rect& plugin_rect, |
| 475 const gfx::Rect& paint_rect) { | 486 const gfx::Rect& paint_rect) { |
| 476 ImageDataAutoMapper auto_mapper(image_data_); | 487 ImageDataAutoMapper auto_mapper(image_data_); |
| 477 const SkBitmap& backing_bitmap = *image_data_->GetMappedBitmap(); | 488 const SkBitmap& backing_bitmap = *image_data_->GetMappedBitmap(); |
| 478 | 489 |
| 479 #if defined(OS_MACOSX) | 490 #if defined(OS_MACOSX) |
| 480 SkAutoLockPixels lock(backing_bitmap); | 491 SkAutoLockPixels lock(backing_bitmap); |
| 481 | 492 |
| 482 base::mac::ScopedCFTypeRef<CGDataProviderRef> data_provider( | 493 base::mac::ScopedCFTypeRef<CGDataProviderRef> data_provider( |
| 483 CGDataProviderCreateWithData( | 494 CGDataProviderCreateWithData( |
| 484 NULL, backing_bitmap.getAddr32(0, 0), | 495 NULL, backing_bitmap.getAddr32(0, 0), |
| 485 backing_bitmap.rowBytes() * backing_bitmap.height(), NULL)); | 496 backing_bitmap.rowBytes() * backing_bitmap.height(), NULL)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 } | 529 } |
| 519 | 530 |
| 520 gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y()); | 531 gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y()); |
| 521 canvas->drawBitmap(backing_bitmap, | 532 canvas->drawBitmap(backing_bitmap, |
| 522 SkIntToScalar(plugin_rect.origin().x()), | 533 SkIntToScalar(plugin_rect.origin().x()), |
| 523 SkIntToScalar(plugin_rect.origin().y()), | 534 SkIntToScalar(plugin_rect.origin().y()), |
| 524 &paint); | 535 &paint); |
| 525 #endif | 536 #endif |
| 526 } | 537 } |
| 527 | 538 |
| 528 void Graphics2D::ViewInitiatedPaint() { | 539 void PPB_Graphics2D_Impl::ViewInitiatedPaint() { |
| 529 // Move any "unpainted" callback to the painted state. See | 540 // Move any "unpainted" callback to the painted state. See |
| 530 // |unpainted_flush_callback_| in the header for more. | 541 // |unpainted_flush_callback_| in the header for more. |
| 531 if (!unpainted_flush_callback_.is_null()) { | 542 if (!unpainted_flush_callback_.is_null()) { |
| 532 DCHECK(painted_flush_callback_.is_null()); | 543 DCHECK(painted_flush_callback_.is_null()); |
| 533 std::swap(painted_flush_callback_, unpainted_flush_callback_); | 544 std::swap(painted_flush_callback_, unpainted_flush_callback_); |
| 534 } | 545 } |
| 535 } | 546 } |
| 536 | 547 |
| 537 void Graphics2D::ViewFlushedPaint() { | 548 void PPB_Graphics2D_Impl::ViewFlushedPaint() { |
| 538 // Notify any "painted" callback. See |unpainted_flush_callback_| in the | 549 // Notify any "painted" callback. See |unpainted_flush_callback_| in the |
| 539 // header for more. | 550 // header for more. |
| 540 if (!painted_flush_callback_.is_null()) { | 551 if (!painted_flush_callback_.is_null()) { |
| 541 // We must clear this variable before issuing the callback. It will be | 552 // We must clear this variable before issuing the callback. It will be |
| 542 // common for the plugin to issue another invalidate in response to a flush | 553 // common for the plugin to issue another invalidate in response to a flush |
| 543 // callback, and we don't want to think that a callback is already pending. | 554 // callback, and we don't want to think that a callback is already pending. |
| 544 FlushCallbackData callback; | 555 FlushCallbackData callback; |
| 545 std::swap(callback, painted_flush_callback_); | 556 std::swap(callback, painted_flush_callback_); |
| 546 callback.Execute(PP_OK); | 557 callback.Execute(PP_OK); |
| 547 } | 558 } |
| 548 } | 559 } |
| 549 | 560 |
| 550 void Graphics2D::ExecutePaintImageData(ImageData* image, | 561 void PPB_Graphics2D_Impl::ExecutePaintImageData(PPB_ImageData_Impl* image, |
| 551 int x, int y, | 562 int x, int y, |
| 552 const gfx::Rect& src_rect, | 563 const gfx::Rect& src_rect, |
| 553 gfx::Rect* invalidated_rect) { | 564 gfx::Rect* invalidated_rect) { |
| 554 // Ensure the source image is mapped to read from it. | 565 // Ensure the source image is mapped to read from it. |
| 555 ImageDataAutoMapper auto_mapper(image); | 566 ImageDataAutoMapper auto_mapper(image); |
| 556 if (!auto_mapper.is_valid()) | 567 if (!auto_mapper.is_valid()) |
| 557 return; | 568 return; |
| 558 | 569 |
| 559 // Portion within the source image to cut out. | 570 // Portion within the source image to cut out. |
| 560 SkIRect src_irect = { src_rect.x(), src_rect.y(), | 571 SkIRect src_irect = { src_rect.x(), src_rect.y(), |
| 561 src_rect.right(), src_rect.bottom() }; | 572 src_rect.right(), src_rect.bottom() }; |
| 562 | 573 |
| 563 // Location within the backing store to copy to. | 574 // Location within the backing store to copy to. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 576 skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas(); | 587 skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas(); |
| 577 | 588 |
| 578 // We want to replace the contents of the bitmap rather than blend. | 589 // We want to replace the contents of the bitmap rather than blend. |
| 579 SkPaint paint; | 590 SkPaint paint; |
| 580 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 591 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 581 backing_canvas->drawBitmapRect(*image->GetMappedBitmap(), | 592 backing_canvas->drawBitmapRect(*image->GetMappedBitmap(), |
| 582 &src_irect, dest_rect, &paint); | 593 &src_irect, dest_rect, &paint); |
| 583 } | 594 } |
| 584 } | 595 } |
| 585 | 596 |
| 586 void Graphics2D::ExecuteScroll(const gfx::Rect& clip, int dx, int dy, | 597 void PPB_Graphics2D_Impl::ExecuteScroll(const gfx::Rect& clip, |
| 587 gfx::Rect* invalidated_rect) { | 598 int dx, int dy, |
| 599 gfx::Rect* invalidated_rect) { |
| 588 gfx::ScrollCanvas(image_data_->mapped_canvas(), | 600 gfx::ScrollCanvas(image_data_->mapped_canvas(), |
| 589 clip, gfx::Point(dx, dy)); | 601 clip, gfx::Point(dx, dy)); |
| 590 *invalidated_rect = clip; | 602 *invalidated_rect = clip; |
| 591 } | 603 } |
| 592 | 604 |
| 593 void Graphics2D::ExecuteReplaceContents(ImageData* image, | 605 void PPB_Graphics2D_Impl::ExecuteReplaceContents(PPB_ImageData_Impl* image, |
| 594 gfx::Rect* invalidated_rect) { | 606 gfx::Rect* invalidated_rect) { |
| 595 if (image->format() != image_data_->format()) { | 607 if (image->format() != image_data_->format()) { |
| 596 DCHECK(image->width() == image_data_->width() && | 608 DCHECK(image->width() == image_data_->width() && |
| 597 image->height() == image_data_->height()); | 609 image->height() == image_data_->height()); |
| 598 // Convert the image data if the format does not match. | 610 // Convert the image data if the format does not match. |
| 599 SkIRect src_irect = { 0, 0, image->width(), image->height() }; | 611 SkIRect src_irect = { 0, 0, image->width(), image->height() }; |
| 600 SkRect dest_rect = { SkIntToScalar(0), | 612 SkRect dest_rect = { SkIntToScalar(0), |
| 601 SkIntToScalar(0), | 613 SkIntToScalar(0), |
| 602 SkIntToScalar(image_data_->width()), | 614 SkIntToScalar(image_data_->width()), |
| 603 SkIntToScalar(image_data_->height()) }; | 615 SkIntToScalar(image_data_->height()) }; |
| 604 ConvertImageData(image, src_irect, image_data_, dest_rect); | 616 ConvertImageData(image, src_irect, image_data_, dest_rect); |
| 605 } else { | 617 } else { |
| 606 image_data_->Swap(image); | 618 image_data_->Swap(image); |
| 607 } | 619 } |
| 608 *invalidated_rect = gfx::Rect(0, 0, | 620 *invalidated_rect = gfx::Rect(0, 0, |
| 609 image_data_->width(), image_data_->height()); | 621 image_data_->width(), image_data_->height()); |
| 610 } | 622 } |
| 611 | 623 |
| 612 void Graphics2D::ScheduleOffscreenCallback(const FlushCallbackData& callback) { | 624 void PPB_Graphics2D_Impl::ScheduleOffscreenCallback( |
| 625 const FlushCallbackData& callback) { |
| 613 DCHECK(!HasPendingFlush()); | 626 DCHECK(!HasPendingFlush()); |
| 614 offscreen_flush_pending_ = true; | 627 offscreen_flush_pending_ = true; |
| 615 MessageLoop::current()->PostTask( | 628 MessageLoop::current()->PostTask( |
| 616 FROM_HERE, | 629 FROM_HERE, |
| 617 NewRunnableMethod(this, | 630 NewRunnableMethod(this, |
| 618 &Graphics2D::ExecuteOffscreenCallback, | 631 &PPB_Graphics2D_Impl::ExecuteOffscreenCallback, |
| 619 callback)); | 632 callback)); |
| 620 } | 633 } |
| 621 | 634 |
| 622 void Graphics2D::ExecuteOffscreenCallback(FlushCallbackData data) { | 635 void PPB_Graphics2D_Impl::ExecuteOffscreenCallback(FlushCallbackData data) { |
| 623 DCHECK(offscreen_flush_pending_); | 636 DCHECK(offscreen_flush_pending_); |
| 624 | 637 |
| 625 // We must clear this flag before issuing the callback. It will be | 638 // We must clear this flag before issuing the callback. It will be |
| 626 // common for the plugin to issue another invalidate in response to a flush | 639 // common for the plugin to issue another invalidate in response to a flush |
| 627 // callback, and we don't want to think that a callback is already pending. | 640 // callback, and we don't want to think that a callback is already pending. |
| 628 offscreen_flush_pending_ = false; | 641 offscreen_flush_pending_ = false; |
| 629 data.Execute(PP_OK); | 642 data.Execute(PP_OK); |
| 630 } | 643 } |
| 631 | 644 |
| 632 bool Graphics2D::HasPendingFlush() const { | 645 bool PPB_Graphics2D_Impl::HasPendingFlush() const { |
| 633 return !unpainted_flush_callback_.is_null() || | 646 return !unpainted_flush_callback_.is_null() || |
| 634 !painted_flush_callback_.is_null() || | 647 !painted_flush_callback_.is_null() || |
| 635 offscreen_flush_pending_; | 648 offscreen_flush_pending_; |
| 636 } | 649 } |
| 637 | 650 |
| 638 } // namespace pepper | 651 } // namespace ppapi |
| 652 } // namespace plugins |
| 653 } // namespace webkit |
| 654 |
| OLD | NEW |