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

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

Issue 160103002: Work in progress to make SkShader immutable. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 10 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/SkBlitter_ARGB32.cpp ('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 /* 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 }; 62 };
63 #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore) 63 #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore)
64 64
65 void SkComposeShader::flatten(SkWriteBuffer& buffer) const { 65 void SkComposeShader::flatten(SkWriteBuffer& buffer) const {
66 this->INHERITED::flatten(buffer); 66 this->INHERITED::flatten(buffer);
67 buffer.writeFlattenable(fShaderA); 67 buffer.writeFlattenable(fShaderA);
68 buffer.writeFlattenable(fShaderB); 68 buffer.writeFlattenable(fShaderB);
69 buffer.writeFlattenable(fMode); 69 buffer.writeFlattenable(fMode);
70 } 70 }
71 71
72 struct ComposeContext {
73 SkShader::Context* fContextA;
74 SkShader::Context* fContextB;
75 };
76
77 // Helper function to get the ComposeContext from the Context.
78 static ComposeContext* get_compose_context(SkShader::Context* c, const SkShader& shader) {
79 return (ComposeContext*) shader.getMyContext(c);
80 }
81
82 size_t SkComposeShader::getMySpaceNeededForContext() const {
83 return sizeof(ComposeContext);
84 }
85
72 /* We call setContext on our two worker shaders. However, we 86 /* We call setContext on our two worker shaders. However, we
73 always let them see opaque alpha, and if the paint really 87 always let them see opaque alpha, and if the paint really
74 is translucent, then we apply that after the fact. 88 is translucent, then we apply that after the fact.
75 89
76 We need to keep the calls to setContext/endContext balanced, since if we 90 We need to keep the calls to setContext/endContext balanced, since if we
77 return false, our endContext() will not be called. 91 return false, our endContext() will not be called.
78 */ 92 */
79 bool SkComposeShader::setContext(const SkBitmap& device, 93 bool SkComposeShader::onSetContext(Context* c, const SkBitmap& device,
80 const SkPaint& paint, 94 const SkPaint& paint,
81 const SkMatrix& matrix) { 95 const SkMatrix& matrix) {
82 if (!this->INHERITED::setContext(device, paint, matrix)) { 96 if (!this->INHERITED::onSetContext(c, device, paint, matrix)) {
83 return false; 97 return false;
84 } 98 }
85 99
86 // we preconcat our localMatrix (if any) with the device matrix 100 // we preconcat our localMatrix (if any) with the device matrix
87 // before calling our sub-shaders 101 // before calling our sub-shaders
88 102
89 SkMatrix tmpM; 103 SkMatrix tmpM;
90 104
105 // Will come from the paint.
91 tmpM.setConcat(matrix, this->getLocalMatrix()); 106 tmpM.setConcat(matrix, this->getLocalMatrix());
92 107
93 SkAutoAlphaRestore restore(const_cast<SkPaint*>(&paint), 0xFF); 108 SkAutoAlphaRestore restore(const_cast<SkPaint*>(&paint), 0xFF);
94 109
95 bool setContextA = fShaderA->setContext(device, paint, tmpM); 110 SkShader::Context* contextA = fShaderA->setContext(device, paint, tmpM);
96 bool setContextB = fShaderB->setContext(device, paint, tmpM); 111 if (!contextA) {
97 if (!setContextA || !setContextB) {
98 if (setContextB) {
99 fShaderB->endContext();
100 }
101 else if (setContextA) {
102 fShaderA->endContext();
103 }
104 this->INHERITED::endContext();
105 return false; 112 return false;
106 } 113 }
114
115 SkShader::Context* contextB = fShaderB->setContext(device, paint, tmpM);
116 if (!contextB) {
117 SkDELETE(contextA);
118 return false;
119 }
120
121 ComposeContext* composeContext = get_compose_context(c, *this);
122 composeContext->fContextA = contextA;
123 composeContext->fContextB = contextB;
124
107 return true; 125 return true;
108 } 126 }
109 127
110 void SkComposeShader::endContext() { 128 void SkComposeShader::endContext(Context* c) {
111 fShaderB->endContext(); 129 ComposeContext* composeContext = get_compose_context(c, *this);
112 fShaderA->endContext(); 130
113 this->INHERITED::endContext(); 131 fShaderB->endContext(c->fContextA);
132 fShaderA->endContext(c->fContextB);
133 this->INHERITED::endContext(c);
114 } 134 }
115 135
116 // larger is better (fewer times we have to loop), but we shouldn't 136 // larger is better (fewer times we have to loop), but we shouldn't
117 // take up too much stack-space (each element is 4 bytes) 137 // take up too much stack-space (each element is 4 bytes)
118 #define TMP_COLOR_COUNT 64 138 #define TMP_COLOR_COUNT 64
119 139
120 void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) { 140 void SkComposeShader::shadeSpan(Context* c, int x, int y, SkPMColor result[], in t count) {
121 SkShader* shaderA = fShaderA; 141 SkShader* shaderA = fShaderA;
122 SkShader* shaderB = fShaderB; 142 SkShader* shaderB = fShaderB;
123 SkXfermode* mode = fMode; 143 SkXfermode* mode = fMode;
124 unsigned scale = SkAlpha255To256(this->getPaintAlpha()); 144 unsigned scale = SkAlpha255To256(c->getPaintAlpha());
125 145
126 SkPMColor tmp[TMP_COLOR_COUNT]; 146 SkPMColor tmp[TMP_COLOR_COUNT];
127 147
148 ComposeContext* composeContext = get_compose_context(c, *this);
149
128 if (NULL == mode) { // implied SRC_OVER 150 if (NULL == mode) { // implied SRC_OVER
129 // TODO: when we have a good test-case, should use SkBlitRow::Proc32 151 // TODO: when we have a good test-case, should use SkBlitRow::Proc32
130 // for these loops 152 // for these loops
131 do { 153 do {
132 int n = count; 154 int n = count;
133 if (n > TMP_COLOR_COUNT) { 155 if (n > TMP_COLOR_COUNT) {
134 n = TMP_COLOR_COUNT; 156 n = TMP_COLOR_COUNT;
135 } 157 }
136 158
137 shaderA->shadeSpan(x, y, result, n); 159 shaderA->shadeSpan(composeContext->fContextA, x, y, result, n);
138 shaderB->shadeSpan(x, y, tmp, n); 160 shaderB->shadeSpan(composeContext->fContextB, x, y, tmp, n);
139 161
140 if (256 == scale) { 162 if (256 == scale) {
141 for (int i = 0; i < n; i++) { 163 for (int i = 0; i < n; i++) {
142 result[i] = SkPMSrcOver(tmp[i], result[i]); 164 result[i] = SkPMSrcOver(tmp[i], result[i]);
143 } 165 }
144 } else { 166 } else {
145 for (int i = 0; i < n; i++) { 167 for (int i = 0; i < n; i++) {
146 result[i] = SkAlphaMulQ(SkPMSrcOver(tmp[i], result[i]), 168 result[i] = SkAlphaMulQ(SkPMSrcOver(tmp[i], result[i]),
147 scale); 169 scale);
148 } 170 }
149 } 171 }
150 172
151 result += n; 173 result += n;
152 x += n; 174 x += n;
153 count -= n; 175 count -= n;
154 } while (count > 0); 176 } while (count > 0);
155 } else { // use mode for the composition 177 } else { // use mode for the composition
156 do { 178 do {
157 int n = count; 179 int n = count;
158 if (n > TMP_COLOR_COUNT) { 180 if (n > TMP_COLOR_COUNT) {
159 n = TMP_COLOR_COUNT; 181 n = TMP_COLOR_COUNT;
160 } 182 }
161 183
162 shaderA->shadeSpan(x, y, result, n); 184 shaderA->shadeSpan(composeContext->fContextA, x, y, result, n);
163 shaderB->shadeSpan(x, y, tmp, n); 185 shaderB->shadeSpan(composeContext->fContextB, x, y, tmp, n);
164 mode->xfer32(result, tmp, n, NULL); 186 mode->xfer32(result, tmp, n, NULL);
165 187
166 if (256 == scale) { 188 if (256 == scale) {
167 for (int i = 0; i < n; i++) { 189 for (int i = 0; i < n; i++) {
168 result[i] = SkAlphaMulQ(result[i], scale); 190 result[i] = SkAlphaMulQ(result[i], scale);
169 } 191 }
170 } 192 }
171 193
172 result += n; 194 result += n;
173 x += n; 195 x += n;
(...skipping 11 matching lines...) Expand all
185 str->append(" ShaderB: "); 207 str->append(" ShaderB: ");
186 fShaderB->toString(str); 208 fShaderB->toString(str);
187 str->append(" Xfermode: "); 209 str->append(" Xfermode: ");
188 fMode->toString(str); 210 fMode->toString(str);
189 211
190 this->INHERITED::toString(str); 212 this->INHERITED::toString(str);
191 213
192 str->append(")"); 214 str->append(")");
193 } 215 }
194 #endif 216 #endif
OLDNEW
« no previous file with comments | « src/core/SkBlitter_ARGB32.cpp ('k') | src/core/SkShader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698