diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-11 14:38:51 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-11 14:38:51 +0000 |
commit | 458849004892c05fa1dcbcf6d355dfcce028d77a (patch) | |
tree | 3b8862ceb2725bea7916967498e52327cc3b5151 | |
parent | a1c6ff4922251065c45e3323e17e985a62931fc7 (diff) |
lazily make a copy of the paint when choosing a blitter. For simple draws,
this is never actually needed, and it is faster to skip the copy.
git-svn-id: http://skia.googlecode.com/svn/trunk@3908 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/core/SkBlitter.cpp | 71 |
1 files changed, 45 insertions, 26 deletions
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index 735ad0431f..8acdeb1112 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -14,6 +14,7 @@ #include "SkMask.h" #include "SkMaskFilter.h" #include "SkTemplatesPriv.h" +#include "SkTLazy.h" #include "SkUtils.h" #include "SkXfermode.h" @@ -839,24 +840,33 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device, return blitter; } - SkPaint paint(origPaint); - SkShader* shader = paint.getShader(); - SkColorFilter* cf = paint.getColorFilter(); - SkXfermode* mode = paint.getXfermode(); - + SkShader* shader = origPaint.getShader(); + SkColorFilter* cf = origPaint.getColorFilter(); + SkXfermode* mode = origPaint.getXfermode(); Sk3DShader* shader3D = NULL; - if (paint.getMaskFilter() != NULL && - paint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { + + SkTLazy<SkPaint> lazyPaint; + // we promise not to mutate paint unless we know we've reassigned it from + // lazyPaint + SkPaint* paint = const_cast<SkPaint*>(&origPaint); + + if (origPaint.getMaskFilter() != NULL && + origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { shader3D = SkNEW_ARGS(Sk3DShader, (shader)); - paint.setShader(shader3D)->unref(); + // we know we haven't initialized lazyPaint yet, so just do it + paint = lazyPaint.set(origPaint); + paint->setShader(shader3D)->unref(); shader = shader3D; } if (NULL != mode) { - switch (interpret_xfermode(paint, mode, device.config())) { + switch (interpret_xfermode(*paint, mode, device.config())) { case kSrcOver_XferInterp: mode = NULL; - paint.setXfermode(NULL); + if (!lazyPaint.isValid()) { + paint = lazyPaint.set(origPaint); + } + paint->setXfermode(NULL); break; case kSkipDrawing_XferInterp: SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); @@ -874,12 +884,18 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device, #endif // xfermodes (and filters) require shaders for our current blitters shader = SkNEW(SkColorShader); - paint.setShader(shader)->unref(); + if (!lazyPaint.isValid()) { + paint = lazyPaint.set(origPaint); + } + paint->setShader(shader)->unref(); } else if (cf) { // if no shader && no xfermode, we just apply the colorfilter to // our color and move on. - paint.setColor(cf->filterColor(paint.getColor())); - paint.setColorFilter(NULL); + if (!lazyPaint.isValid()) { + paint = lazyPaint.set(origPaint); + } + paint->setColor(cf->filterColor(paint->getColor())); + paint->setColorFilter(NULL); cf = NULL; } } @@ -887,52 +903,55 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device, if (cf) { SkASSERT(shader); shader = SkNEW_ARGS(SkFilterShader, (shader, cf)); - paint.setShader(shader)->unref(); + if (!lazyPaint.isValid()) { + paint = lazyPaint.set(origPaint); + } + paint->setShader(shader)->unref(); // blitters should ignore the presence/absence of a filter, since // if there is one, the shader will take care of it. } - if (shader && !shader->setContext(device, paint, matrix)) { + if (shader && !shader->setContext(device, *paint, matrix)) { return SkNEW(SkNullBlitter); } switch (device.getConfig()) { case SkBitmap::kA1_Config: SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter, - storage, storageSize, (device, paint)); + storage, storageSize, (device, *paint)); break; case SkBitmap::kA8_Config: if (shader) { SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Shader_Blitter, - storage, storageSize, (device, paint)); + storage, storageSize, (device, *paint)); } else { SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Blitter, - storage, storageSize, (device, paint)); + storage, storageSize, (device, *paint)); } break; case SkBitmap::kARGB_4444_Config: - blitter = SkBlitter_ChooseD4444(device, paint, storage, storageSize); + blitter = SkBlitter_ChooseD4444(device, *paint, storage, storageSize); break; case SkBitmap::kRGB_565_Config: - blitter = SkBlitter_ChooseD565(device, paint, storage, storageSize); + blitter = SkBlitter_ChooseD565(device, *paint, storage, storageSize); break; case SkBitmap::kARGB_8888_Config: if (shader) { SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Shader_Blitter, - storage, storageSize, (device, paint)); - } else if (paint.getColor() == SK_ColorBLACK) { + storage, storageSize, (device, *paint)); + } else if (paint->getColor() == SK_ColorBLACK) { SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Black_Blitter, - storage, storageSize, (device, paint)); - } else if (paint.getAlpha() == 0xFF) { + storage, storageSize, (device, *paint)); + } else if (paint->getAlpha() == 0xFF) { SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Opaque_Blitter, - storage, storageSize, (device, paint)); + storage, storageSize, (device, *paint)); } else { SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Blitter, - storage, storageSize, (device, paint)); + storage, storageSize, (device, *paint)); } break; |