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

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

Issue 265163008: fix composeshader to respect the paint's alpha (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 newRec.fMatrix = &tmpM; 93 newRec.fMatrix = &tmpM;
94 94
95 return fShaderA->validContext(newRec) && fShaderB->validContext(newRec); 95 return fShaderA->validContext(newRec) && fShaderB->validContext(newRec);
96 } 96 }
97 97
98 SkShader::Context* SkComposeShader::createContext(const ContextRec& rec, void* s torage) const { 98 SkShader::Context* SkComposeShader::createContext(const ContextRec& rec, void* s torage) const {
99 if (!this->validContext(rec)) { 99 if (!this->validContext(rec)) {
100 return NULL; 100 return NULL;
101 } 101 }
102 102
103 // TODO : must fix this to not "cheat" and modify fPaint
104 SkAutoAlphaRestore restore(const_cast<SkPaint*>(rec.fPaint), 0xFF);
105
106 char* aStorage = (char*) storage + sizeof(ComposeShaderContext); 103 char* aStorage = (char*) storage + sizeof(ComposeShaderContext);
107 char* bStorage = aStorage + fShaderA->contextSize(); 104 char* bStorage = aStorage + fShaderA->contextSize();
108 105
109 // we preconcat our localMatrix (if any) with the device matrix 106 // we preconcat our localMatrix (if any) with the device matrix
110 // before calling our sub-shaders 107 // before calling our sub-shaders
111
112 SkMatrix tmpM; 108 SkMatrix tmpM;
113 tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); 109 tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix());
114 110
111 // Our sub-shaders need to see opaque, so by combining them we don't double- alphatize the
112 // result. ComposeShader itself will respect the alpha, and post-apply it af ter calling the
113 // sub-shaders.
114 SkPaint opaquePaint(*rec.fPaint);
115 opaquePaint.setAlpha(0xFF);
116
115 ContextRec newRec(rec); 117 ContextRec newRec(rec);
116 newRec.fMatrix = &tmpM; 118 newRec.fMatrix = &tmpM;
119 newRec.fPaint = &opaquePaint;
117 120
118 SkShader::Context* contextA = fShaderA->createContext(newRec, aStorage); 121 SkShader::Context* contextA = fShaderA->createContext(newRec, aStorage);
119 SkShader::Context* contextB = fShaderB->createContext(newRec, bStorage); 122 SkShader::Context* contextB = fShaderB->createContext(newRec, bStorage);
120 123
121 // Both functions must succeed; otherwise validContext should have returned 124 // Both functions must succeed; otherwise validContext should have returned
122 // false. 125 // false.
123 SkASSERT(contextA); 126 SkASSERT(contextA);
124 SkASSERT(contextB); 127 SkASSERT(contextB);
125 128
126 return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext, (*this, rec, cont extA, contextB)); 129 return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext, (*this, rec, cont extA, contextB));
(...skipping 14 matching lines...) Expand all
141 // larger is better (fewer times we have to loop), but we shouldn't 144 // larger is better (fewer times we have to loop), but we shouldn't
142 // take up too much stack-space (each element is 4 bytes) 145 // take up too much stack-space (each element is 4 bytes)
143 #define TMP_COLOR_COUNT 64 146 #define TMP_COLOR_COUNT 64
144 147
145 void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor re sult[], int count) { 148 void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor re sult[], int count) {
146 SkShader::Context* shaderContextA = fShaderContextA; 149 SkShader::Context* shaderContextA = fShaderContextA;
147 SkShader::Context* shaderContextB = fShaderContextB; 150 SkShader::Context* shaderContextB = fShaderContextB;
148 SkXfermode* mode = static_cast<const SkComposeShader&>(fShader).fMode ; 151 SkXfermode* mode = static_cast<const SkComposeShader&>(fShader).fMode ;
149 unsigned scale = SkAlpha255To256(this->getPaintAlpha()); 152 unsigned scale = SkAlpha255To256(this->getPaintAlpha());
150 153
154 #ifdef SK_BUILD_FOR_ANDROID
155 scale = 256; // ugh -- maintain old bug/behavior for now
156 #endif
157
151 SkPMColor tmp[TMP_COLOR_COUNT]; 158 SkPMColor tmp[TMP_COLOR_COUNT];
152 159
153 if (NULL == mode) { // implied SRC_OVER 160 if (NULL == mode) { // implied SRC_OVER
154 // TODO: when we have a good test-case, should use SkBlitRow::Proc32 161 // TODO: when we have a good test-case, should use SkBlitRow::Proc32
155 // for these loops 162 // for these loops
156 do { 163 do {
157 int n = count; 164 int n = count;
158 if (n > TMP_COLOR_COUNT) { 165 if (n > TMP_COLOR_COUNT) {
159 n = TMP_COLOR_COUNT; 166 n = TMP_COLOR_COUNT;
160 } 167 }
(...skipping 20 matching lines...) Expand all
181 do { 188 do {
182 int n = count; 189 int n = count;
183 if (n > TMP_COLOR_COUNT) { 190 if (n > TMP_COLOR_COUNT) {
184 n = TMP_COLOR_COUNT; 191 n = TMP_COLOR_COUNT;
185 } 192 }
186 193
187 shaderContextA->shadeSpan(x, y, result, n); 194 shaderContextA->shadeSpan(x, y, result, n);
188 shaderContextB->shadeSpan(x, y, tmp, n); 195 shaderContextB->shadeSpan(x, y, tmp, n);
189 mode->xfer32(result, tmp, n, NULL); 196 mode->xfer32(result, tmp, n, NULL);
190 197
191 if (256 == scale) { 198 if (256 != scale) {
192 for (int i = 0; i < n; i++) { 199 for (int i = 0; i < n; i++) {
193 result[i] = SkAlphaMulQ(result[i], scale); 200 result[i] = SkAlphaMulQ(result[i], scale);
194 } 201 }
195 } 202 }
196 203
197 result += n; 204 result += n;
198 x += n; 205 x += n;
199 count -= n; 206 count -= n;
200 } while (count > 0); 207 } while (count > 0);
201 } 208 }
202 } 209 }
203 210
204 #ifndef SK_IGNORE_TO_STRING 211 #ifndef SK_IGNORE_TO_STRING
205 void SkComposeShader::toString(SkString* str) const { 212 void SkComposeShader::toString(SkString* str) const {
206 str->append("SkComposeShader: ("); 213 str->append("SkComposeShader: (");
207 214
208 str->append("ShaderA: "); 215 str->append("ShaderA: ");
209 fShaderA->toString(str); 216 fShaderA->toString(str);
210 str->append(" ShaderB: "); 217 str->append(" ShaderB: ");
211 fShaderB->toString(str); 218 fShaderB->toString(str);
212 str->append(" Xfermode: "); 219 str->append(" Xfermode: ");
213 fMode->toString(str); 220 fMode->toString(str);
214 221
215 this->INHERITED::toString(str); 222 this->INHERITED::toString(str);
216 223
217 str->append(")"); 224 str->append(")");
218 } 225 }
219 #endif 226 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698