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

Side by Side Diff: src/utils/SkDeferredCanvas.cpp

Issue 14263015: Fix crash with SkDeferredCanvas+SkSurface integration with in order draw buffer. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 8 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 | « no previous file | tests/DeferredCanvasTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2013 Google Inc. 3 * Copyright 2013 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkDeferredCanvas.h" 9 #include "SkDeferredCanvas.h"
10 10
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 //----------------------------------------------------------------------------- 139 //-----------------------------------------------------------------------------
140 class DeferredDevice : public SkDevice { 140 class DeferredDevice : public SkDevice {
141 public: 141 public:
142 explicit DeferredDevice(SkDevice* immediateDevice); 142 explicit DeferredDevice(SkDevice* immediateDevice);
143 explicit DeferredDevice(SkSurface* surface); 143 explicit DeferredDevice(SkSurface* surface);
144 ~DeferredDevice(); 144 ~DeferredDevice();
145 145
146 void setNotificationClient(SkDeferredCanvas::NotificationClient* notificatio nClient); 146 void setNotificationClient(SkDeferredCanvas::NotificationClient* notificatio nClient);
147 SkCanvas* recordingCanvas(); 147 SkCanvas* recordingCanvas();
148 SkCanvas* immediateCanvas() const {return fImmediateCanvas;} 148 SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
149 SkDevice* immediateDevice() const {return fImmediateDevice;} 149 SkDevice* immediateDevice() const {return fImmediateCanvas->getTopDevice();}
150 SkImage* newImageSnapshot(); 150 SkImage* newImageSnapshot();
151 bool isFreshFrame(); 151 bool isFreshFrame();
152 bool hasPendingCommands(); 152 bool hasPendingCommands();
153 size_t storageAllocatedForRecording() const; 153 size_t storageAllocatedForRecording() const;
154 size_t freeMemoryIfPossible(size_t bytesToFree); 154 size_t freeMemoryIfPossible(size_t bytesToFree);
155 size_t getBitmapSizeThreshold() const; 155 size_t getBitmapSizeThreshold() const;
156 void setBitmapSizeThreshold(size_t sizeThreshold); 156 void setBitmapSizeThreshold(size_t sizeThreshold);
157 void flushPendingCommands(PlaybackMode); 157 void flushPendingCommands(PlaybackMode);
158 void skipPendingCommands(); 158 void skipPendingCommands();
159 void setMaxRecordingStorage(size_t); 159 void setMaxRecordingStorage(size_t);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 const SkPaint&) 236 const SkPaint&)
237 {SkASSERT(0);} 237 {SkASSERT(0);}
238 private: 238 private:
239 virtual void flush(); 239 virtual void flush();
240 240
241 void beginRecording(); 241 void beginRecording();
242 void init(); 242 void init();
243 243
244 DeferredPipeController fPipeController; 244 DeferredPipeController fPipeController;
245 SkGPipeWriter fPipeWriter; 245 SkGPipeWriter fPipeWriter;
246 SkDevice* fImmediateDevice;
247 SkCanvas* fImmediateCanvas; 246 SkCanvas* fImmediateCanvas;
248 SkCanvas* fRecordingCanvas; 247 SkCanvas* fRecordingCanvas;
249 SkSurface* fSurface; 248 SkSurface* fSurface;
250 SkDeferredCanvas::NotificationClient* fNotificationClient; 249 SkDeferredCanvas::NotificationClient* fNotificationClient;
251 bool fFreshFrame; 250 bool fFreshFrame;
252 size_t fMaxRecordingStorageBytes; 251 size_t fMaxRecordingStorageBytes;
253 size_t fPreviousStorageAllocated; 252 size_t fPreviousStorageAllocated;
254 size_t fBitmapSizeThreshold; 253 size_t fBitmapSizeThreshold;
255 }; 254 };
256 255
257 DeferredDevice::DeferredDevice(SkDevice* immediateDevice) 256 DeferredDevice::DeferredDevice(SkDevice* immediateDevice)
258 : SkDevice(SkBitmap::kNo_Config, 257 : SkDevice(SkBitmap::kNo_Config,
259 immediateDevice->width(), immediateDevice->height(), 258 immediateDevice->width(), immediateDevice->height(),
260 immediateDevice->isOpaque(), 259 immediateDevice->isOpaque(),
261 immediateDevice->getDeviceProperties()) { 260 immediateDevice->getDeviceProperties()) {
262 fSurface = NULL; 261 fSurface = NULL;
263 fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas 262 fImmediateCanvas = SkNEW_ARGS(SkCanvas, (immediateDevice));
264 fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice));
265 this->init(); 263 this->init();
266 } 264 }
267 265
268 DeferredDevice::DeferredDevice(SkSurface* surface) 266 DeferredDevice::DeferredDevice(SkSurface* surface)
269 : SkDevice(SkBitmap::kNo_Config, 267 : SkDevice(SkBitmap::kNo_Config,
270 surface->getCanvas()->getDevice()->width(), 268 surface->getCanvas()->getDevice()->width(),
271 surface->getCanvas()->getDevice()->height(), 269 surface->getCanvas()->getDevice()->height(),
272 surface->getCanvas()->getDevice()->isOpaque(), 270 surface->getCanvas()->getDevice()->isOpaque(),
273 surface->getCanvas()->getDevice()->getDeviceProperties()) { 271 surface->getCanvas()->getDevice()->getDeviceProperties()) {
274 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; 272 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
275 fNotificationClient = NULL; 273 fNotificationClient = NULL;
276 fImmediateCanvas = surface->getCanvas(); 274 fImmediateCanvas = surface->getCanvas();
277 SkSafeRef(fImmediateCanvas); 275 SkSafeRef(fImmediateCanvas);
278 fSurface = surface; 276 fSurface = surface;
279 SkSafeRef(fSurface); 277 SkSafeRef(fSurface);
280 fImmediateDevice = fImmediateCanvas->getDevice(); // ref counted via fImmed iateCanvas
281 this->init(); 278 this->init();
282 } 279 }
283 280
284 void DeferredDevice::init() { 281 void DeferredDevice::init() {
285 fRecordingCanvas = NULL; 282 fRecordingCanvas = NULL;
286 fFreshFrame = true; 283 fFreshFrame = true;
287 fPreviousStorageAllocated = 0; 284 fPreviousStorageAllocated = 0;
288 fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold; 285 fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
289 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; 286 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
290 fNotificationClient = NULL; 287 fNotificationClient = NULL;
291 fPipeController.setPlaybackCanvas(fImmediateCanvas); 288 fPipeController.setPlaybackCanvas(fImmediateCanvas);
292 this->beginRecording(); 289 this->beginRecording();
293 } 290 }
294 291
295 DeferredDevice::~DeferredDevice() { 292 DeferredDevice::~DeferredDevice() {
296 this->flushPendingCommands(kSilent_PlaybackMode); 293 this->flushPendingCommands(kSilent_PlaybackMode);
297 SkSafeUnref(fImmediateCanvas); 294 SkSafeUnref(fImmediateCanvas);
298 SkSafeUnref(fSurface); 295 SkSafeUnref(fSurface);
299 } 296 }
300 297
301 void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) { 298 void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) {
302 fMaxRecordingStorageBytes = maxStorage; 299 fMaxRecordingStorageBytes = maxStorage;
303 this->recordingCanvas(); // Accessing the recording canvas applies the new l imit. 300 this->recordingCanvas(); // Accessing the recording canvas applies the new l imit.
304 } 301 }
305 302
306 void DeferredDevice::beginRecording() { 303 void DeferredDevice::beginRecording() {
307 SkASSERT(NULL == fRecordingCanvas); 304 SkASSERT(NULL == fRecordingCanvas);
308 fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0, 305 fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0,
309 fImmediateDevice->width(), fImmediateDevice->height()); 306 immediateDevice()->width(), immediateDevice()->height());
310 } 307 }
311 308
312 void DeferredDevice::setNotificationClient( 309 void DeferredDevice::setNotificationClient(
313 SkDeferredCanvas::NotificationClient* notificationClient) { 310 SkDeferredCanvas::NotificationClient* notificationClient) {
314 fNotificationClient = notificationClient; 311 fNotificationClient = notificationClient;
315 } 312 }
316 313
317 void DeferredDevice::skipPendingCommands() { 314 void DeferredDevice::skipPendingCommands() {
318 if (!fRecordingCanvas->isDrawingToLayer() && fPipeController.hasPendingComma nds()) { 315 if (!fRecordingCanvas->isDrawingToLayer() && fPipeController.hasPendingComma nds()) {
319 fFreshFrame = true; 316 fFreshFrame = true;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 SkCanvas* DeferredDevice::recordingCanvas() { 396 SkCanvas* DeferredDevice::recordingCanvas() {
400 return fRecordingCanvas; 397 return fRecordingCanvas;
401 } 398 }
402 399
403 SkImage* DeferredDevice::newImageSnapshot() { 400 SkImage* DeferredDevice::newImageSnapshot() {
404 this->flush(); 401 this->flush();
405 return fSurface ? fSurface->newImageSnapshot() : NULL; 402 return fSurface ? fSurface->newImageSnapshot() : NULL;
406 } 403 }
407 404
408 uint32_t DeferredDevice::getDeviceCapabilities() { 405 uint32_t DeferredDevice::getDeviceCapabilities() {
409 return fImmediateDevice->getDeviceCapabilities(); 406 return immediateDevice()->getDeviceCapabilities();
410 } 407 }
411 408
412 int DeferredDevice::width() const { 409 int DeferredDevice::width() const {
413 return fImmediateDevice->width(); 410 return immediateDevice()->width();
414 } 411 }
415 412
416 int DeferredDevice::height() const { 413 int DeferredDevice::height() const {
417 return fImmediateDevice->height(); 414 return immediateDevice()->height();
418 } 415 }
419 416
420 SkGpuRenderTarget* DeferredDevice::accessRenderTarget() { 417 SkGpuRenderTarget* DeferredDevice::accessRenderTarget() {
421 this->flushPendingCommands(kNormal_PlaybackMode); 418 this->flushPendingCommands(kNormal_PlaybackMode);
422 return fImmediateDevice->accessRenderTarget(); 419 return immediateDevice()->accessRenderTarget();
423 } 420 }
424 421
425 void DeferredDevice::writePixels(const SkBitmap& bitmap, 422 void DeferredDevice::writePixels(const SkBitmap& bitmap,
426 int x, int y, SkCanvas::Config8888 config8888) { 423 int x, int y, SkCanvas::Config8888 config8888) {
427 424
428 if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() && 425 if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() &&
429 (y + bitmap.height()) >= height()) { 426 (y + bitmap.height()) >= height()) {
430 this->skipPendingCommands(); 427 this->skipPendingCommands();
431 } 428 }
432 429
433 if (SkBitmap::kARGB_8888_Config == bitmap.config() && 430 if (SkBitmap::kARGB_8888_Config == bitmap.config() &&
434 SkCanvas::kNative_Premul_Config8888 != config8888 && 431 SkCanvas::kNative_Premul_Config8888 != config8888 &&
435 kPMColorAlias != config8888) { 432 kPMColorAlias != config8888) {
436 //Special case config: no deferral 433 //Special case config: no deferral
437 this->flushPendingCommands(kNormal_PlaybackMode); 434 this->flushPendingCommands(kNormal_PlaybackMode);
438 fImmediateDevice->writePixels(bitmap, x, y, config8888); 435 immediateDevice()->writePixels(bitmap, x, y, config8888);
439 return; 436 return;
440 } 437 }
441 438
442 SkPaint paint; 439 SkPaint paint;
443 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 440 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
444 if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) { 441 if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) {
445 this->flushPendingCommands(kNormal_PlaybackMode); 442 this->flushPendingCommands(kNormal_PlaybackMode);
446 fImmediateCanvas->drawSprite(bitmap, x, y, &paint); 443 fImmediateCanvas->drawSprite(bitmap, x, y, &paint);
447 } else { 444 } else {
448 this->recordingCanvas()->drawSprite(bitmap, x, y, &paint); 445 this->recordingCanvas()->drawSprite(bitmap, x, y, &paint);
449 this->recordedDrawCommand(); 446 this->recordedDrawCommand();
450 447
451 } 448 }
452 } 449 }
453 450
454 const SkBitmap& DeferredDevice::onAccessBitmap(SkBitmap*) { 451 const SkBitmap& DeferredDevice::onAccessBitmap(SkBitmap*) {
455 this->flushPendingCommands(kNormal_PlaybackMode); 452 this->flushPendingCommands(kNormal_PlaybackMode);
456 return fImmediateDevice->accessBitmap(false); 453 return immediateDevice()->accessBitmap(false);
457 } 454 }
458 455
459 SkDevice* DeferredDevice::onCreateCompatibleDevice( 456 SkDevice* DeferredDevice::onCreateCompatibleDevice(
460 SkBitmap::Config config, int width, int height, bool isOpaque, 457 SkBitmap::Config config, int width, int height, bool isOpaque,
461 Usage usage) { 458 Usage usage) {
462 459
463 // Save layer usage not supported, and not required by SkDeferredCanvas. 460 // Save layer usage not supported, and not required by SkDeferredCanvas.
464 SkASSERT(usage != kSaveLayer_Usage); 461 SkASSERT(usage != kSaveLayer_Usage);
465 // Create a compatible non-deferred device. 462 // Create a compatible non-deferred device.
466 SkAutoTUnref<SkDevice> compatibleDevice 463 SkAutoTUnref<SkDevice> compatibleDevice
467 (fImmediateDevice->createCompatibleDevice(config, width, height, 464 (immediateDevice()->createCompatibleDevice(config, width, height,
468 isOpaque)); 465 isOpaque));
469 DeferredDevice* device = SkNEW_ARGS(DeferredDevice, (compatibleDevice)); 466 DeferredDevice* device = SkNEW_ARGS(DeferredDevice, (compatibleDevice));
470 device->setNotificationClient(fNotificationClient); 467 device->setNotificationClient(fNotificationClient);
471 return device; 468 return device;
472 } 469 }
473 470
474 bool DeferredDevice::onReadPixels( 471 bool DeferredDevice::onReadPixels(
475 const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { 472 const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) {
476 this->flushPendingCommands(kNormal_PlaybackMode); 473 this->flushPendingCommands(kNormal_PlaybackMode);
477 return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap), 474 return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap),
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { 954 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
958 this->drawingCanvas()->setDrawFilter(filter); 955 this->drawingCanvas()->setDrawFilter(filter);
959 this->INHERITED::setDrawFilter(filter); 956 this->INHERITED::setDrawFilter(filter);
960 this->recordedDrawCommand(); 957 this->recordedDrawCommand();
961 return filter; 958 return filter;
962 } 959 }
963 960
964 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { 961 SkCanvas* SkDeferredCanvas::canvasForDrawIter() {
965 return this->drawingCanvas(); 962 return this->drawingCanvas();
966 } 963 }
OLDNEW
« no previous file with comments | « no previous file | tests/DeferredCanvasTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698