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

Side by Side Diff: src/core/SkComposeShader.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/SkCanvas.cpp ('k') | src/core/SkCoreBlitters.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 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
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 8
9 9
10 #include "SkComposeShader.h" 10 #include "SkComposeShader.h"
(...skipping 27 matching lines...) Expand all
38 } 38 }
39 fMode = buffer.readXfermode(); 39 fMode = buffer.readXfermode();
40 } 40 }
41 41
42 SkComposeShader::~SkComposeShader() { 42 SkComposeShader::~SkComposeShader() {
43 SkSafeUnref(fMode); 43 SkSafeUnref(fMode);
44 fShaderB->unref(); 44 fShaderB->unref();
45 fShaderA->unref(); 45 fShaderA->unref();
46 } 46 }
47 47
48 size_t SkComposeShader::contextSize() const {
49 return sizeof(ComposeShaderContext) + fShaderA->contextSize() + fShaderB->co ntextSize();
50 }
51
52 class SkAutoAlphaRestore { 48 class SkAutoAlphaRestore {
53 public: 49 public:
54 SkAutoAlphaRestore(SkPaint* paint, uint8_t newAlpha) { 50 SkAutoAlphaRestore(SkPaint* paint, uint8_t newAlpha) {
55 fAlpha = paint->getAlpha(); 51 fAlpha = paint->getAlpha();
56 fPaint = paint; 52 fPaint = paint;
57 paint->setAlpha(newAlpha); 53 paint->setAlpha(newAlpha);
58 } 54 }
59 55
60 ~SkAutoAlphaRestore() { 56 ~SkAutoAlphaRestore() {
61 fPaint->setAlpha(fAlpha); 57 fPaint->setAlpha(fAlpha);
62 } 58 }
63 private: 59 private:
64 SkPaint* fPaint; 60 SkPaint* fPaint;
65 uint8_t fAlpha; 61 uint8_t fAlpha;
66 }; 62 };
67 #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore) 63 #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore)
68 64
69 void SkComposeShader::flatten(SkWriteBuffer& buffer) const { 65 void SkComposeShader::flatten(SkWriteBuffer& buffer) const {
70 this->INHERITED::flatten(buffer); 66 this->INHERITED::flatten(buffer);
71 buffer.writeFlattenable(fShaderA); 67 buffer.writeFlattenable(fShaderA);
72 buffer.writeFlattenable(fShaderB); 68 buffer.writeFlattenable(fShaderB);
73 buffer.writeFlattenable(fMode); 69 buffer.writeFlattenable(fMode);
74 } 70 }
75 71
76 /* We call validContext/createContext on our two worker shaders. 72 /* We call setContext on our two worker shaders. However, we
77 However, we always let them see opaque alpha, and if the paint 73 always let them see opaque alpha, and if the paint really
78 really is translucent, then we apply that after the fact. 74 is translucent, then we apply that after the fact.
79 75
76 We need to keep the calls to setContext/endContext balanced, since if we
77 return false, our endContext() will not be called.
80 */ 78 */
81 bool SkComposeShader::validContext(const SkBitmap& device, 79 bool SkComposeShader::setContext(const SkBitmap& device,
82 const SkPaint& paint, 80 const SkPaint& paint,
83 const SkMatrix& matrix, 81 const SkMatrix& matrix) {
84 SkMatrix* totalInverse) const { 82 if (!this->INHERITED::setContext(device, paint, matrix)) {
85 if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
86 return false; 83 return false;
87 } 84 }
88 85
89 // we preconcat our localMatrix (if any) with the device matrix 86 // we preconcat our localMatrix (if any) with the device matrix
90 // before calling our sub-shaders
91
92 SkMatrix tmpM;
93
94 tmpM.setConcat(matrix, this->getLocalMatrix());
95
96 return fShaderA->validContext(device, paint, tmpM) &&
97 fShaderB->validContext(device, paint, tmpM);
98 }
99
100 SkShader::Context* SkComposeShader::createContext(const SkBitmap& device, const SkPaint& paint,
101 const SkMatrix& matrix, void* storage) const {
102 if (!this->validContext(device, paint, matrix)) {
103 return NULL;
104 }
105
106 // we preconcat our localMatrix (if any) with the device matrix
107 // before calling our sub-shaders 87 // before calling our sub-shaders
108 88
109 SkMatrix tmpM; 89 SkMatrix tmpM;
110 90
111 tmpM.setConcat(matrix, this->getLocalMatrix()); 91 tmpM.setConcat(matrix, this->getLocalMatrix());
112 92
113 SkAutoAlphaRestore restore(const_cast<SkPaint*>(&paint), 0xFF); 93 SkAutoAlphaRestore restore(const_cast<SkPaint*>(&paint), 0xFF);
114 94
115 char* aStorage = (char*) storage + sizeof(ComposeShaderContext); 95 bool setContextA = fShaderA->setContext(device, paint, tmpM);
116 char* bStorage = aStorage + fShaderA->contextSize(); 96 bool setContextB = fShaderB->setContext(device, paint, tmpM);
117 97 if (!setContextA || !setContextB) {
118 SkShader::Context* contextA = fShaderA->createContext(device, paint, tmpM, a Storage); 98 if (setContextB) {
119 SkShader::Context* contextB = fShaderB->createContext(device, paint, tmpM, b Storage); 99 fShaderB->endContext();
120 100 }
121 // Both functions must succeed; otherwise validContext should have returned 101 else if (setContextA) {
122 // false. 102 fShaderA->endContext();
123 SkASSERT(contextA); 103 }
124 SkASSERT(contextB); 104 this->INHERITED::endContext();
125 105 return false;
126 return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext, 106 }
127 (*this, device, paint, matrix, contextA, context B)); 107 return true;
128 } 108 }
129 109
130 SkComposeShader::ComposeShaderContext::ComposeShaderContext( 110 void SkComposeShader::endContext() {
131 const SkComposeShader& shader, const SkBitmap& device, 111 fShaderB->endContext();
132 const SkPaint& paint, const SkMatrix& matrix, 112 fShaderA->endContext();
133 SkShader::Context* contextA, SkShader::Context* contextB) 113 this->INHERITED::endContext();
134 : INHERITED(shader, device, paint, matrix)
135 , fShaderContextA(contextA)
136 , fShaderContextB(contextB) {}
137
138 SkComposeShader::ComposeShaderContext::~ComposeShaderContext() {
139 fShaderContextA->SkShader::Context::~Context();
140 fShaderContextB->SkShader::Context::~Context();
141 } 114 }
142 115
143 // larger is better (fewer times we have to loop), but we shouldn't 116 // larger is better (fewer times we have to loop), but we shouldn't
144 // take up too much stack-space (each element is 4 bytes) 117 // take up too much stack-space (each element is 4 bytes)
145 #define TMP_COLOR_COUNT 64 118 #define TMP_COLOR_COUNT 64
146 119
147 void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor re sult[], int count) { 120 void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
148 SkShader::Context* shaderContextA = fShaderContextA; 121 SkShader* shaderA = fShaderA;
149 SkShader::Context* shaderContextB = fShaderContextB; 122 SkShader* shaderB = fShaderB;
150 SkXfermode* mode = static_cast<const SkComposeShader&>(fShader).fMode ; 123 SkXfermode* mode = fMode;
151 unsigned scale = SkAlpha255To256(this->getPaintAlpha()); 124 unsigned scale = SkAlpha255To256(this->getPaintAlpha());
152 125
153 SkPMColor tmp[TMP_COLOR_COUNT]; 126 SkPMColor tmp[TMP_COLOR_COUNT];
154 127
155 if (NULL == mode) { // implied SRC_OVER 128 if (NULL == mode) { // implied SRC_OVER
156 // TODO: when we have a good test-case, should use SkBlitRow::Proc32 129 // TODO: when we have a good test-case, should use SkBlitRow::Proc32
157 // for these loops 130 // for these loops
158 do { 131 do {
159 int n = count; 132 int n = count;
160 if (n > TMP_COLOR_COUNT) { 133 if (n > TMP_COLOR_COUNT) {
161 n = TMP_COLOR_COUNT; 134 n = TMP_COLOR_COUNT;
162 } 135 }
163 136
164 shaderContextA->shadeSpan(x, y, result, n); 137 shaderA->shadeSpan(x, y, result, n);
165 shaderContextB->shadeSpan(x, y, tmp, n); 138 shaderB->shadeSpan(x, y, tmp, n);
166 139
167 if (256 == scale) { 140 if (256 == scale) {
168 for (int i = 0; i < n; i++) { 141 for (int i = 0; i < n; i++) {
169 result[i] = SkPMSrcOver(tmp[i], result[i]); 142 result[i] = SkPMSrcOver(tmp[i], result[i]);
170 } 143 }
171 } else { 144 } else {
172 for (int i = 0; i < n; i++) { 145 for (int i = 0; i < n; i++) {
173 result[i] = SkAlphaMulQ(SkPMSrcOver(tmp[i], result[i]), 146 result[i] = SkAlphaMulQ(SkPMSrcOver(tmp[i], result[i]),
174 scale); 147 scale);
175 } 148 }
176 } 149 }
177 150
178 result += n; 151 result += n;
179 x += n; 152 x += n;
180 count -= n; 153 count -= n;
181 } while (count > 0); 154 } while (count > 0);
182 } else { // use mode for the composition 155 } else { // use mode for the composition
183 do { 156 do {
184 int n = count; 157 int n = count;
185 if (n > TMP_COLOR_COUNT) { 158 if (n > TMP_COLOR_COUNT) {
186 n = TMP_COLOR_COUNT; 159 n = TMP_COLOR_COUNT;
187 } 160 }
188 161
189 shaderContextA->shadeSpan(x, y, result, n); 162 shaderA->shadeSpan(x, y, result, n);
190 shaderContextB->shadeSpan(x, y, tmp, n); 163 shaderB->shadeSpan(x, y, tmp, n);
191 mode->xfer32(result, tmp, n, NULL); 164 mode->xfer32(result, tmp, n, NULL);
192 165
193 if (256 == scale) { 166 if (256 == scale) {
194 for (int i = 0; i < n; i++) { 167 for (int i = 0; i < n; i++) {
195 result[i] = SkAlphaMulQ(result[i], scale); 168 result[i] = SkAlphaMulQ(result[i], scale);
196 } 169 }
197 } 170 }
198 171
199 result += n; 172 result += n;
200 x += n; 173 x += n;
(...skipping 11 matching lines...) Expand all
212 str->append(" ShaderB: "); 185 str->append(" ShaderB: ");
213 fShaderB->toString(str); 186 fShaderB->toString(str);
214 str->append(" Xfermode: "); 187 str->append(" Xfermode: ");
215 fMode->toString(str); 188 fMode->toString(str);
216 189
217 this->INHERITED::toString(str); 190 this->INHERITED::toString(str);
218 191
219 str->append(")"); 192 str->append(")");
220 } 193 }
221 #endif 194 #endif
OLDNEW
« no previous file with comments | « src/core/SkCanvas.cpp ('k') | src/core/SkCoreBlitters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698