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
This commit is contained in:
reed@google.com 2012-10-12 18:56:18 +00:00
parent cb1bbb375a
commit 3bafe74a29
6 changed files with 66 additions and 3 deletions

View File

@ -148,6 +148,9 @@ public:
*/
virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count);
virtual ShadeProc asAShadeProc(void** ctx);
/**
* Called only for 16bit devices when getFlags() returns
* kOpaqueAlphaFlag | kHasSpan16_Flag

View File

@ -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()) {

View File

@ -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();

View File

@ -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;

View File

@ -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;
};

View File

@ -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) {