aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkBlitter.cpp
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-04-01 18:31:44 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-04-01 18:31:44 +0000
commitd252db03d9650013b545ef9781fe993c07f8f314 (patch)
tree85afe2a17d58115d5e62225487e27308c7ad5f82 /src/core/SkBlitter.cpp
parent6c924ad46c89955e78e071c792ef00df9910b42f (diff)
API change: SkPath computeBounds -> getBounds
git-svn-id: http://skia.googlecode.com/svn/trunk@140 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkBlitter.cpp')
-rw-r--r--src/core/SkBlitter.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index 920842937c..25303ac6b8 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -784,6 +784,64 @@ static void delete_blitter(void* blitter)
SkDELETE((SkBlitter*)blitter);
}
+static bool just_solid_color(const SkPaint& paint) {
+ if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) {
+ SkShader* shader = paint.getShader();
+ if (NULL == shader ||
+ (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/** By analyzing the paint (with an xfermode), we may decide we can take
+ special action. This enum lists our possible actions
+ */
+enum XferInterp {
+ kNormal_XferInterp, // no special interpretation, draw normally
+ kSrcOver_XferInterp, // draw as if in srcover mode
+ kSkipDrawing_XferInterp // draw nothing
+};
+
+static XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer,
+ SkBitmap::Config deviceConfig) {
+ SkPorterDuff::Mode mode;
+
+ if (SkPorterDuff::IsMode(xfer, &mode)) {
+ switch (mode) {
+ case SkPorterDuff::kSrc_Mode:
+ if (just_solid_color(paint)) {
+ return kSrcOver_XferInterp;
+ }
+ break;
+ case SkPorterDuff::kDst_Mode:
+ return kSkipDrawing_XferInterp;
+ case SkPorterDuff::kSrcOver_Mode:
+ return kSrcOver_XferInterp;
+ case SkPorterDuff::kDstOver_Mode:
+ if (SkBitmap::kRGB_565_Config == deviceConfig) {
+ return kSkipDrawing_XferInterp;
+ }
+ break;
+ case SkPorterDuff::kSrcIn_Mode:
+ if (SkBitmap::kRGB_565_Config == deviceConfig &&
+ just_solid_color(paint)) {
+ return kSrcOver_XferInterp;
+ }
+ break;
+ case SkPorterDuff::kDstIn_Mode:
+ if (just_solid_color(paint)) {
+ return kSkipDrawing_XferInterp;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return kNormal_XferInterp;
+}
+
SkBlitter* SkBlitter::Choose(const SkBitmap& device,
const SkMatrix& matrix,
const SkPaint& paint,
@@ -813,6 +871,19 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
}
SkXfermode* mode = paint.getXfermode();
+ if (NULL != mode) {
+ switch (interpret_xfermode(paint, mode, device.config())) {
+ case kSrcOver_XferInterp:
+ mode = NULL;
+ break;
+ case kSkipDrawing_XferInterp:
+ SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
+ return blitter;
+ default:
+ break;
+ }
+ }
+
if (NULL == shader && (NULL != mode || paint.getColorFilter() != NULL))
{
// xfermodes require shaders for our current set of blitters