1c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon/* 2c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon * Copyright 2015 Google Inc. 3c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon * 4c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon * Use of this source code is governed by a BSD-style license that can be 5c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon * found in the LICENSE file. 6c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon */ 7c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 8c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon#include "effects/GrConstColorProcessor.h" 9c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon#include "gl/GrGLProcessor.h" 10c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon#include "gl/GrGLSL.h" 11c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon#include "gl/builders/GrGLProgramBuilder.h" 12c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 13c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomonclass GLConstColorProcessor : public GrGLFragmentProcessor { 14c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomonpublic: 15c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GLConstColorProcessor() : fPrevColor(GrColor_ILLEGAL) {} 16c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 17c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon void emitCode(GrGLFPBuilder* builder, 18c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon const GrFragmentProcessor& fp, 19c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon const char* outputColor, 20c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon const char* inputColor, 21c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon const TransformedCoordsArray& coords, 22c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon const TextureSamplerArray& samplers) override { 2329bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 24c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon const char* colorUni; 25c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon fColorUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 26c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon kVec4f_GrSLType, kMedium_GrSLPrecision, "constantColor", 27c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon &colorUni); 28c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon switch (fp.cast<GrConstColorProcessor>().inputMode()) { 29c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon case GrConstColorProcessor::kIgnore_InputMode: 30c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon fsBuilder->codeAppendf("%s = %s;", outputColor, colorUni); 31c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon break; 32c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon case GrConstColorProcessor::kModulateRGBA_InputMode: 33c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon fsBuilder->codeAppendf("%s = %s * %s;", outputColor, inputColor, colorUni); 34c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon break; 35c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon case GrConstColorProcessor::kModulateA_InputMode: 36c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon fsBuilder->codeAppendf("%s = %s.a * %s;", outputColor, inputColor, colorUni); 37c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon break; 38c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } 39c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } 40c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 41c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon void setData(const GrGLProgramDataManager& pdm, const GrProcessor& processor) override { 42c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrColor color = processor.cast<GrConstColorProcessor>().color(); 43c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon // We use the "illegal" color value as an uninit sentinel. However, ut isn't inherently 44c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon // illegal to use this processor with unpremul colors. So we correctly handle the case 45c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon // when the "illegal" color is used but we will always upload it. 46c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon if (GrColor_ILLEGAL == color || fPrevColor != color) { 47c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon static const GrGLfloat scale = 1.f / 255.f; 48c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrGLfloat floatColor[4] = { 49c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrColorUnpackR(color) * scale, 50c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrColorUnpackG(color) * scale, 51c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrColorUnpackB(color) * scale, 52c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrColorUnpackA(color) * scale, 53c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon }; 54c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon pdm.set4fv(fColorUniform, 1, floatColor); 55c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon fPrevColor = color; 56c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } 57c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } 58c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 59c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomonprivate: 60c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrGLProgramDataManager::UniformHandle fColorUniform; 61c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrColor fPrevColor; 62c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 63c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon typedef GrGLFragmentProcessor INHERITED; 64c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon}; 65c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 66c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon/////////////////////////////////////////////////////////////////////////////// 67c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 68c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomonvoid GrConstColorProcessor::onComputeInvariantOutput(GrInvariantOutput* inout) const { 69c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon if (kIgnore_InputMode == fMode) { 70c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon inout->setToOther(kRGBA_GrColorComponentFlags, fColor, GrInvariantOutput::kWill_ReadInput); 71c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } else { 72c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrColor r = GrColorUnpackR(fColor); 73c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon bool colorIsSingleChannel = r == GrColorUnpackG(fColor) && r == GrColorUnpackB(fColor) && 74c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon r == GrColorUnpackA(fColor); 75c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon if (kModulateRGBA_InputMode == fMode) { 76c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon if (colorIsSingleChannel) { 77c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon inout->mulByKnownSingleComponent(r); 78c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } else { 79c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon inout->mulByKnownFourComponents(fColor); 80c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } 81c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } else { 82c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon if (colorIsSingleChannel) { 83c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon inout->mulAlphaByKnownSingleComponent(r); 84c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } else { 85c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon inout->mulAlphaByKnownFourComponents(fColor); 86c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } 87c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } 88c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } 89c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon} 90c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 91cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid GrConstColorProcessor::getGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder* b) const { 92c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon b->add32(fMode); 93c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon} 94c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 95c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomonGrGLFragmentProcessor* GrConstColorProcessor::createGLInstance() const { 96c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon return SkNEW(GLConstColorProcessor); 97c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon} 98c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 99c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomonbool GrConstColorProcessor::onIsEqual(const GrFragmentProcessor& other) const { 100c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon const GrConstColorProcessor& that = other.cast<GrConstColorProcessor>(); 101c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon return fMode == that.fMode && fColor == that.fColor; 102c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon} 103c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 104c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon/////////////////////////////////////////////////////////////////////////////// 105c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 106c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomonGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConstColorProcessor); 107c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon 108c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomonGrFragmentProcessor* GrConstColorProcessor::TestCreate(SkRandom* random, 109c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrContext*, 110c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon const GrDrawTargetCaps&, 111c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrTexture*[]) { 112c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon GrColor color; 113c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon int colorPicker = random->nextULessThan(3); 114c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon switch (colorPicker) { 115c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon case 0: { 116c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon uint32_t a = random->nextULessThan(0x100); 117c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon uint32_t r = random->nextULessThan(a+1); 118c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon uint32_t g = random->nextULessThan(a+1); 119c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon uint32_t b = random->nextULessThan(a+1); 120c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon color = GrColorPackRGBA(r, g, b, a); 121c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon break; 122c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } 123c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon case 1: 124c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon color = 0; 125c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon break; 126c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon case 2: 127c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon color = random->nextULessThan(0x100); 128c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon color = color | (color << 8) | (color << 16) | (color << 24); 129c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon break; 130c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon } 131c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon InputMode mode = static_cast<InputMode>(random->nextULessThan(kInputModeCnt)); 132c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon return GrConstColorProcessor::Create(color, mode); 133c9c3e62b4ef6ec288549a0ad1d252986d7f0889dbsalomon} 134