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

Unified Diff: src/core/SkBlitter.cpp

Issue 249643002: Revert of Extract most of the mutable state of SkShader into a separate Context object. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 8 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
« no previous file with comments | « src/core/SkBlitter.h ('k') | src/core/SkBlitter_A8.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkBlitter.cpp
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index 7243f521613905cf164ecbff723d246ff5276917..52a05eded8fda41b55cc66a300875877b90e3f00 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -26,15 +26,6 @@
bool SkBlitter::isNullBlitter() const { return false; }
-bool SkBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix) {
- return true;
-}
-
-SkShader::Context* SkBlitter::getShaderContext() const {
- return NULL;
-}
-
const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) {
return NULL;
}
@@ -577,149 +568,102 @@
public:
Sk3DShader(SkShader* proxy) : fProxy(proxy) {
SkSafeRef(proxy);
+ fMask = NULL;
}
virtual ~Sk3DShader() {
SkSafeUnref(fProxy);
}
- virtual size_t contextSize() const SK_OVERRIDE {
- size_t size = sizeof(Sk3DShaderContext);
+ 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)) {
+ return false;
+ }
if (fProxy) {
- size += fProxy->contextSize();
- }
- return size;
- }
-
- virtual bool validContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, SkMatrix* totalInverse = NULL) const
- SK_OVERRIDE
- {
- if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
- return false;
- }
+ 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 true;
+ }
+
+ virtual void endContext() SK_OVERRIDE {
if (fProxy) {
- return fProxy->validContext(device, paint, matrix);
- }
- return true;
- }
-
- virtual SkShader::Context* createContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix,
- void* storage) const SK_OVERRIDE
- {
- if (!this->validContext(device, paint, matrix)) {
- return NULL;
- }
-
- SkShader::Context* proxyContext;
+ fProxy->endContext();
+ }
+ this->INHERITED::endContext();
+ }
+
+ virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE {
if (fProxy) {
- char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderContext);
- proxyContext = fProxy->createContext(device, paint, matrix, proxyContextStorage);
- SkASSERT(proxyContext);
- } else {
- proxyContext = NULL;
- }
- return SkNEW_PLACEMENT_ARGS(storage, Sk3DShaderContext, (*this, device, paint, matrix,
- proxyContext));
- }
-
- class Sk3DShaderContext : public SkShader::Context {
- public:
- // Calls proxyContext's destructor but will NOT free its memory.
- Sk3DShaderContext(const Sk3DShader& shader, const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, SkShader::Context* proxyContext)
- : INHERITED(shader, device, paint, matrix)
- , fMask(NULL)
- , fProxyContext(proxyContext)
- {
- if (!fProxyContext) {
- fPMColor = SkPreMultiplyColor(paint.getColor());
- }
- }
-
- virtual ~Sk3DShaderContext() {
- if (fProxyContext) {
- fProxyContext->~Context();
- }
- }
-
- void setMask(const SkMask* mask) { fMask = mask; }
-
- virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE {
- if (fProxyContext) {
- fProxyContext->shadeSpan(x, y, span, count);
- }
-
- if (fMask == NULL) {
- if (fProxyContext == 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 (fProxyContext) {
- 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]) {
+ fProxy->shadeSpan(x, y, span, count);
+ }
+
+ if (fMask == NULL) {
+ if (fProxy == 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 (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);
+
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;
+ 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;
}
}
- }
-
- private:
- // Unowned.
- const SkMask* fMask;
- // Memory is unowned, but we need to call the destructor.
- SkShader::Context* fProxyContext;
- SkPMColor fPMColor;
-
- typedef SkShader::Context INHERITED;
- };
+ } 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;
+ }
+ }
+ }
+ }
#ifndef SK_IGNORE_TO_STRING
virtual void toString(SkString* str) const SK_OVERRIDE {
@@ -741,30 +685,29 @@
protected:
Sk3DShader(SkReadBuffer& buffer) : INHERITED(buffer) {
fProxy = buffer.readShader();
- // Leaving this here until we bump the picture version, though this
- // shader should never be recorded.
- buffer.readColor();
+ fPMColor = buffer.readColor();
+ fMask = NULL;
}
virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
this->INHERITED::flatten(buffer);
buffer.writeFlattenable(fProxy);
- // Leaving this here until we bump the picture version, though this
- // shader should never be recorded.
- buffer.writeColor(SkColor());
+ buffer.writeColor(fPMColor);
}
private:
SkShader* fProxy;
+ SkPMColor fPMColor;
+ const SkMask* fMask;
typedef SkShader INHERITED;
};
class Sk3DBlitter : public SkBlitter {
public:
- Sk3DBlitter(SkBlitter* proxy, Sk3DShader::Sk3DShaderContext* shaderContext)
+ Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader)
: fProxy(proxy)
- , f3DShaderContext(shaderContext)
+ , f3DShader(SkRef(shader))
{}
virtual void blitH(int x, int y, int width) {
@@ -786,22 +729,22 @@
virtual void blitMask(const SkMask& mask, const SkIRect& clip) {
if (mask.fFormat == SkMask::k3D_Format) {
- f3DShaderContext->setMask(&mask);
+ f3DShader->setMask(&mask);
((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
fProxy->blitMask(mask, clip);
((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
- f3DShaderContext->setMask(NULL);
+ f3DShader->setMask(NULL);
} else {
fProxy->blitMask(mask, clip);
}
}
private:
- // Both pointers are unowned. They will be deleted by SkSmallAllocator.
- SkBlitter* fProxy;
- Sk3DShader::Sk3DShaderContext* f3DShaderContext;
+ // fProxy is unowned. It will be deleted by SkSmallAllocator.
+ SkBlitter* fProxy;
+ SkAutoTUnref<Sk3DShader> f3DShader;
};
///////////////////////////////////////////////////////////////////////////////
@@ -811,7 +754,8 @@
static bool just_solid_color(const SkPaint& paint) {
if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) {
SkShader* shader = paint.getShader();
- if (NULL == shader) {
+ if (NULL == shader ||
+ (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
return true;
}
}
@@ -949,22 +893,16 @@
}
/*
- * We create a SkShader::Context object, and store it on the blitter.
+ * 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.
*/
- SkShader::Context* shaderContext;
- if (shader) {
- // Try to create the ShaderContext
- void* storage = allocator->reserveT<SkShader::Context>(shader->contextSize());
- shaderContext = shader->createContext(device, *paint, matrix, storage);
- if (!shaderContext) {
- allocator->freeLast();
- blitter = allocator->createT<SkNullBlitter>();
- return blitter;
- }
- SkASSERT(shaderContext);
- SkASSERT((void*) shaderContext == storage);
- } else {
- shaderContext = NULL;
+ if (shader && !shader->setContext(device, *paint, matrix)) {
+ blitter = allocator->createT<SkNullBlitter>();
+ return blitter;
}
@@ -975,20 +913,19 @@
SkASSERT(NULL == paint->getXfermode());
blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *paint);
} else if (shader) {
- blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint, shaderContext);
+ blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint);
} else {
blitter = allocator->createT<SkA8_Blitter>(device, *paint);
}
break;
case kRGB_565_SkColorType:
- blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, allocator);
+ blitter = SkBlitter_ChooseD565(device, *paint, allocator);
break;
case kN32_SkColorType:
if (shader) {
- blitter = allocator->createT<SkARGB32_Shader_Blitter>(
- device, *paint, shaderContext);
+ blitter = allocator->createT<SkARGB32_Shader_Blitter>(device, *paint);
} else if (paint->getColor() == SK_ColorBLACK) {
blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *paint);
} else if (paint->getAlpha() == 0xFF) {
@@ -1007,9 +944,7 @@
if (shader3D) {
SkBlitter* innerBlitter = blitter;
// innerBlitter was allocated by allocator, which will delete it.
- // We know shaderContext is of type Sk3DShaderContext because it belongs to shader3D.
- blitter = allocator->createT<Sk3DBlitter>(innerBlitter,
- static_cast<Sk3DShader::Sk3DShaderContext*>(shaderContext));
+ blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shader3D);
}
return blitter;
}
@@ -1021,36 +956,18 @@
///////////////////////////////////////////////////////////////////////////////
-SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext)
- : INHERITED(device)
- , fShader(paint.getShader())
- , fShaderContext(shaderContext) {
+SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint)
+ : INHERITED(device) {
+ fShader = paint.getShader();
SkASSERT(fShader);
- SkASSERT(fShaderContext);
+ SkASSERT(fShader->setContextHasBeenCalled());
fShader->ref();
- fShaderFlags = fShaderContext->getFlags();
+ fShaderFlags = fShader->getFlags();
}
SkShaderBlitter::~SkShaderBlitter() {
+ SkASSERT(fShader->setContextHasBeenCalled());
+ fShader->endContext();
fShader->unref();
}
-
-bool SkShaderBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix) {
- if (!fShader->validContext(device, paint, matrix)) {
- return false;
- }
-
- // Only destroy the old context if we have a new one. We need to ensure to have a
- // live context in fShaderContext because the storage is owned by an SkSmallAllocator
- // outside of this class.
- // The new context will be of the same size as the old one because we use the same
- // shader to create it. It is therefore safe to re-use the storage.
- fShaderContext->~Context();
- fShaderContext = fShader->createContext(device, paint, matrix, (void*)fShaderContext);
- SkASSERT(fShaderContext);
-
- return true;
-}
« no previous file with comments | « src/core/SkBlitter.h ('k') | src/core/SkBlitter_A8.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698