| 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 |