aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-12 18:56:18 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-12 18:56:18 +0000
commit3bafe74a29c37761082980ed4ee9b831256bd27e (patch)
tree7033c0d28c67f52e811eb941599b1a0990c75b2c /src/core
parentcb1bbb375aa4fdd099dc60302ca1712f04607782 (diff)
Add SkShader::asShadeProc to fast-path the caller when the shader is fast
Review URL: https://codereview.appspot.com/6649055 git-svn-id: http://skia.googlecode.com/svn/trunk@5930 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkBitmapProcShader.cpp8
-rw-r--r--src/core/SkBitmapProcShader.h1
-rw-r--r--src/core/SkBlitter_ARGB32.cpp46
-rw-r--r--src/core/SkCoreBlitters.h7
-rw-r--r--src/core/SkShader.cpp4
5 files changed, 63 insertions, 3 deletions
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 43a6b0a7b9..66d9d7645d 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -203,6 +203,14 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
}
}
+SkShader::ShadeProc SkBitmapProcShader::asAShadeProc(void** ctx) {
+ if (fState.getShaderProc32()) {
+ *ctx = &fState;
+ return (ShadeProc)fState.getShaderProc32();
+ }
+ return NULL;
+}
+
void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) {
const SkBitmapProcState& state = fState;
if (state.getShaderProc16()) {
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
index e5e5f13a93..23e099250b 100644
--- a/src/core/SkBitmapProcShader.h
+++ b/src/core/SkBitmapProcShader.h
@@ -22,6 +22,7 @@ public:
virtual bool setContext(const SkBitmap&, const SkPaint&, const SkMatrix&);
virtual uint32_t getFlags() { return fFlags; }
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
+ virtual ShadeProc asAShadeProc(void** ctx) SK_OVERRIDE;
virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count);
virtual void beginSession();
virtual void endSession();
diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp
index 417c252d80..109b7ad885 100644
--- a/src/core/SkBlitter_ARGB32.cpp
+++ b/src/core/SkBlitter_ARGB32.cpp
@@ -303,6 +303,52 @@ void SkARGB32_Shader_Blitter::blitH(int x, int y, int width) {
}
}
+void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) {
+ SkASSERT(x >= 0 && y >= 0 &&
+ x + width <= fDevice.width() && y + height <= fDevice.height());
+
+ uint32_t* device = fDevice.getAddr32(x, y);
+ size_t deviceRB = fDevice.rowBytes();
+ SkShader* shader = fShader;
+
+ if (fXfermode == NULL && (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
+ void* ctx;
+ SkShader::ShadeProc shadeProc = fShader->asAShadeProc(&ctx);
+ if (shadeProc) {
+ do {
+ shadeProc(ctx, x, y, device, width);
+ y += 1;
+ device = (uint32_t*)((char*)device + deviceRB);
+ } while (--height > 0);
+ } else {
+ do {
+ shader->shadeSpan(x, y, device, width);
+ y += 1;
+ device = (uint32_t*)((char*)device + deviceRB);
+ } while (--height > 0);
+ }
+ } else {
+ SkPMColor* span = fBuffer;
+ SkXfermode* xfer = fXfermode;
+ if (xfer) {
+ do {
+ shader->shadeSpan(x, y, span, width);
+ xfer->xfer32(device, span, width, NULL);
+ y += 1;
+ device = (uint32_t*)((char*)device + deviceRB);
+ } while (--height > 0);
+ } else {
+ SkBlitRow::Proc32 proc = fProc32;
+ do {
+ shader->shadeSpan(x, y, span, width);
+ proc(device, span, width, 255);
+ y += 1;
+ device = (uint32_t*)((char*)device + deviceRB);
+ } while (--height > 0);
+ }
+ }
+}
+
void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
const int16_t runs[]) {
SkPMColor* span = fBuffer;
diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h
index 4a03a53169..b97eed82ca 100644
--- a/src/core/SkCoreBlitters.h
+++ b/src/core/SkCoreBlitters.h
@@ -130,18 +130,19 @@ public:
SkARGB32_Shader_Blitter(const SkBitmap& device, const SkPaint& paint);
virtual ~SkARGB32_Shader_Blitter();
virtual void blitH(int x, int y, int width);
+ virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
virtual void blitMask(const SkMask&, const SkIRect&);
-
+
private:
SkXfermode* fXfermode;
SkPMColor* fBuffer;
SkBlitRow::Proc32 fProc32;
SkBlitRow::Proc32 fProc32Blend;
-
+
// illegal
SkARGB32_Shader_Blitter& operator=(const SkARGB32_Shader_Blitter&);
-
+
typedef SkShaderBlitter INHERITED;
};
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index 97cca5f81c..2f1def62c1 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -103,6 +103,10 @@ bool SkShader::setContext(const SkBitmap& device,
return false;
}
+SkShader::ShadeProc SkShader::asAShadeProc(void** ctx) {
+ return NULL;
+}
+
#include "SkColorPriv.h"
void SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) {