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

Side by Side Diff: src/core/SkBitmapProcShader.cpp

Issue 246403013: Revert of 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 unified diff | Download patch
« no previous file with comments | « src/core/SkBitmapProcShader.h ('k') | src/core/SkBitmapProcState.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 #include "SkColorPriv.h" 8 #include "SkColorPriv.h"
9 #include "SkReadBuffer.h" 9 #include "SkReadBuffer.h"
10 #include "SkWriteBuffer.h" 10 #include "SkWriteBuffer.h"
(...skipping 16 matching lines...) Expand all
27 return true; 27 return true;
28 default: 28 default:
29 break; 29 break;
30 } 30 }
31 return false; 31 return false;
32 } 32 }
33 33
34 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, 34 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src,
35 TileMode tmx, TileMode tmy) { 35 TileMode tmx, TileMode tmy) {
36 fRawBitmap = src; 36 fRawBitmap = src;
37 fState.fTileModeX = (uint8_t)tmx; 37 fTileModeX = (uint8_t)tmx;
38 fState.fTileModeY = (uint8_t)tmy; 38 fTileModeY = (uint8_t)tmy;
39 fFlags = 0; // computed in setContext
40 } 39 }
41 40
42 SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer) 41 SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer)
43 : INHERITED(buffer) { 42 : INHERITED(buffer) {
44 buffer.readBitmap(&fRawBitmap); 43 buffer.readBitmap(&fRawBitmap);
45 fRawBitmap.setImmutable(); 44 fRawBitmap.setImmutable();
46 fState.fTileModeX = buffer.readUInt(); 45 fTileModeX = buffer.readUInt();
47 fState.fTileModeY = buffer.readUInt(); 46 fTileModeY = buffer.readUInt();
48 fFlags = 0; // computed in setContext
49 } 47 }
50 48
51 SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture, 49 SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture,
52 SkMatrix* texM, 50 SkMatrix* texM,
53 TileMode xy[]) const { 51 TileMode xy[]) const {
54 if (texture) { 52 if (texture) {
55 *texture = fRawBitmap; 53 *texture = fRawBitmap;
56 } 54 }
57 if (texM) { 55 if (texM) {
58 texM->reset(); 56 texM->reset();
59 } 57 }
60 if (xy) { 58 if (xy) {
61 xy[0] = (TileMode)fState.fTileModeX; 59 xy[0] = (TileMode)fTileModeX;
62 xy[1] = (TileMode)fState.fTileModeY; 60 xy[1] = (TileMode)fTileModeY;
63 } 61 }
64 return kDefault_BitmapType; 62 return kDefault_BitmapType;
65 } 63 }
66 64
67 void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { 65 void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const {
68 this->INHERITED::flatten(buffer); 66 this->INHERITED::flatten(buffer);
69 67
70 buffer.writeBitmap(fRawBitmap); 68 buffer.writeBitmap(fRawBitmap);
71 buffer.writeUInt(fState.fTileModeX); 69 buffer.writeUInt(fTileModeX);
72 buffer.writeUInt(fState.fTileModeY); 70 buffer.writeUInt(fTileModeY);
73 } 71 }
74 72
75 static bool only_scale_and_translate(const SkMatrix& matrix) { 73 static bool only_scale_and_translate(const SkMatrix& matrix) {
76 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; 74 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
77 return (matrix.getType() & ~mask) == 0; 75 return (matrix.getType() & ~mask) == 0;
78 } 76 }
79 77
80 bool SkBitmapProcShader::isOpaque() const { 78 bool SkBitmapProcShader::isOpaque() const {
81 return fRawBitmap.isOpaque(); 79 return fRawBitmap.isOpaque();
82 } 80 }
83 81
84 static bool valid_for_drawing(const SkBitmap& bm) { 82 static bool valid_for_drawing(const SkBitmap& bm) {
85 if (0 == bm.width() || 0 == bm.height()) { 83 if (0 == bm.width() || 0 == bm.height()) {
86 return false; // nothing to draw 84 return false; // nothing to draw
87 } 85 }
88 if (NULL == bm.pixelRef()) { 86 if (NULL == bm.pixelRef()) {
89 return false; // no pixels to read 87 return false; // no pixels to read
90 } 88 }
91 if (kIndex_8_SkColorType == bm.colorType()) { 89 if (kIndex_8_SkColorType == bm.colorType()) {
92 // ugh, I have to lock-pixels to inspect the colortable 90 // ugh, I have to lock-pixels to inspect the colortable
93 SkAutoLockPixels alp(bm); 91 SkAutoLockPixels alp(bm);
94 if (!bm.getColorTable()) { 92 if (!bm.getColorTable()) {
95 return false; 93 return false;
96 } 94 }
97 } 95 }
98 return true; 96 return true;
99 } 97 }
100 98
101 bool SkBitmapProcShader::setContext(const SkBitmap& device, 99 bool SkBitmapProcShader::validInternal(const SkBitmap& device,
102 const SkPaint& paint, 100 const SkPaint& paint,
103 const SkMatrix& matrix) { 101 const SkMatrix& matrix,
102 SkMatrix* totalInverse,
103 SkBitmapProcState* state) const {
104 if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) { 104 if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) {
105 return false; 105 return false;
106 } 106 }
107 107
108 // do this first, so we have a correct inverse matrix 108 // Make sure we can use totalInverse as a cache.
109 if (!this->INHERITED::setContext(device, paint, matrix)) { 109 SkMatrix totalInverseLocal;
110 if (NULL == totalInverse) {
111 totalInverse = &totalInverseLocal;
112 }
113
114 // Do this first, so we know the matrix can be inverted.
115 if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
110 return false; 116 return false;
111 } 117 }
112 118
113 fState.fOrigBitmap = fRawBitmap; 119 SkASSERT(state);
114 if (!fState.chooseProcs(this->getTotalInverse(), paint)) { 120 state->fTileModeX = fTileModeX;
115 this->INHERITED::endContext(); 121 state->fTileModeY = fTileModeY;
116 return false; 122 state->fOrigBitmap = fRawBitmap;
123 return state->chooseProcs(*totalInverse, paint);
124 }
125
126 bool SkBitmapProcShader::validContext(const SkBitmap& device,
127 const SkPaint& paint,
128 const SkMatrix& matrix,
129 SkMatrix* totalInverse) const {
130 SkBitmapProcState state;
131 return this->validInternal(device, paint, matrix, totalInverse, &state);
132 }
133
134 SkShader::Context* SkBitmapProcShader::createContext(const SkBitmap& device, con st SkPaint& paint,
135 const SkMatrix& matrix, voi d* storage) const {
136 void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
137 SkBitmapProcState* state = SkNEW_PLACEMENT(stateStorage, SkBitmapProcState);
138 if (!this->validInternal(device, paint, matrix, NULL, state)) {
139 state->~SkBitmapProcState();
140 return NULL;
117 } 141 }
118 142
119 const SkBitmap& bitmap = *fState.fBitmap; 143 return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext,
144 (*this, device, paint, matrix, state));
145 }
146
147 size_t SkBitmapProcShader::contextSize() const {
148 // The SkBitmapProcState is stored outside of the context object, with the c ontext holding
149 // a pointer to it.
150 return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState);
151 }
152
153 SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(
154 const SkBitmapProcShader& shader, const SkBitmap& device,
155 const SkPaint& paint, const SkMatrix& matrix, SkBitmapProcState* state)
156 : INHERITED(shader, device, paint, matrix)
157 , fState(state)
158 {
159 const SkBitmap& bitmap = *fState->fBitmap;
120 bool bitmapIsOpaque = bitmap.isOpaque(); 160 bool bitmapIsOpaque = bitmap.isOpaque();
121 161
122 // update fFlags 162 // update fFlags
123 uint32_t flags = 0; 163 uint32_t flags = 0;
124 if (bitmapIsOpaque && (255 == this->getPaintAlpha())) { 164 if (bitmapIsOpaque && (255 == this->getPaintAlpha())) {
125 flags |= kOpaqueAlpha_Flag; 165 flags |= kOpaqueAlpha_Flag;
126 } 166 }
127 167
128 switch (bitmap.colorType()) { 168 switch (bitmap.colorType()) {
129 case kRGB_565_SkColorType: 169 case kRGB_565_SkColorType:
(...skipping 20 matching lines...) Expand all
150 // if we're only 1-pixel high, and we don't rotate, then we can claim this 190 // if we're only 1-pixel high, and we don't rotate, then we can claim this
151 if (1 == bitmap.height() && 191 if (1 == bitmap.height() &&
152 only_scale_and_translate(this->getTotalInverse())) { 192 only_scale_and_translate(this->getTotalInverse())) {
153 flags |= kConstInY32_Flag; 193 flags |= kConstInY32_Flag;
154 if (flags & kHasSpan16_Flag) { 194 if (flags & kHasSpan16_Flag) {
155 flags |= kConstInY16_Flag; 195 flags |= kConstInY16_Flag;
156 } 196 }
157 } 197 }
158 198
159 fFlags = flags; 199 fFlags = flags;
160 return true;
161 } 200 }
162 201
163 void SkBitmapProcShader::endContext() { 202 SkBitmapProcShader::BitmapProcShaderContext::~BitmapProcShaderContext() {
164 fState.endContext(); 203 // The bitmap proc state has been created outside of the context on memory t hat will be freed
165 this->INHERITED::endContext(); 204 // elsewhere. Only call the destructor but leave the freeing of the memory t o the caller.
205 fState->~SkBitmapProcState();
166 } 206 }
167 207
168 #define BUF_MAX 128 208 #define BUF_MAX 128
169 209
170 #define TEST_BUFFER_OVERRITEx 210 #define TEST_BUFFER_OVERRITEx
171 211
172 #ifdef TEST_BUFFER_OVERRITE 212 #ifdef TEST_BUFFER_OVERRITE
173 #define TEST_BUFFER_EXTRA 32 213 #define TEST_BUFFER_EXTRA 32
174 #define TEST_PATTERN 0x88888888 214 #define TEST_PATTERN 0x88888888
175 #else 215 #else
176 #define TEST_BUFFER_EXTRA 0 216 #define TEST_BUFFER_EXTRA 0
177 #endif 217 #endif
178 218
179 void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { 219 void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan(int x, int y, SkPMCo lor dstC[],
180 const SkBitmapProcState& state = fState; 220 int count) {
221 const SkBitmapProcState& state = *fState;
181 if (state.getShaderProc32()) { 222 if (state.getShaderProc32()) {
182 state.getShaderProc32()(state, x, y, dstC, count); 223 state.getShaderProc32()(state, x, y, dstC, count);
183 return; 224 return;
184 } 225 }
185 226
186 uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; 227 uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA];
187 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); 228 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc();
188 SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); 229 SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32();
189 int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); 230 int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
190 231
191 SkASSERT(state.fBitmap->getPixels()); 232 SkASSERT(state.fBitmap->getPixels());
192 SkASSERT(state.fBitmap->pixelRef() == NULL || 233 SkASSERT(state.fBitmap->pixelRef() == NULL ||
193 state.fBitmap->pixelRef()->isLocked()); 234 state.fBitmap->pixelRef()->isLocked());
194 235
195 for (;;) { 236 for (;;) {
196 int n = count; 237 int n = count;
197 if (n > max) { 238 if (n > max) {
198 n = max; 239 n = max;
199 } 240 }
(...skipping 13 matching lines...) Expand all
213 254
214 if ((count -= n) == 0) { 255 if ((count -= n) == 0) {
215 break; 256 break;
216 } 257 }
217 SkASSERT(count > 0); 258 SkASSERT(count > 0);
218 x += n; 259 x += n;
219 dstC += n; 260 dstC += n;
220 } 261 }
221 } 262 }
222 263
223 SkShader::ShadeProc SkBitmapProcShader::asAShadeProc(void** ctx) { 264 SkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asASha deProc(void** ctx) {
224 if (fState.getShaderProc32()) { 265 if (fState->getShaderProc32()) {
225 *ctx = &fState; 266 *ctx = fState;
226 return (ShadeProc)fState.getShaderProc32(); 267 return (ShadeProc)fState->getShaderProc32();
227 } 268 }
228 return NULL; 269 return NULL;
229 } 270 }
230 271
231 void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) { 272 void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan16(int x, int y, uint 16_t dstC[],
232 const SkBitmapProcState& state = fState; 273 int count) {
274 const SkBitmapProcState& state = *fState;
233 if (state.getShaderProc16()) { 275 if (state.getShaderProc16()) {
234 state.getShaderProc16()(state, x, y, dstC, count); 276 state.getShaderProc16()(state, x, y, dstC, count);
235 return; 277 return;
236 } 278 }
237 279
238 uint32_t buffer[BUF_MAX]; 280 uint32_t buffer[BUF_MAX];
239 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); 281 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc();
240 SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16(); 282 SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16();
241 int max = fState.maxCountForBufferSize(sizeof(buffer)); 283 int max = state.maxCountForBufferSize(sizeof(buffer));
242 284
243 SkASSERT(state.fBitmap->getPixels()); 285 SkASSERT(state.fBitmap->getPixels());
244 SkASSERT(state.fBitmap->pixelRef() == NULL || 286 SkASSERT(state.fBitmap->pixelRef() == NULL ||
245 state.fBitmap->pixelRef()->isLocked()); 287 state.fBitmap->pixelRef()->isLocked());
246 288
247 for (;;) { 289 for (;;) {
248 int n = count; 290 int n = count;
249 if (n > max) { 291 if (n > max) {
250 n = max; 292 n = max;
251 } 293 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 377
336 #ifndef SK_IGNORE_TO_STRING 378 #ifndef SK_IGNORE_TO_STRING
337 void SkBitmapProcShader::toString(SkString* str) const { 379 void SkBitmapProcShader::toString(SkString* str) const {
338 static const char* gTileModeName[SkShader::kTileModeCount] = { 380 static const char* gTileModeName[SkShader::kTileModeCount] = {
339 "clamp", "repeat", "mirror" 381 "clamp", "repeat", "mirror"
340 }; 382 };
341 383
342 str->append("BitmapShader: ("); 384 str->append("BitmapShader: (");
343 385
344 str->appendf("(%s, %s)", 386 str->appendf("(%s, %s)",
345 gTileModeName[fState.fTileModeX], 387 gTileModeName[fTileModeX],
346 gTileModeName[fState.fTileModeY]); 388 gTileModeName[fTileModeY]);
347 389
348 str->append(" "); 390 str->append(" ");
349 fRawBitmap.toString(str); 391 fRawBitmap.toString(str);
350 392
351 this->INHERITED::toString(str); 393 this->INHERITED::toString(str);
352 394
353 str->append(")"); 395 str->append(")");
354 } 396 }
355 #endif 397 #endif
356 398
(...skipping 20 matching lines...) Expand all
377 SkMatrix matrix; 419 SkMatrix matrix;
378 matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); 420 matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height());
379 421
380 SkMatrix lmInverse; 422 SkMatrix lmInverse;
381 if (!this->getLocalMatrix().invert(&lmInverse)) { 423 if (!this->getLocalMatrix().invert(&lmInverse)) {
382 return NULL; 424 return NULL;
383 } 425 }
384 matrix.preConcat(lmInverse); 426 matrix.preConcat(lmInverse);
385 427
386 SkShader::TileMode tm[] = { 428 SkShader::TileMode tm[] = {
387 (TileMode)fState.fTileModeX, 429 (TileMode)fTileModeX,
388 (TileMode)fState.fTileModeY, 430 (TileMode)fTileModeY,
389 }; 431 };
390 432
391 // Must set wrap and filter on the sampler before requesting a texture. In t wo places below 433 // Must set wrap and filter on the sampler before requesting a texture. In t wo places below
392 // we check the matrix scale factors to determine how to interpret the filte r quality setting. 434 // we check the matrix scale factors to determine how to interpret the filte r quality setting.
393 // This completely ignores the complexity of the drawVertices case where exp licit local coords 435 // This completely ignores the complexity of the drawVertices case where exp licit local coords
394 // are provided by the caller. 436 // are provided by the caller.
395 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); 437 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel();
396 GrTextureParams::FilterMode textureFilterMode; 438 GrTextureParams::FilterMode textureFilterMode;
397 switch(paintFilterLevel) { 439 switch(paintFilterLevel) {
398 case SkPaint::kNone_FilterLevel: 440 case SkPaint::kNone_FilterLevel:
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 GrEffectRef* effect = NULL; 486 GrEffectRef* effect = NULL;
445 if (paintFilterLevel == SkPaint::kHigh_FilterLevel) { 487 if (paintFilterLevel == SkPaint::kHigh_FilterLevel) {
446 effect = GrBicubicEffect::Create(texture, matrix, tm); 488 effect = GrBicubicEffect::Create(texture, matrix, tm);
447 } else { 489 } else {
448 effect = GrSimpleTextureEffect::Create(texture, matrix, params); 490 effect = GrSimpleTextureEffect::Create(texture, matrix, params);
449 } 491 }
450 GrUnlockAndUnrefCachedBitmapTexture(texture); 492 GrUnlockAndUnrefCachedBitmapTexture(texture);
451 return effect; 493 return effect;
452 } 494 }
453 #endif 495 #endif
OLDNEW
« no previous file with comments | « src/core/SkBitmapProcShader.h ('k') | src/core/SkBitmapProcState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698