Index: src/core/SkBitmapProcShader.cpp |
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp |
index 55a772ec10ace94578a4be78cedbd508de1deb97..9ba655f240794be9c8a12a47c53e8d866186f2ac 100644 |
--- a/src/core/SkBitmapProcShader.cpp |
+++ b/src/core/SkBitmapProcShader.cpp |
@@ -34,18 +34,16 @@ bool SkBitmapProcShader::CanDo(const SkBitmap& bm, TileMode tx, TileMode ty) { |
SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, |
TileMode tmx, TileMode tmy) { |
fRawBitmap = src; |
- fState.fTileModeX = (uint8_t)tmx; |
- fState.fTileModeY = (uint8_t)tmy; |
- fFlags = 0; // computed in setContext |
+ fTileModeX = (uint8_t)tmx; |
+ fTileModeY = (uint8_t)tmy; |
} |
SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer) |
: INHERITED(buffer) { |
buffer.readBitmap(&fRawBitmap); |
fRawBitmap.setImmutable(); |
- fState.fTileModeX = buffer.readUInt(); |
- fState.fTileModeY = buffer.readUInt(); |
- fFlags = 0; // computed in setContext |
+ fTileModeX = buffer.readUInt(); |
+ fTileModeY = buffer.readUInt(); |
} |
SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture, |
@@ -58,8 +56,8 @@ SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture, |
texM->reset(); |
} |
if (xy) { |
- xy[0] = (TileMode)fState.fTileModeX; |
- xy[1] = (TileMode)fState.fTileModeY; |
+ xy[0] = (TileMode)fTileModeX; |
+ xy[1] = (TileMode)fTileModeY; |
} |
return kDefault_BitmapType; |
} |
@@ -68,8 +66,8 @@ void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { |
this->INHERITED::flatten(buffer); |
buffer.writeBitmap(fRawBitmap); |
- buffer.writeUInt(fState.fTileModeX); |
- buffer.writeUInt(fState.fTileModeY); |
+ buffer.writeUInt(fTileModeX); |
+ buffer.writeUInt(fTileModeY); |
} |
static bool only_scale_and_translate(const SkMatrix& matrix) { |
@@ -98,24 +96,58 @@ static bool valid_for_drawing(const SkBitmap& bm) { |
return true; |
} |
-bool SkBitmapProcShader::setContext(const SkBitmap& device, |
- const SkPaint& paint, |
- const SkMatrix& matrix) { |
+bool SkBitmapProcShader::validContext(const SkBitmap& device, |
+ const SkPaint& paint, |
+ const SkMatrix& matrix) const { |
if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) { |
return false; |
} |
- // do this first, so we have a correct inverse matrix |
- if (!this->INHERITED::setContext(device, paint, matrix)) { |
+ // Do this first, so we know the matrix can be inverted. |
+ if (!this->INHERITED::validContext(device, paint, matrix)) { |
return false; |
} |
- fState.fOrigBitmap = fRawBitmap; |
- if (!fState.chooseProcs(this->getTotalInverse(), paint)) { |
- this->INHERITED::endContext(); |
+ // TODO(dominikg): Can we avoid re-computing the inverse? |
+ SkMatrix inverse; |
+ SkASSERT(matrix.invert(&inverse)); |
+ |
+ SkBitmapProcState state; |
+ state.fTileModeX = fTileModeX; |
+ state.fTileModeY = fTileModeY; |
+ state.fOrigBitmap = fRawBitmap; |
+ // TODO(dominikg): Could we have a more light-weight method instead of chooseProcs that only |
scroggo
2014/03/24 21:24:46
Here's what I might do:
1. Instead of making crea
Dominik Grewe
2014/03/26 17:22:22
Yeah, that could easily lead to problems, couldn't
scroggo
2014/03/26 23:13:09
I don't think we'll subclass SkBitmapProcShader, a
Dominik Grewe
2014/03/27 14:27:20
Do you mean SkBitmapProcState rather than Shader?
scroggo
2014/03/27 18:05:33
You are correct; I did mean SkBitmapProcState. I d
Dominik Grewe
2014/03/28 18:16:31
Yes, that looks reasonable. The only caveat is tha
scroggo
2014/03/28 20:50:07
I also don't have much time to look at this until
Dominik Grewe
2014/04/01 10:49:55
Good idea. I'm now placing the SkBitmapProcState o
|
+ // validates the inputs? |
+ if (!state.chooseProcs(inverse, paint)) { |
return false; |
} |
+ return true; |
+} |
+ |
+SkShader::Context* SkBitmapProcShader::createContext(const SkBitmap& device, const SkPaint& paint, |
+ const SkMatrix& matrix, void* storage) const { |
+ if (!this->validContext(device, paint, matrix)) { |
+ return NULL; |
+ } |
+ |
+ return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext, (*this, device, paint, matrix)); |
+} |
+ |
+size_t SkBitmapProcShader::contextSize() const { |
+ return sizeof(BitmapProcShaderContext); |
+} |
+ |
+SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext( |
+ const SkBitmapProcShader& shader, const SkBitmap& device, |
+ const SkPaint& paint, const SkMatrix& matrix) |
+ : INHERITED(shader, device, paint, matrix) { |
+ |
+ fState.fTileModeX = shader.fTileModeX; |
+ fState.fTileModeY = shader.fTileModeY; |
+ fState.fOrigBitmap = shader.fRawBitmap; |
+ SkASSERT(fState.chooseProcs(this->getTotalInverse(), paint)); |
+ |
const SkBitmap& bitmap = *fState.fBitmap; |
bool bitmapIsOpaque = bitmap.isOpaque(); |
@@ -157,12 +189,9 @@ bool SkBitmapProcShader::setContext(const SkBitmap& device, |
} |
fFlags = flags; |
- return true; |
} |
-void SkBitmapProcShader::endContext() { |
- fState.endContext(); |
- this->INHERITED::endContext(); |
+SkBitmapProcShader::BitmapProcShaderContext::~BitmapProcShaderContext() { |
scroggo
2014/03/24 21:24:46
Any reason not to just remove this entirely?
Dominik Grewe
2014/03/26 17:22:22
Just for completeness. I've moved the empty body t
|
} |
#define BUF_MAX 128 |
@@ -176,7 +205,8 @@ void SkBitmapProcShader::endContext() { |
#define TEST_BUFFER_EXTRA 0 |
#endif |
-void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { |
+void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan( |
+ int x, int y, SkPMColor dstC[], int count) { |
scroggo
2014/03/24 21:24:46
Parameters that fit should be on the same line.
Dominik Grewe
2014/03/26 17:22:22
If I read the coding style correctly it seems that
scroggo
2014/03/26 23:13:09
I think it's more conventional, but you're right,
|
const SkBitmapProcState& state = fState; |
if (state.getShaderProc32()) { |
state.getShaderProc32()(state, x, y, dstC, count); |
@@ -220,7 +250,7 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { |
} |
} |
-SkShader::ShadeProc SkBitmapProcShader::asAShadeProc(void** ctx) { |
+SkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asAShadeProc(void** ctx) { |
if (fState.getShaderProc32()) { |
*ctx = &fState; |
return (ShadeProc)fState.getShaderProc32(); |
@@ -228,7 +258,8 @@ SkShader::ShadeProc SkBitmapProcShader::asAShadeProc(void** ctx) { |
return NULL; |
} |
-void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) { |
+void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan16( |
+ int x, int y, uint16_t dstC[], int count) { |
scroggo
2014/03/24 21:24:46
Same
|
const SkBitmapProcState& state = fState; |
if (state.getShaderProc16()) { |
state.getShaderProc16()(state, x, y, dstC, count); |
@@ -342,8 +373,8 @@ void SkBitmapProcShader::toString(SkString* str) const { |
str->append("BitmapShader: ("); |
str->appendf("(%s, %s)", |
- gTileModeName[fState.fTileModeX], |
- gTileModeName[fState.fTileModeY]); |
+ gTileModeName[fTileModeX], |
+ gTileModeName[fTileModeY]); |
str->append(" "); |
fRawBitmap.toString(str); |
@@ -384,8 +415,8 @@ GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& |
matrix.preConcat(lmInverse); |
SkShader::TileMode tm[] = { |
- (TileMode)fState.fTileModeX, |
- (TileMode)fState.fTileModeY, |
+ (TileMode)fTileModeX, |
+ (TileMode)fTileModeY, |
}; |
// Must set wrap and filter on the sampler before requesting a texture. In two places below |