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

Side by Side Diff: src/core/SkCanvas.cpp

Issue 1091173003: apply xfermode after imagefilter when we create a tmp layer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 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
« no previous file with comments | « no previous file | no next file » | 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 * Copyright 2008 The Android Open Source Project 2 * Copyright 2008 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkCanvas.h" 8 #include "SkCanvas.h"
9 #include "SkCanvasPriv.h" 9 #include "SkCanvasPriv.h"
10 #include "SkBitmapDevice.h" 10 #include "SkBitmapDevice.h"
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 301
302 class AutoDrawLooper { 302 class AutoDrawLooper {
303 public: 303 public:
304 AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, 304 AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint,
305 bool skipLayerForImageFilter = false, 305 bool skipLayerForImageFilter = false,
306 const SkRect* bounds = NULL) : fOrigPaint(paint) { 306 const SkRect* bounds = NULL) : fOrigPaint(paint) {
307 fCanvas = canvas; 307 fCanvas = canvas;
308 fFilter = canvas->getDrawFilter(); 308 fFilter = canvas->getDrawFilter();
309 fPaint = &fOrigPaint; 309 fPaint = &fOrigPaint;
310 fSaveCount = canvas->getSaveCount(); 310 fSaveCount = canvas->getSaveCount();
311 fDoClearImageFilter = false; 311 fTempLayerForImageFilter = false;
312 fDone = false; 312 fDone = false;
313 313
314 if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { 314 if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) {
315 /**
316 * We implement ImageFilters for a given draw by creating a layer, then applying the
317 * imagefilter to the pixels of that layer (its backing surface/ima ge), and then
318 * we call restore() to apply that layer to the main canvas.
319 *
320 * To generate the src pixels for the filter, we remove the imagefi lter and the
321 * xfermode from the paint that we (AutoDrawLooper) return (fPaint) . The imagefilter
322 * is applied right before the restore, and the xfermode is applied during the restore.
Stephen White 2015/04/20 14:36:46 Nit: this might be slightly misleading: the imagef
reed1 2015/04/20 14:49:19 Done.
323 *
324 * We strip the imagefilter/xfermode inside doNext().
325 */
315 SkPaint tmp; 326 SkPaint tmp;
327 // store the imagefilter/xfermode on the layer's paint, so they can be applied in
328 // restore.
316 tmp.setImageFilter(fOrigPaint.getImageFilter()); 329 tmp.setImageFilter(fOrigPaint.getImageFilter());
330 tmp.setXfermode(fOrigPaint.getXfermode());
317 (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLa yer_SaveFlag, 331 (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLa yer_SaveFlag,
318 SkCanvas::kFullLayer_SaveLayerStrate gy); 332 SkCanvas::kFullLayer_SaveLayerStrate gy);
319 // we'll clear the imageFilter for the actual draws in next(), so 333 fTempLayerForImageFilter = true;
Stephen White 2015/04/20 14:36:46 This name is much clearer to me; thanks for that!
320 // it will only be applied during the restore().
321 fDoClearImageFilter = true;
322 } 334 }
323 335
324 if (SkDrawLooper* looper = paint.getLooper()) { 336 if (SkDrawLooper* looper = paint.getLooper()) {
325 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex t>( 337 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex t>(
326 looper->contextSize()); 338 looper->contextSize());
327 fLooperContext = looper->createContext(canvas, buffer); 339 fLooperContext = looper->createContext(canvas, buffer);
328 fIsSimple = false; 340 fIsSimple = false;
329 } else { 341 } else {
330 fLooperContext = NULL; 342 fLooperContext = NULL;
331 // can we be marked as simple? 343 // can we be marked as simple?
332 fIsSimple = !fFilter && !fDoClearImageFilter; 344 fIsSimple = !fFilter && !fTempLayerForImageFilter;
333 } 345 }
334 346
335 uint32_t oldFlags = paint.getFlags(); 347 uint32_t oldFlags = paint.getFlags();
336 fNewPaintFlags = filter_paint_flags(props, oldFlags); 348 fNewPaintFlags = filter_paint_flags(props, oldFlags);
337 if (fIsSimple && (fNewPaintFlags != oldFlags)) { 349 if (fIsSimple && (fNewPaintFlags != oldFlags)) {
338 SkPaint* paint = fLazyPaint.set(fOrigPaint); 350 SkPaint* paint = fLazyPaint.set(fOrigPaint);
339 paint->setFlags(fNewPaintFlags); 351 paint->setFlags(fNewPaintFlags);
340 fPaint = paint; 352 fPaint = paint;
341 // if we're not simple, doNext() will take care of calling setFlags( ) 353 // if we're not simple, doNext() will take care of calling setFlags( )
342 } 354 }
343 } 355 }
344 356
345 ~AutoDrawLooper() { 357 ~AutoDrawLooper() {
346 if (fDoClearImageFilter) { 358 if (fTempLayerForImageFilter) {
347 fCanvas->internalRestore(); 359 fCanvas->internalRestore();
348 } 360 }
349 SkASSERT(fCanvas->getSaveCount() == fSaveCount); 361 SkASSERT(fCanvas->getSaveCount() == fSaveCount);
350 } 362 }
351 363
352 const SkPaint& paint() const { 364 const SkPaint& paint() const {
353 SkASSERT(fPaint); 365 SkASSERT(fPaint);
354 return *fPaint; 366 return *fPaint;
355 } 367 }
356 368
357 bool next(SkDrawFilter::Type drawType) { 369 bool next(SkDrawFilter::Type drawType) {
358 if (fDone) { 370 if (fDone) {
359 return false; 371 return false;
360 } else if (fIsSimple) { 372 } else if (fIsSimple) {
361 fDone = true; 373 fDone = true;
362 return !fPaint->nothingToDraw(); 374 return !fPaint->nothingToDraw();
363 } else { 375 } else {
364 return this->doNext(drawType); 376 return this->doNext(drawType);
365 } 377 }
366 } 378 }
367 379
368 private: 380 private:
369 SkLazyPaint fLazyPaint; 381 SkLazyPaint fLazyPaint;
370 SkCanvas* fCanvas; 382 SkCanvas* fCanvas;
371 const SkPaint& fOrigPaint; 383 const SkPaint& fOrigPaint;
372 SkDrawFilter* fFilter; 384 SkDrawFilter* fFilter;
373 const SkPaint* fPaint; 385 const SkPaint* fPaint;
374 int fSaveCount; 386 int fSaveCount;
375 uint32_t fNewPaintFlags; 387 uint32_t fNewPaintFlags;
376 bool fDoClearImageFilter; 388 bool fTempLayerForImageFilter;
377 bool fDone; 389 bool fDone;
378 bool fIsSimple; 390 bool fIsSimple;
379 SkDrawLooper::Context* fLooperContext; 391 SkDrawLooper::Context* fLooperContext;
380 SkSmallAllocator<1, 32> fLooperContextAllocator; 392 SkSmallAllocator<1, 32> fLooperContextAllocator;
381 393
382 bool doNext(SkDrawFilter::Type drawType); 394 bool doNext(SkDrawFilter::Type drawType);
383 }; 395 };
384 396
385 bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 397 bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) {
386 fPaint = NULL; 398 fPaint = NULL;
387 SkASSERT(!fIsSimple); 399 SkASSERT(!fIsSimple);
388 SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); 400 SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter);
389 401
390 SkPaint* paint = fLazyPaint.set(fOrigPaint); 402 SkPaint* paint = fLazyPaint.set(fOrigPaint);
391 paint->setFlags(fNewPaintFlags); 403 paint->setFlags(fNewPaintFlags);
392 404
393 if (fDoClearImageFilter) { 405 if (fTempLayerForImageFilter) {
394 paint->setImageFilter(NULL); 406 paint->setImageFilter(NULL);
407 paint->setXfermode(NULL);
395 } 408 }
396 409
397 if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 410 if (fLooperContext && !fLooperContext->next(fCanvas, paint)) {
398 fDone = true; 411 fDone = true;
399 return false; 412 return false;
400 } 413 }
401 if (fFilter) { 414 if (fFilter) {
402 if (!fFilter->filter(paint, drawType)) { 415 if (!fFilter->filter(paint, drawType)) {
403 fDone = true; 416 fDone = true;
404 return false; 417 return false;
(...skipping 2155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2560 } 2573 }
2561 2574
2562 if (matrix) { 2575 if (matrix) {
2563 canvas->concat(*matrix); 2576 canvas->concat(*matrix);
2564 } 2577 }
2565 } 2578 }
2566 2579
2567 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2580 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
2568 fCanvas->restoreToCount(fSaveCount); 2581 fCanvas->restoreToCount(fSaveCount);
2569 } 2582 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698