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

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

Issue 241283003: 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/SkPictureShader.h ('k') | src/core/SkShader.cpp » ('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 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkPictureShader.h" 8 #include "SkPictureShader.h"
9 9
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 this->INHERITED::flatten(buffer); 48 this->INHERITED::flatten(buffer);
49 49
50 buffer.write32(fTmx); 50 buffer.write32(fTmx);
51 buffer.write32(fTmy); 51 buffer.write32(fTmy);
52 buffer.writeBool(NULL != fPicture); 52 buffer.writeBool(NULL != fPicture);
53 if (fPicture) { 53 if (fPicture) {
54 fPicture->flatten(buffer); 54 fPicture->flatten(buffer);
55 } 55 }
56 } 56 }
57 57
58 SkShader* SkPictureShader::buildBitmapShader(const SkMatrix& matrix) const { 58 bool SkPictureShader::buildBitmapShader(const SkMatrix& matrix) const {
59 if (!fPicture || (0 == fPicture->width() && 0 == fPicture->height())) { 59 if (!fPicture || (0 == fPicture->width() && 0 == fPicture->height())) {
60 return NULL; 60 return false;
61 } 61 }
62 62
63 SkMatrix m; 63 SkMatrix m;
64 if (this->hasLocalMatrix()) { 64 if (this->hasLocalMatrix()) {
65 m.setConcat(matrix, this->getLocalMatrix()); 65 m.setConcat(matrix, this->getLocalMatrix());
66 } else { 66 } else {
67 m = matrix; 67 m = matrix;
68 } 68 }
69 69
70 // Use a rotation-invariant scale 70 // Use a rotation-invariant scale
71 SkPoint scale; 71 SkPoint scale;
72 if (!SkDecomposeUpper2x2(m, NULL, &scale, NULL)) { 72 if (!SkDecomposeUpper2x2(m, NULL, &scale, NULL)) {
73 // Decomposition failed, use an approximation. 73 // Decomposition failed, use an approximation.
74 scale.set(SkScalarSqrt(m.getScaleX() * m.getScaleX() + m.getSkewX() * m. getSkewX()), 74 scale.set(SkScalarSqrt(m.getScaleX() * m.getScaleX() + m.getSkewX() * m. getSkewX()),
75 SkScalarSqrt(m.getScaleY() * m.getScaleY() + m.getSkewY() * m. getSkewY())); 75 SkScalarSqrt(m.getScaleY() * m.getScaleY() + m.getSkewY() * m. getSkewY()));
76 } 76 }
77 SkSize scaledSize = SkSize::Make(scale.x() * fPicture->width(), scale.y() * fPicture->height()); 77 SkSize scaledSize = SkSize::Make(scale.x() * fPicture->width(), scale.y() * fPicture->height());
78 78
79 SkISize tileSize = scaledSize.toRound(); 79 SkISize tileSize = scaledSize.toRound();
80 if (tileSize.isEmpty()) { 80 if (tileSize.isEmpty()) {
81 return NULL; 81 return false;
82 } 82 }
83 83
84 // The actual scale, compensating for rounding. 84 // The actual scale, compensating for rounding.
85 SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fPicture-> width(), 85 SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fPicture-> width(),
86 SkIntToScalar(tileSize.height()) / fPicture- >height()); 86 SkIntToScalar(tileSize.height()) / fPicture- >height());
87 87
88 SkAutoMutexAcquire ama(fCachedBitmapShaderMutex); 88 if (!fCachedShader || tileScale != fCachedTileScale) {
89
90 if (!fCachedBitmapShader || tileScale != fCachedTileScale ||
91 this->getLocalMatrix() != fCachedLocalMatrix) {
92 SkBitmap bm; 89 SkBitmap bm;
93 if (!bm.allocN32Pixels(tileSize.width(), tileSize.height())) { 90 if (!bm.allocN32Pixels(tileSize.width(), tileSize.height())) {
94 return NULL; 91 return false;
95 } 92 }
96 bm.eraseColor(SK_ColorTRANSPARENT); 93 bm.eraseColor(SK_ColorTRANSPARENT);
97 94
98 SkCanvas canvas(bm); 95 SkCanvas canvas(bm);
99 canvas.scale(tileScale.width(), tileScale.height()); 96 canvas.scale(tileScale.width(), tileScale.height());
100 canvas.drawPicture(*fPicture); 97 canvas.drawPicture(*fPicture);
101 98
102 fCachedBitmapShader.reset(CreateBitmapShader(bm, fTmx, fTmy)); 99 fCachedShader.reset(CreateBitmapShader(bm, fTmx, fTmy));
103 fCachedTileScale = tileScale; 100 fCachedTileScale = tileScale;
104 fCachedLocalMatrix = this->getLocalMatrix();
105
106 SkMatrix shaderMatrix = this->getLocalMatrix();
107 shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height());
108 fCachedBitmapShader->setLocalMatrix(shaderMatrix);
109 } 101 }
110 102
111 // Increment the ref counter inside the mutex to ensure the returned pointer is still valid. 103 SkMatrix shaderMatrix = this->getLocalMatrix();
112 // Otherwise, the pointer may have been overwritten on a different thread be fore the object's 104 shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height());
113 // ref count was incremented. 105 fCachedShader->setLocalMatrix(shaderMatrix);
114 fCachedBitmapShader.get()->ref(); 106
115 return fCachedBitmapShader; 107 return true;
116 } 108 }
117 109
118 SkShader* SkPictureShader::validInternal(const SkBitmap& device, const SkPaint& paint, 110 bool SkPictureShader::setContext(const SkBitmap& device,
119 const SkMatrix& matrix, SkMatrix* total Inverse) const { 111 const SkPaint& paint,
120 if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) { 112 const SkMatrix& matrix) {
121 return NULL; 113 if (!this->buildBitmapShader(matrix)) {
114 return false;
122 } 115 }
123 116
124 SkShader* bitmapShader = this->buildBitmapShader(matrix); 117 if (!this->INHERITED::setContext(device, paint, matrix)) {
125 if (!bitmapShader) { 118 return false;
126 return NULL;
127 } 119 }
128 120
129 if (!bitmapShader->validContext(device, paint, matrix)) { 121 SkASSERT(fCachedShader);
130 bitmapShader->unref(); 122 if (!fCachedShader->setContext(device, paint, matrix)) {
131 return NULL; 123 this->INHERITED::endContext();
124 return false;
132 } 125 }
133 126
134 return bitmapShader; 127 return true;
135 } 128 }
136 129
137 bool SkPictureShader::validContext(const SkBitmap& device, const SkPaint& paint, 130 void SkPictureShader::endContext() {
138 const SkMatrix& matrix, SkMatrix* totalInvers e) const { 131 SkASSERT(fCachedShader);
139 SkAutoTUnref<SkShader> shader(this->validInternal(device, paint, matrix, tot alInverse)); 132 fCachedShader->endContext();
140 return shader != NULL; 133
134 this->INHERITED::endContext();
141 } 135 }
142 136
143 SkShader::Context* SkPictureShader::createContext(const SkBitmap& device, const SkPaint& paint, 137 uint32_t SkPictureShader::getFlags() {
144 const SkMatrix& matrix, void* storage) const { 138 if (NULL != fCachedShader) {
145 SkShader* bitmapShader = this->validInternal(device, paint, matrix, NULL); 139 return fCachedShader->getFlags();
146 if (!bitmapShader) {
147 return NULL;
148 } 140 }
149 141 return 0;
150 return SkNEW_PLACEMENT_ARGS(storage, PictureShaderContext,
151 (*this, device, paint, matrix, bitmapShader));
152 } 142 }
153 143
154 size_t SkPictureShader::contextSize() const { 144 SkShader::ShadeProc SkPictureShader::asAShadeProc(void** ctx) {
155 return sizeof(PictureShaderContext); 145 if (fCachedShader) {
146 return fCachedShader->asAShadeProc(ctx);
147 }
148 return NULL;
156 } 149 }
157 150
158 SkPictureShader::PictureShaderContext::PictureShaderContext( 151 void SkPictureShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
159 const SkPictureShader& shader, const SkBitmap& device, 152 SkASSERT(fCachedShader);
160 const SkPaint& paint, const SkMatrix& matrix, SkShader* bitmapShader) 153 fCachedShader->shadeSpan(x, y, dstC, count);
161 : INHERITED(shader, device, paint, matrix)
162 , fBitmapShader(bitmapShader)
163 {
164 SkASSERT(fBitmapShader);
165 fBitmapShaderContextStorage = sk_malloc_throw(fBitmapShader->contextSize());
166 fBitmapShaderContext = fBitmapShader->createContext(
167 device, paint, matrix, fBitmapShaderContextStorage);
168 SkASSERT(fBitmapShaderContext);
169 } 154 }
170 155
171 SkPictureShader::PictureShaderContext::~PictureShaderContext() { 156 void SkPictureShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) {
172 fBitmapShaderContext->SkShader::Context::~Context(); 157 SkASSERT(fCachedShader);
173 sk_free(fBitmapShaderContextStorage); 158 fCachedShader->shadeSpan16(x, y, dstC, count);
174 }
175
176 uint32_t SkPictureShader::PictureShaderContext::getFlags() const {
177 return fBitmapShaderContext->getFlags();
178 }
179
180 SkShader::Context::ShadeProc SkPictureShader::PictureShaderContext::asAShadeProc (void** ctx) {
181 return fBitmapShaderContext->asAShadeProc(ctx);
182 }
183
184 void SkPictureShader::PictureShaderContext::shadeSpan(int x, int y, SkPMColor ds tC[], int count) {
185 SkASSERT(fBitmapShaderContext);
186 fBitmapShaderContext->shadeSpan(x, y, dstC, count);
187 }
188
189 void SkPictureShader::PictureShaderContext::shadeSpan16(int x, int y, uint16_t d stC[], int count) {
190 SkASSERT(fBitmapShaderContext);
191 fBitmapShaderContext->shadeSpan16(x, y, dstC, count);
192 } 159 }
193 160
194 #ifndef SK_IGNORE_TO_STRING 161 #ifndef SK_IGNORE_TO_STRING
195 void SkPictureShader::toString(SkString* str) const { 162 void SkPictureShader::toString(SkString* str) const {
196 static const char* gTileModeName[SkShader::kTileModeCount] = { 163 static const char* gTileModeName[SkShader::kTileModeCount] = {
197 "clamp", "repeat", "mirror" 164 "clamp", "repeat", "mirror"
198 }; 165 };
199 166
200 str->appendf("PictureShader: [%d:%d] ", 167 str->appendf("PictureShader: [%d:%d] ",
201 fPicture ? fPicture->width() : 0, 168 fPicture ? fPicture->width() : 0,
202 fPicture ? fPicture->height() : 0); 169 fPicture ? fPicture->height() : 0);
203 170
204 str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]); 171 str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]);
205 172
206 this->INHERITED::toString(str); 173 this->INHERITED::toString(str);
207 } 174 }
208 #endif 175 #endif
209 176
210 #if SK_SUPPORT_GPU 177 #if SK_SUPPORT_GPU
211 GrEffectRef* SkPictureShader::asNewEffect(GrContext* context, const SkPaint& pai nt) const { 178 GrEffectRef* SkPictureShader::asNewEffect(GrContext* context, const SkPaint& pai nt) const {
212 SkAutoTUnref<SkShader> bitmapShader(this->buildBitmapShader(context->getMatr ix())); 179 if (!this->buildBitmapShader(context->getMatrix())) {
213 if (!bitmapShader) {
214 return NULL; 180 return NULL;
215 } 181 }
216 return bitmapShader->asNewEffect(context, paint); 182 SkASSERT(fCachedShader);
183 return fCachedShader->asNewEffect(context, paint);
217 } 184 }
218 #endif 185 #endif
OLDNEW
« no previous file with comments | « src/core/SkPictureShader.h ('k') | src/core/SkShader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698