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

Unified Diff: src/core/SkBitmapProcShader.cpp

Issue 207683004: 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: clean up 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/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

Powered by Google App Engine
This is Rietveld 408576698