| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "effects/GrXfermodeFragmentProcessor.h" | 8 #include "effects/GrXfermodeFragmentProcessor.h" | 
| 9 | 9 | 
| 10 #include "GrFragmentProcessor.h" | 10 #include "GrFragmentProcessor.h" | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 71 | 71 | 
| 72 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrComposeTwoFragmentProcessor); | 72 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrComposeTwoFragmentProcessor); | 
| 73 | 73 | 
| 74 const GrFragmentProcessor* GrComposeTwoFragmentProcessor::TestCreate(GrProcessor
     TestData* d) { | 74 const GrFragmentProcessor* GrComposeTwoFragmentProcessor::TestCreate(GrProcessor
     TestData* d) { | 
| 75 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS | 75 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS | 
| 76     // Create two random frag procs. | 76     // Create two random frag procs. | 
| 77     // For now, we'll prevent either children from being a shader with children 
     to prevent the | 77     // For now, we'll prevent either children from being a shader with children 
     to prevent the | 
| 78     // possibility of an arbitrarily large tree of procs. | 78     // possibility of an arbitrarily large tree of procs. | 
| 79     SkAutoTUnref<const GrFragmentProcessor> fpA; | 79     SkAutoTUnref<const GrFragmentProcessor> fpA; | 
| 80     do { | 80     do { | 
| 81         fpA.reset(GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d)); | 81         fpA.reset(GrProcessorTestFactory<GrFragmentProcessor>::Create(d)); | 
| 82         SkASSERT(fpA); | 82         SkASSERT(fpA); | 
| 83     } while (fpA->numChildProcessors() != 0); | 83     } while (fpA->numChildProcessors() != 0); | 
| 84     SkAutoTUnref<const GrFragmentProcessor> fpB; | 84     SkAutoTUnref<const GrFragmentProcessor> fpB; | 
| 85     do { | 85     do { | 
| 86         fpB.reset(GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d)); | 86         fpB.reset(GrProcessorTestFactory<GrFragmentProcessor>::Create(d)); | 
| 87         SkASSERT(fpB); | 87         SkASSERT(fpB); | 
| 88     } while (fpB->numChildProcessors() != 0); | 88     } while (fpB->numChildProcessors() != 0); | 
| 89 | 89 | 
| 90     SkXfermode::Mode mode = static_cast<SkXfermode::Mode>( | 90     SkXfermode::Mode mode = static_cast<SkXfermode::Mode>( | 
| 91             d->fRandom->nextRangeU(0, SkXfermode::kLastCoeffMode)); | 91             d->fRandom->nextRangeU(0, SkXfermode::kLastCoeffMode)); | 
| 92     return SkNEW_ARGS(GrComposeTwoFragmentProcessor, (fpA, fpB, mode)); | 92     return SkNEW_ARGS(GrComposeTwoFragmentProcessor, (fpA, fpB, mode)); | 
| 93 #else | 93 #else | 
| 94     SkFAIL("Should not be called if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS"); | 94     SkFAIL("Should not be called if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS"); | 
| 95     return nullptr; | 95     return nullptr; | 
| 96 #endif | 96 #endif | 
| 97 } | 97 } | 
| 98 | 98 | 
| 99 GrGLFragmentProcessor* GrComposeTwoFragmentProcessor::onCreateGLInstance() const
     { | 99 GrGLFragmentProcessor* GrComposeTwoFragmentProcessor::onCreateGLInstance() const
     { | 
| 100     return SkNEW_ARGS(GrGLComposeTwoFragmentProcessor, (*this)); | 100     return SkNEW_ARGS(GrGLComposeTwoFragmentProcessor, (*this)); | 
| 101 } | 101 } | 
| 102 | 102 | 
| 103 ///////////////////////////////////////////////////////////////////// | 103 ///////////////////////////////////////////////////////////////////// | 
| 104 | 104 | 
| 105 void GrGLComposeTwoFragmentProcessor::emitCode(EmitArgs& args) { | 105 void GrGLComposeTwoFragmentProcessor::emitCode(EmitArgs& args) { | 
| 106 | 106 | 
| 107     GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); | 107     GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); | 
| 108     const GrComposeTwoFragmentProcessor& cs = args.fFp.cast<GrComposeTwoFragment
     Processor>(); | 108     const GrComposeTwoFragmentProcessor& cs = args.fFp.cast<GrComposeTwoFragment
     Processor>(); | 
| 109 | 109 | 
| 110     // Store alpha of input color and un-premultiply the input color by its alph
     a. We will | 110     // Store alpha of input color and un-premultiply the input color by its alph
     a. We will | 
| 111     // re-multiply by this alpha after blending the output colors of the two chi
     ld procs. | 111     // re-multiply by this alpha after blending the output colors of the two chi
     ld procs. | 
| 112     // This is because we don't want the paint's alpha to affect either child pr
     oc's output | 112     // This is because we don't want the paint's alpha to affect either child pr
     oc's output | 
| 113     // before the blend; we want to apply the paint's alpha AFTER the blend. Thi
     s mirrors the | 113     // before the blend; we want to apply the paint's alpha AFTER the blend. Thi
     s mirrors the | 
| 114     // software implementation of SkComposeShader. | 114     // software implementation of SkComposeShader. | 
| 115     SkString inputAlpha("inputAlpha"); | 115     const char* opaqueInput = nullptr; | 
| 116     fsBuilder->codeAppendf("float %s = %s.a;", inputAlpha.c_str(), args.fInputCo
     lor); | 116     const char* inputAlpha = nullptr; | 
| 117     fsBuilder->codeAppendf("%s /= %s.a;", args.fInputColor, args.fInputColor); | 117     if (args.fInputColor) { | 
|  | 118         inputAlpha = "inputAlpha"; | 
|  | 119         opaqueInput = "opaqueInput"; | 
|  | 120         fsBuilder->codeAppendf("float inputAlpha = %s.a;", args.fInputColor); | 
|  | 121         fsBuilder->codeAppendf("vec4 opaqueInput = vec4(%s.rgb / inputAlpha, 1);
     ", | 
|  | 122                                args.fInputColor); | 
|  | 123     } | 
| 118 | 124 | 
| 119     // declare outputColor and emit the code for each of the two children | 125     // declare outputColor and emit the code for each of the two children | 
| 120     SkString outputColorSrc(args.fOutputColor); | 126     SkString outputColorSrc(args.fOutputColor); | 
| 121     outputColorSrc.append("_src"); | 127     outputColorSrc.append("_src"); | 
| 122     fsBuilder->codeAppendf("vec4 %s;\n", outputColorSrc.c_str()); | 128     fsBuilder->codeAppendf("vec4 %s;\n", outputColorSrc.c_str()); | 
| 123     this->emitChild(0, args.fInputColor, outputColorSrc.c_str(), args); | 129     this->emitChild(0, opaqueInput, outputColorSrc.c_str(), args); | 
| 124 | 130 | 
| 125     SkString outputColorDst(args.fOutputColor); | 131     SkString outputColorDst(args.fOutputColor); | 
| 126     outputColorDst.append("_dst"); | 132     outputColorDst.append("_dst"); | 
| 127     fsBuilder->codeAppendf("vec4 %s;\n", outputColorDst.c_str()); | 133     fsBuilder->codeAppendf("vec4 %s;\n", outputColorDst.c_str()); | 
| 128     this->emitChild(1, args.fInputColor, outputColorDst.c_str(), args); | 134     this->emitChild(1, opaqueInput, outputColorDst.c_str(), args); | 
| 129 | 135 | 
| 130     // emit blend code | 136     // emit blend code | 
| 131     SkXfermode::Mode mode = cs.getMode(); | 137     SkXfermode::Mode mode = cs.getMode(); | 
| 132     fsBuilder->codeAppend("{"); | 138     fsBuilder->codeAppend("{"); | 
| 133     fsBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mo
     de)); | 139     fsBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mo
     de)); | 
| 134     GrGLBlend::AppendPorterDuffBlend(fsBuilder, outputColorSrc.c_str(), | 140     GrGLBlend::AppendPorterDuffBlend(fsBuilder, outputColorSrc.c_str(), | 
| 135                                      outputColorDst.c_str(), args.fOutputColor, 
     mode); | 141                                      outputColorDst.c_str(), args.fOutputColor, 
     mode); | 
| 136     fsBuilder->codeAppend("}"); | 142     fsBuilder->codeAppend("}"); | 
| 137 | 143 | 
| 138     // re-multiply the output color by the input color's alpha | 144     // re-multiply the output color by the input color's alpha | 
| 139     fsBuilder->codeAppendf("%s *= %s;", args.fOutputColor, inputAlpha.c_str()); | 145     if (inputAlpha) { | 
|  | 146         fsBuilder->codeAppendf("%s *= %s;", args.fOutputColor, inputAlpha); | 
|  | 147     } | 
| 140 } | 148 } | 
| 141 | 149 | 
| 142 |  | 
| 143 const GrFragmentProcessor* GrXfermodeFragmentProcessor::CreateFromTwoProcessors( | 150 const GrFragmentProcessor* GrXfermodeFragmentProcessor::CreateFromTwoProcessors( | 
| 144          const GrFragmentProcessor* src, const GrFragmentProcessor* dst, SkXferm
     ode::Mode mode) { | 151          const GrFragmentProcessor* src, const GrFragmentProcessor* dst, SkXferm
     ode::Mode mode) { | 
| 145     if (SkXfermode::kLastCoeffMode < mode) { | 152     if (SkXfermode::kLastCoeffMode < mode) { | 
| 146         return nullptr; | 153         return nullptr; | 
| 147     } | 154     } | 
| 148     switch (mode) { | 155     switch (mode) { | 
| 149         case SkXfermode::kClear_Mode: | 156         case SkXfermode::kClear_Mode: | 
| 150             return GrConstColorProcessor::Create(GrColor_TRANS_BLACK, | 157             return GrConstColorProcessor::Create(GrColor_TRANS_BLACK, | 
| 151                                                  GrConstColorProcessor::kIgnore_
     InputMode); | 158                                                  GrConstColorProcessor::kIgnore_
     InputMode); | 
| 152             break; | 159             break; | 
| 153         case SkXfermode::kSrc_Mode: | 160         case SkXfermode::kSrc_Mode: | 
| 154             return SkRef(src); | 161             return SkRef(src); | 
| 155             break; | 162             break; | 
| 156         case SkXfermode::kDst_Mode: | 163         case SkXfermode::kDst_Mode: | 
| 157             return SkRef(dst); | 164             return SkRef(dst); | 
| 158             break; | 165             break; | 
| 159         default: | 166         default: | 
| 160             return new GrComposeTwoFragmentProcessor(src, dst, mode); | 167             return new GrComposeTwoFragmentProcessor(src, dst, mode); | 
| 161     } | 168     } | 
| 162 } | 169 } | 
| OLD | NEW | 
|---|