Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(585)

Side by Side Diff: src/gpu/effects/GrXfermodeFragmentProcessor.cpp

Issue 1306163005: Added function CreateFrom2Procs() in new namespace GrXfermodeFragmentProcessor (Closed) Base URL: https://skia.googlesource.com/skia@cs3_testcreate
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkComposeShader.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "effects/GrXfermodeFragmentProcessor.h"
9
10 #include "GrFragmentProcessor.h"
11 #include "effects/GrConstColorProcessor.h"
12 #include "gl/GrGLBlend.h"
13 #include "gl/builders/GrGLProgramBuilder.h"
14
15
16 class GrComposeTwoFragmentProcessor : public GrFragmentProcessor {
17 public:
18 GrComposeTwoFragmentProcessor(const GrFragmentProcessor* src, const GrFragme ntProcessor* dst,
19 SkXfermode::Mode mode)
20 : fMode(mode) {
21 // Only coefficient xfer modes are supported
22 SkASSERT(SkXfermode::kLastCoeffMode >= mode);
23 this->initClassID<GrComposeTwoFragmentProcessor>();
24 SkDEBUGCODE(int shaderAChildIndex = )this->registerChildProcessor(src);
25 SkDEBUGCODE(int shaderBChildIndex = )this->registerChildProcessor(dst);
26 SkASSERT(0 == shaderAChildIndex);
27 SkASSERT(1 == shaderBChildIndex);
28 }
29
30 const char* name() const override { return "ComposeShader"; }
31
32 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override {
33 b->add32(fMode);
34 }
35
36 SkXfermode::Mode getMode() const { return fMode; }
37
38 protected:
39 bool onIsEqual(const GrFragmentProcessor& other) const override {
40 const GrComposeTwoFragmentProcessor& cs = other.cast<GrComposeTwoFragmen tProcessor>();
41 return fMode == cs.fMode;
42 }
43
44 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
45 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
46 }
47
48 private:
49 GrGLFragmentProcessor* onCreateGLInstance() const override;
50
51 SkXfermode::Mode fMode;
52
53 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
54
55 typedef GrFragmentProcessor INHERITED;
56 };
57
58 /////////////////////////////////////////////////////////////////////
59
60 class GrGLComposeTwoFragmentProcessor : public GrGLFragmentProcessor {
61 public:
62 GrGLComposeTwoFragmentProcessor(const GrProcessor& processor) {}
63
64 void emitCode(EmitArgs&) override;
65
66 private:
67 typedef GrGLFragmentProcessor INHERITED;
68 };
69
70 /////////////////////////////////////////////////////////////////////
71
72 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrComposeTwoFragmentProcessor);
73
74 const GrFragmentProcessor* GrComposeTwoFragmentProcessor::TestCreate(GrProcessor TestData* d) {
75 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
76 // Create two random frag procs.
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.
79 SkAutoTUnref<const GrFragmentProcessor> fpA;
80 do {
81 fpA.reset(GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d));
82 SkASSERT(fpA);
83 } while (fpA->numChildProcessors() != 0);
84 SkAutoTUnref<const GrFragmentProcessor> fpB;
85 do {
86 fpB.reset(GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d));
87 SkASSERT(fpB);
88 } while (fpB->numChildProcessors() != 0);
89
90 SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(
91 d->fRandom->nextRangeU(0, SkXfermode::kLastCoeffMode));
92 return SkNEW_ARGS(GrComposeTwoFragmentProcessor, (fpA, fpB, mode));
93 #else
94 SkFAIL("Should not be called if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS");
95 return nullptr;
96 #endif
97 }
98
99 GrGLFragmentProcessor* GrComposeTwoFragmentProcessor::onCreateGLInstance() const {
100 return SkNEW_ARGS(GrGLComposeTwoFragmentProcessor, (*this));
101 }
102
103 /////////////////////////////////////////////////////////////////////
104
105 void GrGLComposeTwoFragmentProcessor::emitCode(EmitArgs& args) {
106
107 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
108 const GrComposeTwoFragmentProcessor& cs = args.fFp.cast<GrComposeTwoFragment Processor>();
109
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.
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
114 // software implementation of SkComposeShader.
115 SkString inputAlpha("inputAlpha");
116 fsBuilder->codeAppendf("float %s = %s.a;", inputAlpha.c_str(), args.fInputCo lor);
117 fsBuilder->codeAppendf("%s /= %s.a;", args.fInputColor, args.fInputColor);
118
119 // declare outputColor and emit the code for each of the two children
120 SkString outputColorSrc(args.fOutputColor);
121 outputColorSrc.append("_src");
122 fsBuilder->codeAppendf("vec4 %s;\n", outputColorSrc.c_str());
123 this->emitChild(0, args.fInputColor, outputColorSrc.c_str(), args);
124
125 SkString outputColorDst(args.fOutputColor);
126 outputColorDst.append("_dst");
127 fsBuilder->codeAppendf("vec4 %s;\n", outputColorDst.c_str());
128 this->emitChild(1, args.fInputColor, outputColorDst.c_str(), args);
129
130 // emit blend code
131 SkXfermode::Mode mode = cs.getMode();
132 fsBuilder->codeAppend("{");
133 fsBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mo de));
134 GrGLBlend::AppendPorterDuffBlend(fsBuilder, outputColorSrc.c_str(),
135 outputColorDst.c_str(), args.fOutputColor, mode);
136 fsBuilder->codeAppend("}");
137
138 // re-multiply the output color by the input color's alpha
139 fsBuilder->codeAppendf("%s *= %s;", args.fOutputColor, inputAlpha.c_str());
140 }
141
142
143 const GrFragmentProcessor* GrXfermodeFragmentProcessor::CreateFromTwoProcessors(
144 const GrFragmentProcessor* src, const GrFragmentProcessor* dst, SkXferm ode::Mode mode) {
145 if (SkXfermode::kLastCoeffMode < mode) {
146 return nullptr;
147 }
148 switch (mode) {
149 case SkXfermode::kClear_Mode:
150 SkDebugf("CreateFromTwoProcessors() should not be used with kClear_M ode. "
151 "Use GrConstColorProcessor.\n");
152 return GrConstColorProcessor::Create(GrColor_TRANS_BLACK,
153 GrConstColorProcessor::kIgnore_ InputMode);
154 break;
155 case SkXfermode::kSrc_Mode:
156 SkDebugf("CreateFromTwoProcessors() should not be used with kSrc_Mod e. "
157 "Use the src processor directly.\n");
158 return SkRef(src);
159 break;
160 case SkXfermode::kDst_Mode:
161 SkDebugf("CreateFromTwoProcessors() should not be used with kDst_Mod e. "
162 "Use the dst processor directly.\n");
163 return SkRef(dst);
164 break;
165 default:
166 return new GrComposeTwoFragmentProcessor(src, dst, mode);
167 }
168 }
OLDNEW
« no previous file with comments | « src/core/SkComposeShader.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698