Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Unified Diff: src/core/SkBlitter.cpp

Issue 198193005: Work (in progress) to make SkShader immutable. (Closed) Base URL: https://skia.googlesource.com/skia.git@shaderGenerator
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/core/SkBlitter.cpp
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index f925eaa7b2d7f193ef076a7b696ef0db42c339ca..17fcdee982cdd7098e534c047b72d17585b21186 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -564,106 +564,142 @@ SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip,
#include "SkColorShader.h"
#include "SkColorPriv.h"
-class Sk3DShader : public SkShader {
+class Sk3DShader : public SkShaderGenerator {
public:
Sk3DShader(SkShader* proxy) : fProxy(proxy) {
SkSafeRef(proxy);
- fMask = NULL;
}
virtual ~Sk3DShader() {
SkSafeUnref(fProxy);
}
- void setMask(const SkMask* mask) { fMask = mask; }
-
- virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix) SK_OVERRIDE {
- if (!this->INHERITED::setContext(device, paint, matrix)) {
+ virtual bool validContext(const SkBitmap& device, const SkPaint& paint,
+ const SkMatrix& matrix) const SK_OVERRIDE
+ {
+ if (!this->INHERITED::validateContext(device, paint, matrix)) {
return false;
}
if (fProxy) {
- if (!fProxy->setContext(device, paint, matrix)) {
- // must keep our set/end context calls balanced
- this->INHERITED::endContext();
- return false;
- }
- } else {
- fPMColor = SkPreMultiplyColor(paint.getColor());
+ return fProxy->validateContext(device, paint, matrix);
}
return true;
}
- virtual void endContext() SK_OVERRIDE {
+ virtual size_t shaderImplSize() const SK_OVERRIDE {
+ size_t size = sizeof(Sk3DShaderImpl);
if (fProxy) {
- fProxy->endContext();
+ size += fProxy->shaderImplSize();
}
- this->INHERITED::endContext();
+ return size;
}
- virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE {
+ virtual ShaderImpl* createShaderImpl(const SkBitmap& device, const SkPaint& paint,
+ const SkMatrix& matrix, void* storage) const Sk_OVERRIDE
+ {
+ SkASSERT(this->validContext(device, paint, matrix));
+ ShaderImpl* proxyImpl;
if (fProxy) {
- fProxy->shadeSpan(x, y, span, count);
+ char* proxyImplStorage = (char*) storage + sizeof(Sk3DShaderImpl);
+ proxyImpl = fProxy->createShaderImpl(device, paint, matrix, proxyImplStorage);
+ } else {
+ proxyImpl = NULL;
+ }
+ return SkNEW_PLACEMENT_ARGS(storage, Sk3DShaderImpl, (*this, device, paint, matrix,
+ proxyImpl));
+ }
+
+ class Sk3DShaderImpl : public ShaderImpl {
+ Sk3DShaderImpl(const Sk3DShader& shader, const SkBitmap& device, const SkPaint& paint,
+ const SkMatrix& matrix, ShaderImpl* proxyImpl)
+ : INHERITED(shader, device, paint, matrix)
+ , fMask(NULL)
+ , fProxyImpl(proxyImpl)
+ {
+ if (!fProxyImpl) {
+ fPMColor = SkPreMultiplyColor(paint.getColor());
+ }
}
- if (fMask == NULL) {
- if (fProxy == NULL) {
- sk_memset32(span, fPMColor, count);
+ virtual ~Sk3DShaderImpl() {
+ if (fProxyImpl) {
+ fProxyImpl->~ShaderImpl();
}
- return;
}
- SkASSERT(fMask->fBounds.contains(x, y));
- SkASSERT(fMask->fBounds.contains(x + count - 1, y));
+ void setMask(const SkMask* mask) { fMask = mask; }
- size_t size = fMask->computeImageSize();
- const uint8_t* alpha = fMask->getAddr8(x, y);
- const uint8_t* mulp = alpha + size;
- const uint8_t* addp = mulp + size;
+ virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE {
+ const Sk3DShader& shader3D = static_cast<const Sk3DShader&>(fShader);
+ if (fProxyImpl) {
+ fProxyImpl->shadeSpan(x, y, span, count);
+ }
- if (fProxy) {
- for (int i = 0; i < count; i++) {
- if (alpha[i]) {
- SkPMColor c = span[i];
- if (c) {
- unsigned a = SkGetPackedA32(c);
- unsigned r = SkGetPackedR32(c);
- unsigned g = SkGetPackedG32(c);
- unsigned b = SkGetPackedB32(c);
+ if (fMask == NULL) {
+ if (fProxyImpl == NULL) {
+ sk_memset32(span, fPMColor, count);
+ }
+ return;
+ }
+ SkASSERT(fMask->fBounds.contains(x, y));
+ SkASSERT(fMask->fBounds.contains(x + count - 1, y));
+
+ size_t size = fMask->computeImageSize();
+ const uint8_t* alpha = fMask->getAddr8(x, y);
+ const uint8_t* mulp = alpha + size;
+ const uint8_t* addp = mulp + size;
+
+ if (fProxyImpl) {
+ for (int i = 0; i < count; i++) {
+ if (alpha[i]) {
+ SkPMColor c = span[i];
+ if (c) {
+ unsigned a = SkGetPackedA32(c);
+ unsigned r = SkGetPackedR32(c);
+ unsigned g = SkGetPackedG32(c);
+ unsigned b = SkGetPackedB32(c);
+
+ unsigned mul = SkAlpha255To256(mulp[i]);
+ unsigned add = addp[i];
+
+ r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
+ g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
+ b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
+
+ span[i] = SkPackARGB32(a, r, g, b);
+ }
+ } else {
+ span[i] = 0;
+ }
+ }
+ } else { // color
+ unsigned a = SkGetPackedA32(fPMColor);
+ unsigned r = SkGetPackedR32(fPMColor);
+ unsigned g = SkGetPackedG32(fPMColor);
+ unsigned b = SkGetPackedB32(fPMColor);
+ for (int i = 0; i < count; i++) {
+ if (alpha[i]) {
unsigned mul = SkAlpha255To256(mulp[i]);
unsigned add = addp[i];
- r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
- g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
- b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
-
- span[i] = SkPackARGB32(a, r, g, b);
+ span[i] = SkPackARGB32( a,
+ SkFastMin32(SkAlphaMul(r, mul) + add, a),
+ SkFastMin32(SkAlphaMul(g, mul) + add, a),
+ SkFastMin32(SkAlphaMul(b, mul) + add, a));
+ } else {
+ span[i] = 0;
}
- } else {
- span[i] = 0;
- }
- }
- } else { // color
- unsigned a = SkGetPackedA32(fPMColor);
- unsigned r = SkGetPackedR32(fPMColor);
- unsigned g = SkGetPackedG32(fPMColor);
- unsigned b = SkGetPackedB32(fPMColor);
- for (int i = 0; i < count; i++) {
- if (alpha[i]) {
- unsigned mul = SkAlpha255To256(mulp[i]);
- unsigned add = addp[i];
-
- span[i] = SkPackARGB32( a,
- SkFastMin32(SkAlphaMul(r, mul) + add, a),
- SkFastMin32(SkAlphaMul(g, mul) + add, a),
- SkFastMin32(SkAlphaMul(b, mul) + add, a));
- } else {
- span[i] = 0;
}
}
}
- }
+ private:
+ // Unowned.
+ const SkMask* fMask;
+ // Memory is unowned, but we need to call the destructor.
+ ShaderImpl* fProxyImpl;
+ SkPMColor fPMColor;
+ };
#ifdef SK_DEVELOPER
virtual void toString(SkString* str) const SK_OVERRIDE {
@@ -685,29 +721,30 @@ public:
protected:
Sk3DShader(SkReadBuffer& buffer) : INHERITED(buffer) {
fProxy = buffer.readShader();
- fPMColor = buffer.readColor();
- fMask = NULL;
+ // Leaving this here until we bump the picture version, though this
+ // shader should never be recorded.
+ buffer.readColor();
}
virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
this->INHERITED::flatten(buffer);
buffer.writeFlattenable(fProxy);
- buffer.writeColor(fPMColor);
+ // Leaving this here until we bump the picture version, though this
+ // shader should never be recorded.
+ buffer.writeColor(SkColor());
}
private:
SkShader* fProxy;
- SkPMColor fPMColor;
- const SkMask* fMask;
- typedef SkShader INHERITED;
+ typedef SkShaderGenerator INHERITED;
};
class Sk3DBlitter : public SkBlitter {
public:
Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader)
: fProxy(proxy)
- , f3DShader(SkRef(shader))
+ , f3DShaderImpl(SkRef(shader))
{}
virtual void blitH(int x, int y, int width) {
@@ -729,22 +766,22 @@ public:
virtual void blitMask(const SkMask& mask, const SkIRect& clip) {
if (mask.fFormat == SkMask::k3D_Format) {
- f3DShader->setMask(&mask);
+ f3DShaderImpl->setMask(&mask);
((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
fProxy->blitMask(mask, clip);
((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
- f3DShader->setMask(NULL);
+ f3DShaderImpl->setMask(NULL);
} else {
fProxy->blitMask(mask, clip);
}
}
private:
- // fProxy is unowned. It will be deleted by SkSmallAllocator.
- SkBlitter* fProxy;
- SkAutoTUnref<Sk3DShader> f3DShader;
+ // Both pointers are unowned. They will be deleted by SkSmallAllocator.
+ SkBlitter* fProxy;
+ Sk3DShader::Sk3DShaderImpl* f3DShaderImpl;
};
///////////////////////////////////////////////////////////////////////////////
@@ -753,9 +790,12 @@ private:
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)) {
+ SkShaderGenerator* shader = paint.getShader();
+ // FIXME: This is ONLY called BEFORE setContext, when the flags are not
+ // supposed to be meaningful. Do we need flags on the shader as well as
+ // the impl?
+ if (NULL == shader /*||
+ (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)*/) {
return true;
}
}
@@ -826,7 +866,7 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
return blitter;
}
- SkShader* shader = origPaint.getShader();
+ SkShaderGenerator* shader = origPaint.getShader();
SkColorFilter* cf = origPaint.getColorFilter();
SkXfermode* mode = origPaint.getXfermode();
Sk3DShader* shader3D = NULL;
@@ -893,16 +933,22 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
}
/*
- * We need to have balanced calls to the shader:
- * setContext
- * endContext
- * We make the first call here, in case it fails we can abort the draw.
- * The endContext() call is made by the blitter (assuming setContext did
- * not fail) in its destructor.
+ * We create a ShaderImpl object, and store it on the blitter.
*/
- if (shader && !shader->setContext(device, *paint, matrix)) {
- blitter = allocator->createT<SkNullBlitter>();
- return blitter;
+ SkShaderGenerator::ShaderImpl* shaderImpl;
+ if (shader) {
+ if (!shader->validContext(device, *paint, matrix)) {
+ blitter = allocator->createT<SkNullBlitter>();
+ return blitter;
+ }
+ // Now create the ShaderImpl
+ void* storage = allocator->reserveT<SkShaderGenerator::ShaderImpl>(
+ shader->shaderImplSize());
+ shaderImpl = shader->createShaderImpl(device, *paint, matrix);
+ SkASSERT(shaderImpl);
+ SkASSERT((void*) shaderImpl == storage);
+ } else {
+ shaderImpl = NULL;
}
@@ -913,19 +959,19 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
SkASSERT(NULL == paint->getXfermode());
blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *paint);
} else if (shader) {
- blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint);
+ blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint, shaderImpl);
} else {
blitter = allocator->createT<SkA8_Blitter>(device, *paint);
}
break;
case kRGB_565_SkColorType:
- blitter = SkBlitter_ChooseD565(device, *paint, allocator);
+ blitter = SkBlitter_ChooseD565(device, *paint, shaderImpl, allocator);
break;
case kPMColor_SkColorType:
if (shader) {
- blitter = allocator->createT<SkARGB32_Shader_Blitter>(device, *paint);
+ blitter = allocator->createT<SkARGB32_Shader_Blitter>(device, *paint, shaderImpl);
} else if (paint->getColor() == SK_ColorBLACK) {
blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *paint);
} else if (paint->getAlpha() == 0xFF) {
@@ -944,7 +990,8 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
if (shader3D) {
SkBlitter* innerBlitter = blitter;
// innerBlitter was allocated by allocator, which will delete it.
- blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shader3D);
+ blitter = allocator->createT<Sk3DBlitter>(innerBlitter,
+ static_cast<Sk3DShader::Sk3DShaderImpl*>(shaderImpl);
}
return blitter;
}
@@ -956,18 +1003,13 @@ const uint32_t gMask_00FF00FF = 0xFF00FF;
///////////////////////////////////////////////////////////////////////////////
-SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint)
+SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint,
+ SkShaderGenerator::ShaderImpl* shaderImpl)
: INHERITED(device) {
- fShader = paint.getShader();
- SkASSERT(fShader);
- SkASSERT(fShader->setContextHasBeenCalled());
+ fShaderImpl = shaderImpl;
+ SkASSERT(paint.getShader());
+ SkASSERT(fShaderImpl);
- fShader->ref();
- fShaderFlags = fShader->getFlags();
+ fShaderFlags = paint.getShader()->getFlags();
}
-SkShaderBlitter::~SkShaderBlitter() {
- SkASSERT(fShader->setContextHasBeenCalled());
- fShader->endContext();
- fShader->unref();
-}
« no previous file with comments | « src/core/SkBitmapProcShader.h ('k') | src/core/SkBlitter_A8.cpp » ('j') | src/core/SkShader.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698