1a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com/* 2a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com * Copyright 2012 Google Inc. 3a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com * 4a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 5a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com * found in the LICENSE file. 6a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com */ 7a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 8a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com#include "GrConfigConversionEffect.h" 9b1456d70100d309c852906fafab006fae63de53ebsalomon@google.com#include "GrContext.h" 102eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com#include "GrTBackendEffectFactory.h" 1168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "GrSimpleTextureEffect.h" 12d698f77c13d97c61109b861eac4d25b14a5de935bsalomon@google.com#include "gl/GrGLEffect.h" 13b1456d70100d309c852906fafab006fae63de53ebsalomon@google.com#include "SkMatrix.h" 14a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1522a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.comclass GrGLConfigConversionEffect : public GrGLEffect { 16a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.compublic: 17396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com GrGLConfigConversionEffect(const GrBackendEffectFactory& factory, 18c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com const GrDrawEffect& drawEffect) 1977af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com : INHERITED (factory) { 20c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com const GrConfigConversionEffect& effect = drawEffect.castEffect<GrConfigConversionEffect>(); 21021fc736f89fddac4f26b3f32f50263ff8fe3279bsalomon@google.com fSwapRedAndBlue = effect.swapsRedAndBlue(); 22021fc736f89fddac4f26b3f32f50263ff8fe3279bsalomon@google.com fPMConversion = effect.pmConversion(); 23a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 24a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 2522a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com virtual void emitCode(GrGLShaderBuilder* builder, 26c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com const GrDrawEffect&, 27b1456d70100d309c852906fafab006fae63de53ebsalomon@google.com EffectKey key, 2822a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const char* outputColor, 2922a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const char* inputColor, 3077af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com const TransformedCoordsArray& coords, 3122a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const TextureSamplerArray& samplers) SK_OVERRIDE { 32f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com builder->fsCodeAppendf("\t\t%s = ", outputColor); 3377af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type()); 34f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com builder->fsCodeAppend(";\n"); 35a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) { 36f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fSwapRedAndBlue); 37f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com builder->fsCodeAppendf("\t%s = %s.bgra;\n", outputColor, outputColor); 38a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 39a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com const char* swiz = fSwapRedAndBlue ? "bgr" : "rgb"; 40a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com switch (fPMConversion) { 41a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion: 42f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com builder->fsCodeAppendf( 43868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com "\t\t%s = vec4(ceil(%s.%s * %s.a * 255.0) / 255.0, %s.a);\n", 44868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com outputColor, outputColor, swiz, outputColor, outputColor); 45a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com break; 46a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversion: 47b4e200ec6bafd2a2ebbc5c73a954136acd4b587dcommit-bot@chromium.org // Add a compensation(0.001) here to avoid the side effect of the floor operation. 48b4e200ec6bafd2a2ebbc5c73a954136acd4b587dcommit-bot@chromium.org // In Intel GPUs, the integer value converted from floor(%s.r * 255.0) / 255.0 49b4e200ec6bafd2a2ebbc5c73a954136acd4b587dcommit-bot@chromium.org // is less than the integer value converted from %s.r by 1 when the %s.r is 50b4e200ec6bafd2a2ebbc5c73a954136acd4b587dcommit-bot@chromium.org // converted from the integer value 2^n, such as 1, 2, 4, 8, etc. 51f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com builder->fsCodeAppendf( 52b4e200ec6bafd2a2ebbc5c73a954136acd4b587dcommit-bot@chromium.org "\t\t%s = vec4(floor(%s.%s * %s.a * 255.0 + 0.001) / 255.0, %s.a);\n", 53868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com outputColor, outputColor, swiz, outputColor, outputColor); 54a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com break; 55a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion: 56f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com builder->fsCodeAppendf("\t\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.%s / %s.a * 255.0) / 255.0, %s.a);\n", 57868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com outputColor, outputColor, outputColor, swiz, outputColor, outputColor); 58a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com break; 59a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversion: 60f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com builder->fsCodeAppendf("\t\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.%s / %s.a * 255.0) / 255.0, %s.a);\n", 61868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com outputColor, outputColor, outputColor, swiz, outputColor, outputColor); 62a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com break; 632af1b188aa186936a78696e00170167204d9a666robertphillips@google.com default: 6488cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unknown conversion op."); 652af1b188aa186936a78696e00170167204d9a666robertphillips@google.com break; 66a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 67a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 68f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com SkString modulate; 69f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor); 70f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com builder->fsCodeAppend(modulate.c_str()); 71a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 72a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 73c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { 74c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com const GrConfigConversionEffect& conv = drawEffect.castEffect<GrConfigConversionEffect>(); 7577af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com return static_cast<EffectKey>(conv.swapsRedAndBlue()) | (conv.pmConversion() << 1); 76a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 77a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 78a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comprivate: 79a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com bool fSwapRedAndBlue; 80a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion fPMConversion; 81a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 8222a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com typedef GrGLEffect INHERITED; 83a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 84a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com}; 85a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 86a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 87a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 88a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comGrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture, 89a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com bool swapRedAndBlue, 90b1456d70100d309c852906fafab006fae63de53ebsalomon@google.com PMConversion pmConversion, 91b1456d70100d309c852906fafab006fae63de53ebsalomon@google.com const SkMatrix& matrix) 92b1456d70100d309c852906fafab006fae63de53ebsalomon@google.com : GrSingleTextureEffect(texture, matrix) 93a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com , fSwapRedAndBlue(swapRedAndBlue) 94a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com , fPMConversion(pmConversion) { 95f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(kRGBA_8888_GrPixelConfig == texture->config() || 96a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com kBGRA_8888_GrPixelConfig == texture->config()); 97a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // Why did we pollute our texture cache instead of using a GrSingleTextureEffect? 98f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(swapRedAndBlue || kNone_PMConversion != pmConversion); 99a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 100a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 101396e61fe440590744345e0c56970b26ab464591dbsalomon@google.comconst GrBackendEffectFactory& GrConfigConversionEffect::getFactory() const { 102396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com return GrTBackendEffectFactory<GrConfigConversionEffect>::getInstance(); 103a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 104a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1058a252f79629b189a03de22cd8ff0312c5bccedd1bsalomon@google.combool GrConfigConversionEffect::onIsEqual(const GrEffect& s) const { 1066340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com const GrConfigConversionEffect& other = CastEffect<GrConfigConversionEffect>(s); 1078a252f79629b189a03de22cd8ff0312c5bccedd1bsalomon@google.com return this->texture(0) == s.texture(0) && 10868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com other.fSwapRedAndBlue == fSwapRedAndBlue && 10968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com other.fPMConversion == fPMConversion; 11068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com} 11168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 11268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.comvoid GrConfigConversionEffect::getConstantColorComponents(GrColor* color, 11368b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com uint32_t* validFlags) const { 11468b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com this->updateConstantColorComponentsForModulation(color, validFlags); 115a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 116a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 117a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 118a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 119f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.comGR_DEFINE_EFFECT_TEST(GrConfigConversionEffect); 120a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 121e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgGrEffectRef* GrConfigConversionEffect::TestCreate(SkRandom* random, 122e0e385c1d4171e065348ba17c546b3463a0bd651sugoi@google.com GrContext*, 123c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com const GrDrawTargetCaps&, 1240ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com GrTexture* textures[]) { 125a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com PMConversion pmConv = static_cast<PMConversion>(random->nextULessThan(kPMConversionCnt)); 126a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com bool swapRB; 127a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (kNone_PMConversion == pmConv) { 128a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com swapRB = true; 129a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 130a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com swapRB = random->nextBool(); 131a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1326340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com AutoEffectUnref effect(SkNEW_ARGS(GrConfigConversionEffect, 1336340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com (textures[GrEffectUnitTest::kSkiaPMTextureIdx], 1346340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com swapRB, 1356340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com pmConv, 1366340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com GrEffectUnitTest::TestMatrix(random)))); 137a1ebbe447d5eab098111eb83580e55f2f5f6facabsalomon@google.com return CreateEffectRef(effect); 138a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 139a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 140a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 141a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comvoid GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context, 142a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com PMConversion* pmToUPMRule, 143a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com PMConversion* upmToPMRule) { 144a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *pmToUPMRule = kNone_PMConversion; 145a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *upmToPMRule = kNone_PMConversion; 146a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkAutoTMalloc<uint32_t> data(256 * 256 * 3); 147a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com uint32_t* srcData = data.get(); 148a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com uint32_t* firstRead = data.get() + 256 * 256; 149a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com uint32_t* secondRead = data.get() + 2 * 256 * 256; 150a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 151a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // Fill with every possible premultiplied A, color channel value. There will be 256-y duplicate 152a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // values in row y. We set r,g, and b to the same value since they are handled identically. 153a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com for (int y = 0; y < 256; ++y) { 154a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com for (int x = 0; x < 256; ++x) { 155a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com uint8_t* color = reinterpret_cast<uint8_t*>(&srcData[256*y + x]); 156a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com color[3] = y; 157972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org color[2] = SkTMin(x, y); 158972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org color[1] = SkTMin(x, y); 159972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org color[0] = SkTMin(x, y); 160a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 161a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 162a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 163a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrTextureDesc desc; 164a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit | 165a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com kNoStencil_GrTextureFlagBit; 166a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fWidth = 256; 167a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fHeight = 256; 168a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fConfig = kRGBA_8888_GrPixelConfig; 169a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 170a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkAutoTUnref<GrTexture> readTex(context->createUncachedTexture(desc, NULL, 0)); 171a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!readTex.get()) { 172a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return; 173a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 174a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkAutoTUnref<GrTexture> tempTex(context->createUncachedTexture(desc, NULL, 0)); 175a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!tempTex.get()) { 176a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return; 177a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 178a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fFlags = kNone_GrTextureFlags; 179a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkAutoTUnref<GrTexture> dataTex(context->createUncachedTexture(desc, data, 0)); 180a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!dataTex.get()) { 181a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return; 182a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 183a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 184a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com static const PMConversion kConversionRules[][2] = { 185a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com {kDivByAlpha_RoundDown_PMConversion, kMulByAlpha_RoundUp_PMConversion}, 186a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com {kDivByAlpha_RoundUp_PMConversion, kMulByAlpha_RoundDown_PMConversion}, 187a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com }; 188a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 189a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrContext::AutoWideOpenIdentityDraw awoid(context, NULL); 190a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 191a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com bool failed = true; 192a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 193972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org for (size_t i = 0; i < SK_ARRAY_COUNT(kConversionRules) && failed; ++i) { 194a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *pmToUPMRule = kConversionRules[i][0]; 195a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *upmToPMRule = kConversionRules[i][1]; 196a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 197fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org static const SkRect kDstRect = SkRect::MakeWH(SkIntToScalar(256), SkIntToScalar(256)); 198fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org static const SkRect kSrcRect = SkRect::MakeWH(SK_Scalar1, SK_Scalar1); 199a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw 200a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data. 201a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // We then verify that two reads produced the same values. 202a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 2036340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com AutoEffectUnref pmToUPM1(SkNEW_ARGS(GrConfigConversionEffect, (dataTex, 2046340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com false, 2056340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com *pmToUPMRule, 2066340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com SkMatrix::I()))); 2076340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com AutoEffectUnref upmToPM(SkNEW_ARGS(GrConfigConversionEffect, (readTex, 2086340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com false, 2096340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com *upmToPMRule, 2106340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com SkMatrix::I()))); 2116340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com AutoEffectUnref pmToUPM2(SkNEW_ARGS(GrConfigConversionEffect, (tempTex, 2126340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com false, 2136340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com *pmToUPMRule, 2146340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com SkMatrix::I()))); 2150ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 216a1ebbe447d5eab098111eb83580e55f2f5f6facabsalomon@google.com SkAutoTUnref<GrEffectRef> pmToUPMEffect1(CreateEffectRef(pmToUPM1)); 217a1ebbe447d5eab098111eb83580e55f2f5f6facabsalomon@google.com SkAutoTUnref<GrEffectRef> upmToPMEffect(CreateEffectRef(upmToPM)); 218a1ebbe447d5eab098111eb83580e55f2f5f6facabsalomon@google.com SkAutoTUnref<GrEffectRef> pmToUPMEffect2(CreateEffectRef(pmToUPM2)); 219a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 220a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com context->setRenderTarget(readTex->asRenderTarget()); 22142dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org GrPaint paint1; 22242dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org paint1.addColorEffect(pmToUPMEffect1); 22342dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org context->drawRectToRect(paint1, kDstRect, kSrcRect); 224a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 225a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, firstRead); 226a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 227a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com context->setRenderTarget(tempTex->asRenderTarget()); 22842dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org GrPaint paint2; 22942dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org paint2.addColorEffect(upmToPMEffect); 23042dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org context->drawRectToRect(paint2, kDstRect, kSrcRect); 231a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com context->setRenderTarget(readTex->asRenderTarget()); 23242dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org 23342dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org GrPaint paint3; 23442dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org paint3.addColorEffect(pmToUPMEffect2); 23542dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org context->drawRectToRect(paint3, kDstRect, kSrcRect); 236a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 237a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, secondRead); 238a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 239a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com failed = false; 240a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com for (int y = 0; y < 256 && !failed; ++y) { 241a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com for (int x = 0; x <= y; ++x) { 242a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (firstRead[256 * y + x] != secondRead[256 * y + x]) { 243a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com failed = true; 244a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com break; 245a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 246a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 247a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 248a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 249a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (failed) { 250a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *pmToUPMRule = kNone_PMConversion; 251a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *upmToPMRule = kNone_PMConversion; 252a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 253a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 254a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 255adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.comconst GrEffectRef* GrConfigConversionEffect::Create(GrTexture* texture, 256adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com bool swapRedAndBlue, 257adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com PMConversion pmConversion, 258adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com const SkMatrix& matrix) { 259a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!swapRedAndBlue && kNone_PMConversion == pmConversion) { 260adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com // If we returned a GrConfigConversionEffect that was equivalent to a GrSimpleTextureEffect 261a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // then we may pollute our texture cache with redundant shaders. So in the case that no 262adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com // conversions were requested we instead return a GrSimpleTextureEffect. 263adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return GrSimpleTextureEffect::Create(texture, matrix); 264a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 265a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (kRGBA_8888_GrPixelConfig != texture->config() && 266a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com kBGRA_8888_GrPixelConfig != texture->config() && 267a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com kNone_PMConversion != pmConversion) { 268a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // The PM conversions assume colors are 0..255 269adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return NULL; 270a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 2716340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com AutoEffectUnref effect(SkNEW_ARGS(GrConfigConversionEffect, (texture, 2726340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com swapRedAndBlue, 2736340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com pmConversion, 2746340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com matrix))); 275adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return CreateEffectRef(effect); 276a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 277a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 278