aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-11 14:38:51 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-11 14:38:51 +0000
commit458849004892c05fa1dcbcf6d355dfcce028d77a (patch)
tree3b8862ceb2725bea7916967498e52327cc3b5151 /src
parenta1c6ff4922251065c45e3323e17e985a62931fc7 (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
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBlitter.cpp71
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;