Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(542)

Side by Side Diff: webkit/glue/plugins/pepper_device_context_2d.cc

Issue 2080021: Chrome-side of tests for Pepper Device2D. This includes some bugfixes and min... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/glue/plugins/pepper_device_context_2d.h ('k') | webkit/glue/plugins/pepper_image_data.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "base/logging.h" 7 #include "base/logging.h"
8 #include "gfx/point.h" 8 #include "gfx/point.h"
9 #include "gfx/rect.h" 9 #include "gfx/rect.h"
10 #include "skia/ext/platform_canvas.h" 10 #include "skia/ext/platform_canvas.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 if (!module) 63 if (!module)
64 return NULL; 64 return NULL;
65 65
66 scoped_refptr<DeviceContext2D> context(new DeviceContext2D(module)); 66 scoped_refptr<DeviceContext2D> context(new DeviceContext2D(module));
67 if (!context->Init(width, height, is_always_opaque)) 67 if (!context->Init(width, height, is_always_opaque))
68 return NULL; 68 return NULL;
69 context->AddRef(); // AddRef for the caller. 69 context->AddRef(); // AddRef for the caller.
70 return context->GetResource(); 70 return context->GetResource();
71 } 71 }
72 72
73 bool Describe(PP_Resource device_context,
74 int32_t* width, int32_t* height, bool* is_always_opaque) {
75 scoped_refptr<DeviceContext2D> context(
76 ResourceTracker::Get()->GetAsDeviceContext2D(device_context));
77 if (!context.get())
78 return false;
79 return context->Describe(width, height, is_always_opaque);
80 }
81
73 bool PaintImageData(PP_Resource device_context, 82 bool PaintImageData(PP_Resource device_context,
74 PP_Resource image, 83 PP_Resource image,
75 int32_t x, int32_t y, 84 int32_t x, int32_t y,
76 const PP_Rect* src_rect) { 85 const PP_Rect* src_rect) {
77 scoped_refptr<DeviceContext2D> context( 86 scoped_refptr<DeviceContext2D> context(
78 ResourceTracker::Get()->GetAsDeviceContext2D(device_context)); 87 ResourceTracker::Get()->GetAsDeviceContext2D(device_context));
79 if (!context.get()) 88 if (!context.get())
80 return false; 89 return false;
81 return context->PaintImageData(image, x, y, src_rect); 90 return context->PaintImageData(image, x, y, src_rect);
82 } 91 }
(...skipping 19 matching lines...) Expand all
102 bool Flush(PP_Resource device_context, 111 bool Flush(PP_Resource device_context,
103 PPB_DeviceContext2D_FlushCallback callback, 112 PPB_DeviceContext2D_FlushCallback callback,
104 void* callback_data) { 113 void* callback_data) {
105 scoped_refptr<DeviceContext2D> context( 114 scoped_refptr<DeviceContext2D> context(
106 ResourceTracker::Get()->GetAsDeviceContext2D(device_context)); 115 ResourceTracker::Get()->GetAsDeviceContext2D(device_context));
107 if (!context.get()) 116 if (!context.get())
108 return false; 117 return false;
109 return context->Flush(callback, callback_data); 118 return context->Flush(callback, callback_data);
110 } 119 }
111 120
121 bool ReadImageData(PP_Resource device_context,
122 PP_Resource image,
123 int32_t x, int32_t y) {
124 scoped_refptr<DeviceContext2D> context(
125 ResourceTracker::Get()->GetAsDeviceContext2D(device_context));
126 if (!context.get())
127 return false;
128 return context->ReadImageData(image, x, y);
129 }
130
112 const PPB_DeviceContext2D ppb_devicecontext2d = { 131 const PPB_DeviceContext2D ppb_devicecontext2d = {
113 &Create, 132 &Create,
133 &Describe,
114 &PaintImageData, 134 &PaintImageData,
115 &Scroll, 135 &Scroll,
116 &ReplaceContents, 136 &ReplaceContents,
117 &Flush 137 &Flush,
138 &ReadImageData
118 }; 139 };
119 140
120 } // namespace 141 } // namespace
121 142
122 struct DeviceContext2D::QueuedOperation { 143 struct DeviceContext2D::QueuedOperation {
123 enum Type { 144 enum Type {
124 PAINT, 145 PAINT,
125 SCROLL, 146 SCROLL,
126 REPLACE 147 REPLACE
127 }; 148 };
(...skipping 26 matching lines...) Expand all
154 175
155 DeviceContext2D::~DeviceContext2D() { 176 DeviceContext2D::~DeviceContext2D() {
156 } 177 }
157 178
158 // static 179 // static
159 const PPB_DeviceContext2D* DeviceContext2D::GetInterface() { 180 const PPB_DeviceContext2D* DeviceContext2D::GetInterface() {
160 return &ppb_devicecontext2d; 181 return &ppb_devicecontext2d;
161 } 182 }
162 183
163 bool DeviceContext2D::Init(int width, int height, bool is_always_opaque) { 184 bool DeviceContext2D::Init(int width, int height, bool is_always_opaque) {
185 // The underlying ImageData will validate the dimensions.
164 image_data_ = new ImageData(module()); 186 image_data_ = new ImageData(module());
165 if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height, true) || 187 if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height, true) ||
166 !image_data_->Map()) { 188 !image_data_->Map()) {
167 image_data_ = NULL; 189 image_data_ = NULL;
168 return false; 190 return false;
169 } 191 }
170 192
171 return true; 193 return true;
172 } 194 }
173 195
196 bool DeviceContext2D::Describe(int32_t* width, int32_t* height,
197 bool* is_always_opaque) {
198 *width = image_data_->width();
199 *height = image_data_->height();
200 *is_always_opaque = false; // TODO(brettw) implement this.
201 return true;
202 }
203
174 bool DeviceContext2D::PaintImageData(PP_Resource image, 204 bool DeviceContext2D::PaintImageData(PP_Resource image,
175 int32_t x, int32_t y, 205 int32_t x, int32_t y,
176 const PP_Rect* src_rect) { 206 const PP_Rect* src_rect) {
177 scoped_refptr<ImageData> image_resource( 207 scoped_refptr<ImageData> image_resource(
178 ResourceTracker::Get()->GetAsImageData(image)); 208 ResourceTracker::Get()->GetAsImageData(image));
179 if (!image_resource.get() || !image_resource->is_valid()) 209 if (!image_resource.get())
180 return false; 210 return false;
181 211
182 const SkBitmap& new_image_bitmap = image_resource->GetMappedBitmap();
183
184 QueuedOperation operation(QueuedOperation::PAINT); 212 QueuedOperation operation(QueuedOperation::PAINT);
185 operation.paint_image = image_resource; 213 operation.paint_image = image_resource;
186 if (!ValidateAndConvertRect(src_rect, new_image_bitmap.width(), 214 if (!ValidateAndConvertRect(src_rect, image_resource->width(),
187 new_image_bitmap.height(), 215 image_resource->height(),
188 &operation.paint_src_rect)) 216 &operation.paint_src_rect))
189 return false; 217 return false;
190 218
191 // Validate the bitmap position using the previously-validated rect. 219 // Validate the bitmap position using the previously-validated rect, there
192 if (x < 0 || 220 // should be no painted area outside of the image.
193 static_cast<int64>(x) + 221 int64 x64 = static_cast<int64>(x), y64 = static_cast<int64>(y);
194 static_cast<int64>(operation.paint_src_rect.right()) > 222 if (x64 + static_cast<int64>(operation.paint_src_rect.x()) < 0 ||
223 x64 + static_cast<int64>(operation.paint_src_rect.right()) >
195 image_data_->width()) 224 image_data_->width())
196 return false; 225 return false;
197 if (y < 0 || 226 if (y64 + static_cast<int64>(operation.paint_src_rect.y()) < 0 ||
198 static_cast<int64>(y) + 227 y64 + static_cast<int64>(operation.paint_src_rect.bottom()) >
199 static_cast<int64>(operation.paint_src_rect.bottom()) >
200 image_data_->height()) 228 image_data_->height())
201 return false; 229 return false;
202 operation.paint_x = x; 230 operation.paint_x = x;
203 operation.paint_y = y; 231 operation.paint_y = y;
204 232
205 queued_operations_.push_back(operation); 233 queued_operations_.push_back(operation);
206 return true; 234 return true;
207 } 235 }
208 236
209 bool DeviceContext2D::Scroll(const PP_Rect* clip_rect, 237 bool DeviceContext2D::Scroll(const PP_Rect* clip_rect,
(...skipping 14 matching lines...) Expand all
224 operation.scroll_dx = dx; 252 operation.scroll_dx = dx;
225 operation.scroll_dy = dy; 253 operation.scroll_dy = dy;
226 254
227 queued_operations_.push_back(operation); 255 queued_operations_.push_back(operation);
228 return false; 256 return false;
229 } 257 }
230 258
231 bool DeviceContext2D::ReplaceContents(PP_Resource image) { 259 bool DeviceContext2D::ReplaceContents(PP_Resource image) {
232 scoped_refptr<ImageData> image_resource( 260 scoped_refptr<ImageData> image_resource(
233 ResourceTracker::Get()->GetAsImageData(image)); 261 ResourceTracker::Get()->GetAsImageData(image));
234 if (!image_resource.get() || !image_resource->is_valid()) 262 if (!image_resource.get())
263 return false;
264 if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL)
235 return false; 265 return false;
236 266
237 if (image_resource->width() != image_data_->width() || 267 if (image_resource->width() != image_data_->width() ||
238 image_resource->height() != image_data_->height()) 268 image_resource->height() != image_data_->height())
239 return false; 269 return false;
240 270
241 QueuedOperation operation(QueuedOperation::REPLACE); 271 QueuedOperation operation(QueuedOperation::REPLACE);
242 operation.replace_image = new ImageData(image_resource->module()); 272 operation.replace_image = image_resource;
243 queued_operations_.push_back(operation); 273 queued_operations_.push_back(operation);
244 274
245 // Swap the input image data with the new one we just made in the 275 return true;
246 // QueuedOperation. This way the plugin still gets to manage the reference
247 // count of the old object without having memory released out from under it.
248 // But it ensures that after this, if the plugin does try to use the image
249 // it gave us, those operations will fail.
250 operation.replace_image->Swap(image_resource.get());
251
252 return false;
253 } 276 }
254 277
255 bool DeviceContext2D::Flush(PPB_DeviceContext2D_FlushCallback callback, 278 bool DeviceContext2D::Flush(PPB_DeviceContext2D_FlushCallback callback,
256 void* callback_data) { 279 void* callback_data) {
257 for (size_t i = 0; i < queued_operations_.size(); i++) { 280 for (size_t i = 0; i < queued_operations_.size(); i++) {
258 QueuedOperation& operation = queued_operations_[i]; 281 QueuedOperation& operation = queued_operations_[i];
259 switch (operation.type) { 282 switch (operation.type) {
260 case QueuedOperation::PAINT: 283 case QueuedOperation::PAINT:
261 ExecutePaintImageData(operation.paint_image.get(), 284 ExecutePaintImageData(operation.paint_image.get(),
262 operation.paint_x, operation.paint_y, 285 operation.paint_x, operation.paint_y,
(...skipping 23 matching lines...) Expand all
286 // Save the callback to execute later. See |unpainted_flush_callbacks_| in 309 // Save the callback to execute later. See |unpainted_flush_callbacks_| in
287 // the header file. 310 // the header file.
288 if (callback) { 311 if (callback) {
289 unpainted_flush_callbacks_.push_back( 312 unpainted_flush_callbacks_.push_back(
290 FlushCallbackData(callback, id, context, user_data)); 313 FlushCallbackData(callback, id, context, user_data));
291 } 314 }
292 */ 315 */
293 return true; 316 return true;
294 } 317 }
295 318
319 bool DeviceContext2D::ReadImageData(PP_Resource image, int32_t x, int32_t y) {
320 // Get and validate the image object to paint into.
321 scoped_refptr<ImageData> image_resource(
322 ResourceTracker::Get()->GetAsImageData(image));
323 if (!image_resource.get())
324 return false;
325 if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL)
326 return false; // Must be in the right format.
327
328 // Validate the bitmap position.
329 if (x < 0 ||
330 static_cast<int64>(x) + static_cast<int64>(image_resource->width()) >
331 image_data_->width())
332 return false;
333 if (y < 0 ||
334 static_cast<int64>(y) + static_cast<int64>(image_resource->height()) >
335 image_data_->height())
336 return false;
337
338 ImageDataAutoMapper auto_mapper(image_resource.get());
339 if (!auto_mapper.is_valid())
340 return false;
341 skia::PlatformCanvas* dest_canvas = image_resource->mapped_canvas();
342
343 SkIRect src_irect = { x, y,
344 x + image_resource->width(),
345 y + image_resource->height() };
346 SkRect dest_rect = { SkIntToScalar(0),
347 SkIntToScalar(0),
348 SkIntToScalar(image_resource->width()),
349 SkIntToScalar(image_resource->height()) };
350
351 // We want to replace the contents of the bitmap rather than blend.
352 SkPaint paint;
353 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
354 dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(),
355 &src_irect, dest_rect, &paint);
356 return true;
357 }
358
296 void DeviceContext2D::Paint(WebKit::WebCanvas* canvas, 359 void DeviceContext2D::Paint(WebKit::WebCanvas* canvas,
297 const gfx::Rect& plugin_rect, 360 const gfx::Rect& plugin_rect,
298 const gfx::Rect& paint_rect) { 361 const gfx::Rect& paint_rect) {
299 // We're guaranteed to have a mapped canvas since we mapped it in Init(). 362 // We're guaranteed to have a mapped canvas since we mapped it in Init().
300 const SkBitmap& backing_bitmap = image_data_->GetMappedBitmap(); 363 const SkBitmap& backing_bitmap = *image_data_->GetMappedBitmap();
301 364
302 #if defined(OS_MACOSX) 365 #if defined(OS_MACOSX)
303 SkAutoLockPixels lock(backing_bitmap); 366 SkAutoLockPixels lock(backing_bitmap);
304 367
305 scoped_cftyperef<CGDataProviderRef> data_provider( 368 scoped_cftyperef<CGDataProviderRef> data_provider(
306 CGDataProviderCreateWithData( 369 CGDataProviderCreateWithData(
307 NULL, backing_bitmap.getAddr32(0, 0), 370 NULL, backing_bitmap.getAddr32(0, 0),
308 backing_bitmap.rowBytes() * backing_bitmap.height(), NULL)); 371 backing_bitmap.rowBytes() * backing_bitmap.height(), NULL));
309 scoped_cftyperef<CGImageRef> image( 372 scoped_cftyperef<CGImageRef> image(
310 CGImageCreate( 373 CGImageCreate(
(...skipping 19 matching lines...) Expand all
330 CGContextDrawImage(canvas, bounds, image); 393 CGContextDrawImage(canvas, bounds, image);
331 CGContextRestoreGState(canvas); 394 CGContextRestoreGState(canvas);
332 #else 395 #else
333 gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y()); 396 gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y());
334 canvas->drawBitmap(backing_bitmap, 397 canvas->drawBitmap(backing_bitmap,
335 SkIntToScalar(plugin_rect.origin().x()), 398 SkIntToScalar(plugin_rect.origin().x()),
336 SkIntToScalar(plugin_rect.origin().y())); 399 SkIntToScalar(plugin_rect.origin().y()));
337 #endif 400 #endif
338 } 401 }
339 402
340 403 void DeviceContext2D::ExecutePaintImageData(ImageData* image,
341 void DeviceContext2D::ExecutePaintImageData(const ImageData* image,
342 int x, int y, 404 int x, int y,
343 const gfx::Rect& src_rect) { 405 const gfx::Rect& src_rect) {
344 // Portion within the source image to cut out. 406 // Portion within the source image to cut out.
345 SkIRect src_irect = { src_rect.x(), src_rect.y(), 407 SkIRect src_irect = { src_rect.x(), src_rect.y(),
346 src_rect.right(), src_rect.bottom() }; 408 src_rect.right(), src_rect.bottom() };
347 409
348 // Location within the backing store to copy to. 410 // Location within the backing store to copy to.
349 SkRect dest_rect = { SkIntToScalar(x + src_rect.x()), 411 SkRect dest_rect = { SkIntToScalar(x + src_rect.x()),
350 SkIntToScalar(y + src_rect.y()), 412 SkIntToScalar(y + src_rect.y()),
351 SkIntToScalar(x + src_rect.right()), 413 SkIntToScalar(x + src_rect.right()),
352 SkIntToScalar(y + src_rect.bottom()) }; 414 SkIntToScalar(y + src_rect.bottom()) };
353 415
354 // We're guaranteed to have a mapped canvas since we mapped it in Init(). 416 // We're guaranteed to have a mapped canvas since we mapped it in Init().
355 skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas(); 417 skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas();
356 418
419 // Ensure the source image is mapped to read from it.
420 ImageDataAutoMapper auto_mapper(image);
421 if (!auto_mapper.is_valid())
422 return;
423
357 // We want to replace the contents of the bitmap rather than blend. 424 // We want to replace the contents of the bitmap rather than blend.
358 SkPaint paint; 425 SkPaint paint;
359 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 426 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
360 backing_canvas->drawBitmapRect(image->GetMappedBitmap(), 427 backing_canvas->drawBitmapRect(*image->GetMappedBitmap(),
361 &src_irect, dest_rect, &paint); 428 &src_irect, dest_rect, &paint);
362 } 429 }
363 430
364 void DeviceContext2D::ExecuteScroll(const gfx::Rect& clip, int dx, int dy) { 431 void DeviceContext2D::ExecuteScroll(const gfx::Rect& clip, int dx, int dy) {
365 // FIXME(brettw) 432 // FIXME(brettw)
366 } 433 }
367 434
368 void DeviceContext2D::ExecuteReplaceContents(ImageData* image) { 435 void DeviceContext2D::ExecuteReplaceContents(ImageData* image) {
369 image_data_->Swap(image); 436 image_data_->Swap(image);
370 } 437 }
371 438
372 } // namespace pepper 439 } // namespace pepper
OLDNEW
« no previous file with comments | « webkit/glue/plugins/pepper_device_context_2d.h ('k') | webkit/glue/plugins/pepper_image_data.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698