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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 | 93 |
94 typedef GrGLFragmentProcessor INHERITED; | 94 typedef GrGLFragmentProcessor INHERITED; |
95 | 95 |
96 }; | 96 }; |
97 | 97 |
98 /////////////////////////////////////////////////////////////////////////////// | 98 /////////////////////////////////////////////////////////////////////////////// |
99 | 99 |
100 GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture, | 100 GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture, |
101 bool swapRedAndBlue, | 101 bool swapRedAndBlue, |
102 PMConversion pmConversion, | 102 PMConversion pmConversion, |
103 const SkMatrix& matrix) | 103 const SkMatrix& matrix, GrRen
derTarget* dst) |
104 : INHERITED(texture, matrix) | 104 : INHERITED(texture, matrix, kLocal_GrCoordSet, dst) |
105 , fSwapRedAndBlue(swapRedAndBlue) | 105 , fSwapRedAndBlue(swapRedAndBlue) |
106 , fPMConversion(pmConversion) { | 106 , fPMConversion(pmConversion) { |
107 this->initClassID<GrConfigConversionEffect>(); | 107 this->initClassID<GrConfigConversionEffect>(); |
108 // We expect to get here with non-BGRA/RGBA only if we're doing not doing a
premul/unpremul | 108 // We expect to get here with non-BGRA/RGBA only if we're doing not doing a
premul/unpremul |
109 // conversion. | 109 // conversion. |
110 SkASSERT((kRGBA_8888_GrPixelConfig == texture->config() || | 110 SkASSERT((kRGBA_8888_GrPixelConfig == texture->config() || |
111 kBGRA_8888_GrPixelConfig == texture->config()) || | 111 kBGRA_8888_GrPixelConfig == texture->config()) || |
112 kNone_PMConversion == pmConversion); | 112 kNone_PMConversion == pmConversion); |
113 // Why did we pollute our texture cache instead of using a GrSingleTextureEf
fect? | 113 // Why did we pollute our texture cache instead of using a GrSingleTextureEf
fect? |
114 SkASSERT(swapRedAndBlue || kNone_PMConversion != pmConversion); | 114 SkASSERT(swapRedAndBlue || kNone_PMConversion != pmConversion); |
(...skipping 15 matching lines...) Expand all Loading... |
130 | 130 |
131 const GrFragmentProcessor* GrConfigConversionEffect::TestCreate(GrProcessorTestD
ata* d) { | 131 const GrFragmentProcessor* GrConfigConversionEffect::TestCreate(GrProcessorTestD
ata* d) { |
132 PMConversion pmConv = static_cast<PMConversion>(d->fRandom->nextULessThan(kP
MConversionCnt)); | 132 PMConversion pmConv = static_cast<PMConversion>(d->fRandom->nextULessThan(kP
MConversionCnt)); |
133 bool swapRB; | 133 bool swapRB; |
134 if (kNone_PMConversion == pmConv) { | 134 if (kNone_PMConversion == pmConv) { |
135 swapRB = true; | 135 swapRB = true; |
136 } else { | 136 } else { |
137 swapRB = d->fRandom->nextBool(); | 137 swapRB = d->fRandom->nextBool(); |
138 } | 138 } |
139 return new GrConfigConversionEffect(d->fTextures[GrProcessorUnitTest::kSkiaP
MTextureIdx], | 139 return new GrConfigConversionEffect(d->fTextures[GrProcessorUnitTest::kSkiaP
MTextureIdx], |
140 swapRB, pmConv, GrTest::TestMatrix(d->fR
andom)); | 140 swapRB, pmConv, GrTest::TestMatrix(d->fR
andom), NULL); |
141 } | 141 } |
142 | 142 |
143 /////////////////////////////////////////////////////////////////////////////// | 143 /////////////////////////////////////////////////////////////////////////////// |
144 | 144 |
145 void GrConfigConversionEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, | 145 void GrConfigConversionEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, |
146 GrProcessorKeyBuilder* b) con
st { | 146 GrProcessorKeyBuilder* b) con
st { |
147 GrGLConfigConversionEffect::GenKey(*this, caps, b); | 147 GrGLConfigConversionEffect::GenKey(*this, caps, b); |
148 } | 148 } |
149 | 149 |
150 GrGLFragmentProcessor* GrConfigConversionEffect::onCreateGLInstance() const { | 150 GrGLFragmentProcessor* GrConfigConversionEffect::onCreateGLInstance() const { |
151 return new GrGLConfigConversionEffect(*this); | 151 return new GrGLConfigConversionEffect(*this); |
152 } | 152 } |
153 | 153 |
154 | 154 |
| 155 #include "GrDrawTarget.h" |
155 | 156 |
156 void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
, | 157 void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
, |
157 PMConversion* pmTo
UPMRule, | 158 PMConversion* pmTo
UPMRule, |
158 PMConversion* upmT
oPMRule) { | 159 PMConversion* upmT
oPMRule) { |
159 *pmToUPMRule = kNone_PMConversion; | 160 *pmToUPMRule = kNone_PMConversion; |
160 *upmToPMRule = kNone_PMConversion; | 161 *upmToPMRule = kNone_PMConversion; |
161 SkAutoTMalloc<uint32_t> data(256 * 256 * 3); | 162 SkAutoTMalloc<uint32_t> data(256 * 256 * 3); |
162 uint32_t* srcData = data.get(); | 163 uint32_t* srcData = data.get(); |
163 uint32_t* firstRead = data.get() + 256 * 256; | 164 uint32_t* firstRead = data.get() + 256 * 256; |
164 uint32_t* secondRead = data.get() + 2 * 256 * 256; | 165 uint32_t* secondRead = data.get() + 2 * 256 * 256; |
(...skipping 17 matching lines...) Expand all Loading... |
182 desc.fConfig = kRGBA_8888_GrPixelConfig; | 183 desc.fConfig = kRGBA_8888_GrPixelConfig; |
183 | 184 |
184 SkAutoTUnref<GrTexture> readTex(context->textureProvider()->createTexture(de
sc, true, nullptr, 0)); | 185 SkAutoTUnref<GrTexture> readTex(context->textureProvider()->createTexture(de
sc, true, nullptr, 0)); |
185 if (!readTex.get()) { | 186 if (!readTex.get()) { |
186 return; | 187 return; |
187 } | 188 } |
188 SkAutoTUnref<GrTexture> tempTex(context->textureProvider()->createTexture(de
sc, true, nullptr, 0)); | 189 SkAutoTUnref<GrTexture> tempTex(context->textureProvider()->createTexture(de
sc, true, nullptr, 0)); |
189 if (!tempTex.get()) { | 190 if (!tempTex.get()) { |
190 return; | 191 return; |
191 } | 192 } |
| 193 |
192 desc.fFlags = kNone_GrSurfaceFlags; | 194 desc.fFlags = kNone_GrSurfaceFlags; |
193 SkAutoTUnref<GrTexture> dataTex(context->textureProvider()->createTexture(de
sc, true, data, 0)); | 195 SkAutoTUnref<GrTexture> dataTex(context->textureProvider()->createTexture(de
sc, true, data, 0)); |
194 if (!dataTex.get()) { | 196 if (!dataTex.get()) { |
195 return; | 197 return; |
196 } | 198 } |
197 | 199 |
| 200 dataTex->setException(true); |
| 201 |
198 static const PMConversion kConversionRules[][2] = { | 202 static const PMConversion kConversionRules[][2] = { |
199 {kDivByAlpha_RoundDown_PMConversion, kMulByAlpha_RoundUp_PMConversion}, | 203 {kDivByAlpha_RoundDown_PMConversion, kMulByAlpha_RoundUp_PMConversion}, |
200 {kDivByAlpha_RoundUp_PMConversion, kMulByAlpha_RoundDown_PMConversion}, | 204 {kDivByAlpha_RoundUp_PMConversion, kMulByAlpha_RoundDown_PMConversion}, |
201 }; | 205 }; |
202 | 206 |
203 bool failed = true; | 207 bool failed = true; |
204 | 208 |
| 209 SkAutoTUnref<GrDrawContext> readDrawContext; |
| 210 SkAutoTUnref<GrDrawContext> tempDrawContext; |
| 211 |
205 for (size_t i = 0; i < SK_ARRAY_COUNT(kConversionRules) && failed; ++i) { | 212 for (size_t i = 0; i < SK_ARRAY_COUNT(kConversionRules) && failed; ++i) { |
206 *pmToUPMRule = kConversionRules[i][0]; | 213 *pmToUPMRule = kConversionRules[i][0]; |
207 *upmToPMRule = kConversionRules[i][1]; | 214 *upmToPMRule = kConversionRules[i][1]; |
208 | 215 |
209 static const SkRect kDstRect = SkRect::MakeWH(SkIntToScalar(256), SkIntT
oScalar(256)); | 216 static const SkRect kDstRect = SkRect::MakeWH(SkIntToScalar(256), SkIntT
oScalar(256)); |
210 static const SkRect kSrcRect = SkRect::MakeWH(SK_Scalar1, SK_Scalar1); | 217 static const SkRect kSrcRect = SkRect::MakeWH(SK_Scalar1, SK_Scalar1); |
211 // We do a PM->UPM draw from dataTex to readTex and read the data. Then
we do a UPM->PM draw | 218 // 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. | 219 // 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. | 220 // We then verify that two reads produced the same values. |
214 | 221 |
215 GrPaint paint1; | 222 GrPaint paint1; |
216 GrPaint paint2; | 223 GrPaint paint2; |
217 GrPaint paint3; | 224 GrPaint paint3; |
218 SkAutoTUnref<GrFragmentProcessor> pmToUPM1(new GrConfigConversionEffect( | 225 SkAutoTUnref<GrFragmentProcessor> pmToUPM1(new GrConfigConversionEffect( |
219 dataTex, false, *pmToUPMRule, SkMatrix::I())); | 226 dataTex, false, *pmToUPMRule, SkMatrix::I(), readTex->asRenderTa
rget())); |
220 SkAutoTUnref<GrFragmentProcessor> upmToPM(new GrConfigConversionEffect( | 227 SkAutoTUnref<GrFragmentProcessor> upmToPM(new GrConfigConversionEffect( |
221 readTex, false, *upmToPMRule, SkMatrix::I())); | 228 readTex, false, *upmToPMRule, SkMatrix::I(), tempTex->asRenderTa
rget())); |
222 SkAutoTUnref<GrFragmentProcessor> pmToUPM2(new GrConfigConversionEffect( | 229 SkAutoTUnref<GrFragmentProcessor> pmToUPM2(new GrConfigConversionEffect( |
223 tempTex, false, *pmToUPMRule, SkMatrix::I())); | 230 tempTex, false, *pmToUPMRule, SkMatrix::I(), readTex->asRenderTa
rget())); |
224 | 231 |
225 paint1.addColorFragmentProcessor(pmToUPM1); | 232 paint1.addColorFragmentProcessor(pmToUPM1); |
226 | 233 |
227 | 234 readDrawContext.reset(context->drawContext(readTex->asRenderTarget())); |
228 SkAutoTUnref<GrDrawContext> readDrawContext( | |
229 context->drawContext(readTex->asRenderTarget
())); | |
230 if (!readDrawContext) { | 235 if (!readDrawContext) { |
231 failed = true; | 236 return; |
232 break; | |
233 } | 237 } |
234 | 238 |
235 readDrawContext->fillRectToRect(GrClip::WideOpen(), | 239 readDrawContext->fillRectToRect(GrClip::WideOpen(), |
236 paint1, | 240 paint1, |
237 SkMatrix::I(), | 241 SkMatrix::I(), |
238 kDstRect, | 242 kDstRect, |
239 kSrcRect); | 243 kSrcRect); |
240 | 244 |
241 readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, firstRead)
; | 245 readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, firstRead)
; |
242 | 246 |
243 paint2.addColorFragmentProcessor(upmToPM); | 247 paint2.addColorFragmentProcessor(upmToPM); |
244 | 248 |
245 SkAutoTUnref<GrDrawContext> tempDrawContext( | 249 tempDrawContext.reset(context->drawContext(tempTex->asRenderTarget())); |
246 context->drawContext(tempTex->asRenderTarget
())); | |
247 if (!tempDrawContext) { | 250 if (!tempDrawContext) { |
248 failed = true; | 251 return; |
249 break; | |
250 } | 252 } |
| 253 |
251 tempDrawContext->fillRectToRect(GrClip::WideOpen(), | 254 tempDrawContext->fillRectToRect(GrClip::WideOpen(), |
252 paint2, | 255 paint2, |
253 SkMatrix::I(), | 256 SkMatrix::I(), |
254 kDstRect, | 257 kDstRect, |
255 kSrcRect); | 258 kSrcRect); |
256 | 259 |
257 paint3.addColorFragmentProcessor(pmToUPM2); | 260 paint3.addColorFragmentProcessor(pmToUPM2); |
258 | 261 |
| 262 SkASSERT(readDrawContext); |
| 263 |
259 readDrawContext.reset(context->drawContext(readTex->asRenderTarget())); | 264 readDrawContext.reset(context->drawContext(readTex->asRenderTarget())); |
260 if (!readDrawContext) { | 265 if (!readDrawContext) { |
261 failed = true; | 266 return; |
262 break; | |
263 } | 267 } |
264 | 268 |
265 readDrawContext->fillRectToRect(GrClip::WideOpen(), | 269 readDrawContext->fillRectToRect(GrClip::WideOpen(), |
266 paint3, | 270 paint3, |
267 SkMatrix::I(), | 271 SkMatrix::I(), |
268 kDstRect, | 272 kDstRect, |
269 kSrcRect); | 273 kSrcRect); |
270 | 274 |
271 readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, secondRead
); | 275 readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, secondRead
); |
272 | 276 |
273 failed = false; | 277 failed = false; |
274 for (int y = 0; y < 256 && !failed; ++y) { | 278 for (int y = 0; y < 256 && !failed; ++y) { |
275 for (int x = 0; x <= y; ++x) { | 279 for (int x = 0; x <= y; ++x) { |
276 if (firstRead[256 * y + x] != secondRead[256 * y + x]) { | 280 if (firstRead[256 * y + x] != secondRead[256 * y + x]) { |
277 failed = true; | 281 failed = true; |
278 break; | 282 break; |
279 } | 283 } |
280 } | 284 } |
281 } | 285 } |
282 } | 286 } |
283 if (failed) { | 287 if (failed) { |
284 *pmToUPMRule = kNone_PMConversion; | 288 *pmToUPMRule = kNone_PMConversion; |
285 *upmToPMRule = kNone_PMConversion; | 289 *upmToPMRule = kNone_PMConversion; |
286 } | 290 } |
287 } | 291 } |
288 | 292 |
289 const GrFragmentProcessor* GrConfigConversionEffect::Create(GrTexture* texture, | 293 const GrFragmentProcessor* GrConfigConversionEffect::Create(GrTexture* texture, |
290 bool swapRedAndBlue, | 294 bool swapRedAndBlue, |
291 PMConversion pmConve
rsion, | 295 PMConversion pmConve
rsion, |
292 const SkMatrix& matr
ix) { | 296 const SkMatrix& matr
ix, GrRenderTarget* dst) { |
293 if (!swapRedAndBlue && kNone_PMConversion == pmConversion) { | 297 if (!swapRedAndBlue && kNone_PMConversion == pmConversion) { |
294 // If we returned a GrConfigConversionEffect that was equivalent to a Gr
SimpleTextureEffect | 298 // If we returned a GrConfigConversionEffect that was equivalent to a Gr
SimpleTextureEffect |
295 // then we may pollute our texture cache with redundant shaders. So in t
he case that no | 299 // then we may pollute our texture cache with redundant shaders. So in t
he case that no |
296 // conversions were requested we instead return a GrSimpleTextureEffect. | 300 // conversions were requested we instead return a GrSimpleTextureEffect. |
297 return GrSimpleTextureEffect::Create(texture, matrix); | 301 return GrSimpleTextureEffect::Create(texture, matrix, kLocal_GrCoordSet,
dst); |
298 } else { | 302 } else { |
299 if (kRGBA_8888_GrPixelConfig != texture->config() && | 303 if (kRGBA_8888_GrPixelConfig != texture->config() && |
300 kBGRA_8888_GrPixelConfig != texture->config() && | 304 kBGRA_8888_GrPixelConfig != texture->config() && |
301 kNone_PMConversion != pmConversion) { | 305 kNone_PMConversion != pmConversion) { |
302 // The PM conversions assume colors are 0..255 | 306 // The PM conversions assume colors are 0..255 |
303 return nullptr; | 307 return nullptr; |
304 } | 308 } |
305 return new GrConfigConversionEffect(texture, swapRedAndBlue, pmConversio
n, matrix); | 309 return new GrConfigConversionEffect(texture, swapRedAndBlue, pmConversio
n, matrix, dst); |
306 } | 310 } |
307 } | 311 } |
OLD | NEW |