OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "GrConfigConversionEffect.h" | 8 #include "GrConfigConversionEffect.h" |
9 #include "GrContext.h" | 9 #include "GrContext.h" |
10 #include "GrDrawContext.h" | 10 #include "GrDrawContext.h" |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 return new GrGLConfigConversionEffect(); | 147 return new GrGLConfigConversionEffect(); |
148 } | 148 } |
149 | 149 |
150 | 150 |
151 | 151 |
152 void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
, | 152 void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
, |
153 PMConversion* pmTo
UPMRule, | 153 PMConversion* pmTo
UPMRule, |
154 PMConversion* upmT
oPMRule) { | 154 PMConversion* upmT
oPMRule) { |
155 *pmToUPMRule = kNone_PMConversion; | 155 *pmToUPMRule = kNone_PMConversion; |
156 *upmToPMRule = kNone_PMConversion; | 156 *upmToPMRule = kNone_PMConversion; |
157 SkAutoTMalloc<uint32_t> data(256 * 256 * 3); | 157 static constexpr int kSize = 256; |
| 158 static constexpr GrPixelConfig kConfig = kRGBA_8888_GrPixelConfig; |
| 159 SkAutoTMalloc<uint32_t> data(kSize * kSize * 3); |
158 uint32_t* srcData = data.get(); | 160 uint32_t* srcData = data.get(); |
159 uint32_t* firstRead = data.get() + 256 * 256; | 161 uint32_t* firstRead = data.get() + kSize * kSize; |
160 uint32_t* secondRead = data.get() + 2 * 256 * 256; | 162 uint32_t* secondRead = data.get() + 2 * kSize * kSize; |
161 | 163 |
162 // Fill with every possible premultiplied A, color channel value. There will
be 256-y duplicate | 164 // Fill with every possible premultiplied A, color channel value. There will
be 256-y duplicate |
163 // values in row y. We set r,g, and b to the same value since they are handl
ed identically. | 165 // values in row y. We set r,g, and b to the same value since they are handl
ed identically. |
164 for (int y = 0; y < 256; ++y) { | 166 for (int y = 0; y < kSize; ++y) { |
165 for (int x = 0; x < 256; ++x) { | 167 for (int x = 0; x < kSize; ++x) { |
166 uint8_t* color = reinterpret_cast<uint8_t*>(&srcData[256*y + x]); | 168 uint8_t* color = reinterpret_cast<uint8_t*>(&srcData[kSize*y + x]); |
167 color[3] = y; | 169 color[3] = y; |
168 color[2] = SkTMin(x, y); | 170 color[2] = SkTMin(x, y); |
169 color[1] = SkTMin(x, y); | 171 color[1] = SkTMin(x, y); |
170 color[0] = SkTMin(x, y); | 172 color[0] = SkTMin(x, y); |
171 } | 173 } |
172 } | 174 } |
173 | 175 |
174 GrSurfaceDesc desc; | 176 sk_sp<GrDrawContext> readDC(context->newDrawContext(SkBackingFit::kExact, kS
ize, kSize, |
175 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 177 kConfig)); |
176 desc.fWidth = 256; | 178 sk_sp<GrDrawContext> tempDC(context->newDrawContext(SkBackingFit::kExact, kS
ize, kSize, |
177 desc.fHeight = 256; | 179 kConfig)); |
178 desc.fConfig = kRGBA_8888_GrPixelConfig; | 180 if (!readDC || !tempDC) { |
179 desc.fIsMipMapped = false; | |
180 | |
181 SkAutoTUnref<GrTexture> readTex(context->textureProvider()->createTexture( | |
182 desc, SkBudgeted::kYes, nullptr, 0)); | |
183 if (!readTex.get()) { | |
184 return; | 181 return; |
185 } | 182 } |
186 SkAutoTUnref<GrTexture> tempTex(context->textureProvider()->createTexture( | 183 GrSurfaceDesc desc; |
187 desc, SkBudgeted::kYes, nullptr, 0)); | 184 desc.fWidth = kSize; |
188 if (!tempTex.get()) { | 185 desc.fHeight = kSize; |
189 return; | 186 desc.fConfig = kConfig; |
190 } | |
191 desc.fFlags = kNone_GrSurfaceFlags; | |
192 SkAutoTUnref<GrTexture> dataTex(context->textureProvider()->createTexture( | 187 SkAutoTUnref<GrTexture> dataTex(context->textureProvider()->createTexture( |
193 desc, SkBudgeted::kYes, data, 0)); | 188 desc, SkBudgeted::kYes, data, 0)); |
194 if (!dataTex.get()) { | 189 if (!dataTex.get()) { |
195 return; | 190 return; |
196 } | 191 } |
197 | 192 |
198 static const PMConversion kConversionRules[][2] = { | 193 static const PMConversion kConversionRules[][2] = { |
199 {kDivByAlpha_RoundDown_PMConversion, kMulByAlpha_RoundUp_PMConversion}, | 194 {kDivByAlpha_RoundDown_PMConversion, kMulByAlpha_RoundUp_PMConversion}, |
200 {kDivByAlpha_RoundUp_PMConversion, kMulByAlpha_RoundDown_PMConversion}, | 195 {kDivByAlpha_RoundUp_PMConversion, kMulByAlpha_RoundDown_PMConversion}, |
201 }; | 196 }; |
202 | 197 |
203 bool failed = true; | 198 bool failed = true; |
204 | 199 |
205 for (size_t i = 0; i < SK_ARRAY_COUNT(kConversionRules) && failed; ++i) { | 200 for (size_t i = 0; i < SK_ARRAY_COUNT(kConversionRules) && failed; ++i) { |
206 *pmToUPMRule = kConversionRules[i][0]; | 201 *pmToUPMRule = kConversionRules[i][0]; |
207 *upmToPMRule = kConversionRules[i][1]; | 202 *upmToPMRule = kConversionRules[i][1]; |
208 | 203 |
209 static const SkRect kDstRect = SkRect::MakeWH(SkIntToScalar(256), SkIntT
oScalar(256)); | 204 static const SkRect kDstRect = SkRect::MakeIWH(kSize, kSize); |
210 static const SkRect kSrcRect = SkRect::MakeWH(SK_Scalar1, SK_Scalar1); | 205 static const SkRect kSrcRect = SkRect::MakeIWH(1, 1); |
211 // We do a PM->UPM draw from dataTex to readTex and read the data. Then
we do a UPM->PM draw | 206 // We do a PM->UPM draw from dataTex to readTex and read the data. Then
we do a UPM->PM draw |
212 // from readTex to tempTex followed by a PM->UPM draw to readTex and fin
ally read the data. | 207 // from readTex to tempTex followed by a PM->UPM draw to readTex and fin
ally read the data. |
213 // We then verify that two reads produced the same values. | 208 // We then verify that two reads produced the same values. |
214 | 209 |
215 GrPaint paint1; | 210 GrPaint paint1; |
216 GrPaint paint2; | 211 GrPaint paint2; |
217 GrPaint paint3; | 212 GrPaint paint3; |
218 sk_sp<GrFragmentProcessor> pmToUPM1(new GrConfigConversionEffect( | 213 sk_sp<GrFragmentProcessor> pmToUPM1(new GrConfigConversionEffect( |
219 dataTex, GrSwizzle::RGBA(), *pmToUPMRule, SkMatrix::I())); | 214 dataTex, GrSwizzle::RGBA(), *pmToUPMRule, SkMatrix::I())); |
220 sk_sp<GrFragmentProcessor> upmToPM(new GrConfigConversionEffect( | 215 sk_sp<GrFragmentProcessor> upmToPM(new GrConfigConversionEffect( |
221 readTex, GrSwizzle::RGBA(), *upmToPMRule, SkMatrix::I())); | 216 readDC->asTexture().get(), GrSwizzle::RGBA(), *upmToPMRule, SkMa
trix::I())); |
222 sk_sp<GrFragmentProcessor> pmToUPM2(new GrConfigConversionEffect( | 217 sk_sp<GrFragmentProcessor> pmToUPM2(new GrConfigConversionEffect( |
223 tempTex, GrSwizzle::RGBA(), *pmToUPMRule, SkMatrix::I())); | 218 tempDC->asTexture().get(), GrSwizzle::RGBA(), *pmToUPMRule, SkMa
trix::I())); |
224 | 219 |
225 paint1.addColorFragmentProcessor(std::move(pmToUPM1)); | 220 paint1.addColorFragmentProcessor(std::move(pmToUPM1)); |
226 paint1.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); | 221 paint1.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); |
227 | 222 |
228 sk_sp<GrDrawContext> readDrawContext( | 223 readDC->fillRectToRect(GrNoClip(), paint1, SkMatrix::I(), kDstRect, kSrc
Rect); |
229 context->drawContext(sk_ref_sp(readTex->asRe
nderTarget()))); | |
230 if (!readDrawContext) { | |
231 failed = true; | |
232 break; | |
233 } | |
234 | 224 |
235 readDrawContext->fillRectToRect(GrNoClip(), | 225 readDC->asTexture()->readPixels(0, 0, kSize, kSize, kConfig, firstRead); |
236 paint1, | |
237 SkMatrix::I(), | |
238 kDstRect, | |
239 kSrcRect); | |
240 | |
241 readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, firstRead)
; | |
242 | 226 |
243 paint2.addColorFragmentProcessor(std::move(upmToPM)); | 227 paint2.addColorFragmentProcessor(std::move(upmToPM)); |
244 paint2.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); | 228 paint2.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); |
245 | 229 |
246 sk_sp<GrDrawContext> tempDrawContext( | 230 tempDC->fillRectToRect(GrNoClip(), paint2, SkMatrix::I(), kDstRect, kSrc
Rect); |
247 context->drawContext(sk_ref_sp(tempTex->asRe
nderTarget()))); | |
248 if (!tempDrawContext) { | |
249 failed = true; | |
250 break; | |
251 } | |
252 tempDrawContext->fillRectToRect(GrNoClip(), | |
253 paint2, | |
254 SkMatrix::I(), | |
255 kDstRect, | |
256 kSrcRect); | |
257 | 231 |
258 paint3.addColorFragmentProcessor(std::move(pmToUPM2)); | 232 paint3.addColorFragmentProcessor(std::move(pmToUPM2)); |
259 paint3.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); | 233 paint3.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); |
260 | 234 |
261 readDrawContext = context->drawContext(sk_ref_sp(readTex->asRenderTarget
())); | 235 readDC->fillRectToRect(GrNoClip(), paint3, SkMatrix::I(), kDstRect, kSrc
Rect); |
262 if (!readDrawContext) { | |
263 failed = true; | |
264 break; | |
265 } | |
266 | 236 |
267 readDrawContext->fillRectToRect(GrNoClip(), | 237 readDC->asTexture()->readPixels(0, 0, kSize, kSize, kConfig, secondRead)
; |
268 paint3, | |
269 SkMatrix::I(), | |
270 kDstRect, | |
271 kSrcRect); | |
272 | |
273 readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, secondRead
); | |
274 | 238 |
275 failed = false; | 239 failed = false; |
276 for (int y = 0; y < 256 && !failed; ++y) { | 240 for (int y = 0; y < kSize && !failed; ++y) { |
277 for (int x = 0; x <= y; ++x) { | 241 for (int x = 0; x <= y; ++x) { |
278 if (firstRead[256 * y + x] != secondRead[256 * y + x]) { | 242 if (firstRead[kSize * y + x] != secondRead[kSize * y + x]) { |
279 failed = true; | 243 failed = true; |
280 break; | 244 break; |
281 } | 245 } |
282 } | 246 } |
283 } | 247 } |
284 } | 248 } |
285 if (failed) { | 249 if (failed) { |
286 *pmToUPMRule = kNone_PMConversion; | 250 *pmToUPMRule = kNone_PMConversion; |
287 *upmToPMRule = kNone_PMConversion; | 251 *upmToPMRule = kNone_PMConversion; |
288 } | 252 } |
(...skipping 12 matching lines...) Expand all Loading... |
301 if (kRGBA_8888_GrPixelConfig != texture->config() && | 265 if (kRGBA_8888_GrPixelConfig != texture->config() && |
302 kBGRA_8888_GrPixelConfig != texture->config() && | 266 kBGRA_8888_GrPixelConfig != texture->config() && |
303 kNone_PMConversion != pmConversion) { | 267 kNone_PMConversion != pmConversion) { |
304 // The PM conversions assume colors are 0..255 | 268 // The PM conversions assume colors are 0..255 |
305 return nullptr; | 269 return nullptr; |
306 } | 270 } |
307 return sk_sp<GrFragmentProcessor>( | 271 return sk_sp<GrFragmentProcessor>( |
308 new GrConfigConversionEffect(texture, swizzle, pmConversion, matrix)
); | 272 new GrConfigConversionEffect(texture, swizzle, pmConversion, matrix)
); |
309 } | 273 } |
310 } | 274 } |
OLD | NEW |