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" 10b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrTBackendProcessorFactory.h" 1168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "GrSimpleTextureEffect.h" 12b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 1330ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/builders/GrGLProgramBuilder.h" 14b1456d70100d309c852906fafab006fae63de53ebsalomon@google.com#include "SkMatrix.h" 15a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 16b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLConfigConversionEffect : public GrGLFragmentProcessor { 17a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.compublic: 18b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLConfigConversionEffect(const GrBackendProcessorFactory& factory, 19b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor& processor) 2077af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com : INHERITED (factory) { 21b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrConfigConversionEffect& configConversionEffect = 22b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt processor.cast<GrConfigConversionEffect>(); 2349586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt fSwapRedAndBlue = configConversionEffect.swapsRedAndBlue(); 2449586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt fPMConversion = configConversionEffect.pmConversion(); 25a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 26a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 2730ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLProgramBuilder* builder, 28b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor&, 29b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 3022a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const char* outputColor, 3122a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const char* inputColor, 3277af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com const TransformedCoordsArray& coords, 3322a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const TextureSamplerArray& samplers) SK_OVERRIDE { 34cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang // Using highp for GLES here in order to avoid some precision issues on specific GPUs. 35cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang GrGLShaderVar tmpVar("tmpColor", kVec4f_GrSLType, 0, GrGLShaderVar::kHigh_Precision); 36cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang SkString tmpDecl; 37cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang tmpVar.appendDecl(builder->ctxInfo(), &tmpDecl); 38cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang 3930ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 4030ba436f04e61d4505fb854d5fc56079636e0788joshualitt 4130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("%s;", tmpDecl.c_str()); 4230ba436f04e61d4505fb854d5fc56079636e0788joshualitt 4330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("%s = ", tmpVar.c_str()); 4423e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType()); 4530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";"); 46cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang 47a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) { 48f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fSwapRedAndBlue); 4930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("%s = %s.bgra;", outputColor, tmpVar.c_str()); 50a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 51a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com const char* swiz = fSwapRedAndBlue ? "bgr" : "rgb"; 52a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com switch (fPMConversion) { 53a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion: 5430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf( 55cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang "%s = vec4(ceil(%s.%s * %s.a * 255.0) / 255.0, %s.a);", 56cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str()); 57a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com break; 58a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversion: 59b4e200ec6bafd2a2ebbc5c73a954136acd4b587dcommit-bot@chromium.org // Add a compensation(0.001) here to avoid the side effect of the floor operation. 60b4e200ec6bafd2a2ebbc5c73a954136acd4b587dcommit-bot@chromium.org // In Intel GPUs, the integer value converted from floor(%s.r * 255.0) / 255.0 61b4e200ec6bafd2a2ebbc5c73a954136acd4b587dcommit-bot@chromium.org // is less than the integer value converted from %s.r by 1 when the %s.r is 62b4e200ec6bafd2a2ebbc5c73a954136acd4b587dcommit-bot@chromium.org // converted from the integer value 2^n, such as 1, 2, 4, 8, etc. 6330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf( 64cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang "%s = vec4(floor(%s.%s * %s.a * 255.0 + 0.001) / 255.0, %s.a);", 65cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str()); 66a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com break; 67a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion: 6830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf( 69cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.%s / %s.a * 255.0) / 255.0, %s.a);", 70cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str()); 71a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com break; 72a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversion: 7330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf( 74cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.%s / %s.a * 255.0) / 255.0, %s.a);", 75cecc91c4446c9c2f9b95736e206bfd1d507a75a9changjun.yang tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str()); 76a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com break; 772af1b188aa186936a78696e00170167204d9a666robertphillips@google.com default: 7888cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unknown conversion op."); 792af1b188aa186936a78696e00170167204d9a666robertphillips@google.com break; 80a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 8130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("%s = %s;", outputColor, tmpVar.c_str()); 82a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 83f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com SkString modulate; 84f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor); 8530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(modulate.c_str()); 86a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 87a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 88b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static inline void GenKey(const GrProcessor& processor, const GrGLCaps&, 89b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 90b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrConfigConversionEffect& conv = processor.cast<GrConfigConversionEffect>(); 9163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon uint32_t key = (conv.swapsRedAndBlue() ? 0 : 1) | (conv.pmConversion() << 1); 9263e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon b->add32(key); 93a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 94a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 95a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comprivate: 96a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com bool fSwapRedAndBlue; 97a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion fPMConversion; 98a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 99b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLFragmentProcessor INHERITED; 100a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 101a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com}; 102a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 103a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 104a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 105a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comGrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture, 106a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com bool swapRedAndBlue, 107b1456d70100d309c852906fafab006fae63de53ebsalomon@google.com PMConversion pmConversion, 108b1456d70100d309c852906fafab006fae63de53ebsalomon@google.com const SkMatrix& matrix) 109b1456d70100d309c852906fafab006fae63de53ebsalomon@google.com : GrSingleTextureEffect(texture, matrix) 110a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com , fSwapRedAndBlue(swapRedAndBlue) 111a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com , fPMConversion(pmConversion) { 112f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(kRGBA_8888_GrPixelConfig == texture->config() || 113a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com kBGRA_8888_GrPixelConfig == texture->config()); 114a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // Why did we pollute our texture cache instead of using a GrSingleTextureEffect? 115f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(swapRedAndBlue || kNone_PMConversion != pmConversion); 116a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 117a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 118b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendFragmentProcessorFactory& GrConfigConversionEffect::getFactory() const { 119b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return GrTBackendFragmentProcessorFactory<GrConfigConversionEffect>::getInstance(); 120a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 121a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 122b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool GrConfigConversionEffect::onIsEqual(const GrProcessor& s) const { 12349586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrConfigConversionEffect& other = s.cast<GrConfigConversionEffect>(); 1248a252f79629b189a03de22cd8ff0312c5bccedd1bsalomon@google.com return this->texture(0) == s.texture(0) && 12568b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com other.fSwapRedAndBlue == fSwapRedAndBlue && 12668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com other.fPMConversion == fPMConversion; 12768b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com} 12868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 12968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.comvoid GrConfigConversionEffect::getConstantColorComponents(GrColor* color, 13068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com uint32_t* validFlags) const { 13168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com this->updateConstantColorComponentsForModulation(color, validFlags); 132a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 133a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 134a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 135a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 136b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConfigConversionEffect); 137a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 138b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrConfigConversionEffect::TestCreate(SkRandom* random, 139b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 140b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 141b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 142a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com PMConversion pmConv = static_cast<PMConversion>(random->nextULessThan(kPMConversionCnt)); 143a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com bool swapRB; 144a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (kNone_PMConversion == pmConv) { 145a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com swapRB = true; 146a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 147a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com swapRB = random->nextBool(); 148a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 14955fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(GrConfigConversionEffect, 150b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt (textures[GrProcessorUnitTest::kSkiaPMTextureIdx], 1516340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com swapRB, 1526340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com pmConv, 153b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::TestMatrix(random))); 154a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 155a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 156a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 157a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comvoid GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context, 158a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com PMConversion* pmToUPMRule, 159a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com PMConversion* upmToPMRule) { 160a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *pmToUPMRule = kNone_PMConversion; 161a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *upmToPMRule = kNone_PMConversion; 162a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkAutoTMalloc<uint32_t> data(256 * 256 * 3); 163a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com uint32_t* srcData = data.get(); 164a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com uint32_t* firstRead = data.get() + 256 * 256; 165a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com uint32_t* secondRead = data.get() + 2 * 256 * 256; 166a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 167a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // Fill with every possible premultiplied A, color channel value. There will be 256-y duplicate 168a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // values in row y. We set r,g, and b to the same value since they are handled identically. 169a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com for (int y = 0; y < 256; ++y) { 170a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com for (int x = 0; x < 256; ++x) { 171a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com uint8_t* color = reinterpret_cast<uint8_t*>(&srcData[256*y + x]); 172a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com color[3] = y; 173972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org color[2] = SkTMin(x, y); 174972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org color[1] = SkTMin(x, y); 175972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org color[0] = SkTMin(x, y); 176a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 177a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 178a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 179a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrTextureDesc desc; 180a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit | 181a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com kNoStencil_GrTextureFlagBit; 182a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fWidth = 256; 183a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fHeight = 256; 184a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fConfig = kRGBA_8888_GrPixelConfig; 185a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 186a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkAutoTUnref<GrTexture> readTex(context->createUncachedTexture(desc, NULL, 0)); 187a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!readTex.get()) { 188a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return; 189a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 190a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkAutoTUnref<GrTexture> tempTex(context->createUncachedTexture(desc, NULL, 0)); 191a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!tempTex.get()) { 192a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return; 193a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 194a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fFlags = kNone_GrTextureFlags; 195a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkAutoTUnref<GrTexture> dataTex(context->createUncachedTexture(desc, data, 0)); 196a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!dataTex.get()) { 197a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return; 198a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 199a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 200a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com static const PMConversion kConversionRules[][2] = { 201a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com {kDivByAlpha_RoundDown_PMConversion, kMulByAlpha_RoundUp_PMConversion}, 202a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com {kDivByAlpha_RoundUp_PMConversion, kMulByAlpha_RoundDown_PMConversion}, 203a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com }; 204a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 205a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrContext::AutoWideOpenIdentityDraw awoid(context, NULL); 206a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 207a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com bool failed = true; 208a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 209972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org for (size_t i = 0; i < SK_ARRAY_COUNT(kConversionRules) && failed; ++i) { 210a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *pmToUPMRule = kConversionRules[i][0]; 211a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *upmToPMRule = kConversionRules[i][1]; 212a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 213fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org static const SkRect kDstRect = SkRect::MakeWH(SkIntToScalar(256), SkIntToScalar(256)); 214fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org static const SkRect kSrcRect = SkRect::MakeWH(SK_Scalar1, SK_Scalar1); 215a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw 216a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data. 217a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // We then verify that two reads produced the same values. 218a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 219b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> pmToUPM1( 220b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkNEW_ARGS(GrConfigConversionEffect, 221b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt (dataTex, false, *pmToUPMRule, SkMatrix::I()))); 222b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> upmToPM( 223b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkNEW_ARGS(GrConfigConversionEffect, 224b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt (readTex, false, *upmToPMRule, SkMatrix::I()))); 225b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> pmToUPM2( 226b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkNEW_ARGS(GrConfigConversionEffect, 227b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt (tempTex, false, *pmToUPMRule, SkMatrix::I()))); 228a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 229a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com context->setRenderTarget(readTex->asRenderTarget()); 23042dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org GrPaint paint1; 231b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt paint1.addColorProcessor(pmToUPM1); 23242dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org context->drawRectToRect(paint1, kDstRect, kSrcRect); 233a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 234a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, firstRead); 235a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 236a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com context->setRenderTarget(tempTex->asRenderTarget()); 23742dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org GrPaint paint2; 238b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt paint2.addColorProcessor(upmToPM); 23942dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org context->drawRectToRect(paint2, kDstRect, kSrcRect); 240a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com context->setRenderTarget(readTex->asRenderTarget()); 24142dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org 24242dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org GrPaint paint3; 243b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt paint3.addColorProcessor(pmToUPM2); 24442dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org context->drawRectToRect(paint3, kDstRect, kSrcRect); 245a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 246a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, secondRead); 247a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 248a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com failed = false; 249a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com for (int y = 0; y < 256 && !failed; ++y) { 250a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com for (int x = 0; x <= y; ++x) { 251a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (firstRead[256 * y + x] != secondRead[256 * y + x]) { 252a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com failed = true; 253a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com break; 254a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 255a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 256a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 257a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 258a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (failed) { 259a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *pmToUPMRule = kNone_PMConversion; 260a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *upmToPMRule = kNone_PMConversion; 261a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 262a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 263a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 264b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrFragmentProcessor* GrConfigConversionEffect::Create(GrTexture* texture, 26583d081ae1d731b5039e99823620f5e287542ee39bsalomon bool swapRedAndBlue, 26683d081ae1d731b5039e99823620f5e287542ee39bsalomon PMConversion pmConversion, 26783d081ae1d731b5039e99823620f5e287542ee39bsalomon const SkMatrix& matrix) { 268a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!swapRedAndBlue && kNone_PMConversion == pmConversion) { 269adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com // If we returned a GrConfigConversionEffect that was equivalent to a GrSimpleTextureEffect 270a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // then we may pollute our texture cache with redundant shaders. So in the case that no 271adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com // conversions were requested we instead return a GrSimpleTextureEffect. 272adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return GrSimpleTextureEffect::Create(texture, matrix); 273a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 274a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (kRGBA_8888_GrPixelConfig != texture->config() && 275a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com kBGRA_8888_GrPixelConfig != texture->config() && 276a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com kNone_PMConversion != pmConversion) { 277a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // The PM conversions assume colors are 0..255 278adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return NULL; 279a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 28055fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(GrConfigConversionEffect, (texture, 28155fad7af61c21d502acb9891d631e8aa29e3628cbsalomon swapRedAndBlue, 28255fad7af61c21d502acb9891d631e8aa29e3628cbsalomon pmConversion, 28355fad7af61c21d502acb9891d631e8aa29e3628cbsalomon matrix)); 284a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 285a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 286