blob: 7de0d77afdadbb608b237c69f01c3f59282d35e2 [file] [log] [blame]
bsalomon50785a32015-02-06 07:02:37 -08001/*
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 "GrXferProcessor.h"
ethannicholasde4166a2015-11-30 08:57:38 -08009#include "GrPipeline.h"
cdaltonedbb31f2015-06-08 12:14:44 -070010#include "GrProcOptInfo.h"
bsalomon50785a32015-02-06 07:02:37 -080011#include "gl/GrGLCaps.h"
12
egdanielc19cdc22015-05-10 08:45:18 -070013GrXferProcessor::GrXferProcessor()
cdalton86ae0a92015-06-08 15:11:04 -070014 : fWillReadDstColor(false)
15 , fDstReadUsesMixedSamples(false)
cdalton86ae0a92015-06-08 15:11:04 -070016 , fDstTextureOffset() {
bsalomon50785a32015-02-06 07:02:37 -080017}
18
cdalton86ae0a92015-06-08 15:11:04 -070019GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture,
20 bool willReadDstColor,
21 bool hasMixedSamples)
bsalomon50785a32015-02-06 07:02:37 -080022 : fWillReadDstColor(willReadDstColor)
cdalton86ae0a92015-06-08 15:11:04 -070023 , fDstReadUsesMixedSamples(willReadDstColor && hasMixedSamples)
bsalomon6a44c6a2015-05-26 09:49:05 -070024 , fDstTextureOffset() {
25 if (dstTexture && dstTexture->texture()) {
cdaltonedbb31f2015-06-08 12:14:44 -070026 SkASSERT(willReadDstColor);
bsalomon6a44c6a2015-05-26 09:49:05 -070027 fDstTexture.reset(dstTexture->texture());
28 fDstTextureOffset = dstTexture->offset();
Brian Salomon0bbecb22016-11-17 11:38:22 -050029 this->addTextureSampler(&fDstTexture);
bsalomon50785a32015-02-06 07:02:37 -080030 }
31}
32
Brian Salomon92aee3d2016-12-21 09:20:25 -050033GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(const GrPipelineAnalysis& analysis,
34 bool doesStencilWrite,
35 GrColor* overrideColor,
36 const GrCaps& caps) const {
37 GrXferProcessor::OptFlags flags =
38 this->onGetOptimizations(analysis, doesStencilWrite, overrideColor, caps);
egdanielc19cdc22015-05-10 08:45:18 -070039 return flags;
40}
41
cdaltonedbb31f2015-06-08 12:14:44 -070042bool GrXferProcessor::hasSecondaryOutput() const {
43 if (!this->willReadDstColor()) {
44 return this->onHasSecondaryOutput();
45 }
cdalton86ae0a92015-06-08 15:11:04 -070046 return this->dstReadUsesMixedSamples();
cdaltonedbb31f2015-06-08 12:14:44 -070047}
48
49void GrXferProcessor::getBlendInfo(BlendInfo* blendInfo) const {
50 blendInfo->reset();
51 if (!this->willReadDstColor()) {
52 this->onGetBlendInfo(blendInfo);
cdalton86ae0a92015-06-08 15:11:04 -070053 } else if (this->dstReadUsesMixedSamples()) {
54 blendInfo->fDstBlend = kIS2A_GrBlendCoeff;
cdaltonedbb31f2015-06-08 12:14:44 -070055 }
56}
57
Brian Salomon94efbf52016-11-29 13:43:05 -050058void GrXferProcessor::getGLSLProcessorKey(const GrShaderCaps& caps,
59 GrProcessorKeyBuilder* b) const {
bsalomon50785a32015-02-06 07:02:37 -080060 uint32_t key = this->willReadDstColor() ? 0x1 : 0x0;
cdaltonedbb31f2015-06-08 12:14:44 -070061 if (key) {
cdalton827bae12015-06-08 13:43:33 -070062 if (const GrTexture* dstTexture = this->getDstTexture()) {
cdaltonedbb31f2015-06-08 12:14:44 -070063 key |= 0x2;
cdalton827bae12015-06-08 13:43:33 -070064 if (kTopLeft_GrSurfaceOrigin == dstTexture->origin()) {
65 key |= 0x4;
66 }
cdaltonedbb31f2015-06-08 12:14:44 -070067 }
cdalton86ae0a92015-06-08 15:11:04 -070068 if (this->dstReadUsesMixedSamples()) {
egdaniel56cf6dc2015-11-30 10:15:58 -080069 key |= 0x8;
cdalton86ae0a92015-06-08 15:11:04 -070070 }
bsalomon50785a32015-02-06 07:02:37 -080071 }
72 b->add32(key);
egdaniel57d3b032015-11-13 11:57:27 -080073 this->onGetGLSLProcessorKey(caps, b);
bsalomon50785a32015-02-06 07:02:37 -080074}
75
bsalomoncb02b382015-08-12 11:14:50 -070076GrXferBarrierType GrXferProcessor::xferBarrierType(const GrRenderTarget* rt,
77 const GrCaps& caps) const {
78 SkASSERT(rt);
bsalomon6a44c6a2015-05-26 09:49:05 -070079 if (static_cast<const GrSurface*>(rt) == this->getDstTexture()) {
cdalton9954bc32015-04-29 14:17:00 -070080 // Texture barriers are required when a shader reads and renders to the same texture.
cdalton9954bc32015-04-29 14:17:00 -070081 SkASSERT(caps.textureBarrierSupport());
bsalomoncb02b382015-08-12 11:14:50 -070082 return kTexture_GrXferBarrierType;
cdalton9954bc32015-04-29 14:17:00 -070083 }
bsalomoncb02b382015-08-12 11:14:50 -070084 return this->onXferBarrier(rt, caps);
cdalton9954bc32015-04-29 14:17:00 -070085}
86
bsalomonf7cc8772015-05-11 11:21:14 -070087#ifdef SK_DEBUG
88static const char* equation_string(GrBlendEquation eq) {
89 switch (eq) {
90 case kAdd_GrBlendEquation:
91 return "add";
92 case kSubtract_GrBlendEquation:
93 return "subtract";
94 case kReverseSubtract_GrBlendEquation:
95 return "reverse_subtract";
96 case kScreen_GrBlendEquation:
97 return "screen";
98 case kOverlay_GrBlendEquation:
99 return "overlay";
100 case kDarken_GrBlendEquation:
101 return "darken";
102 case kLighten_GrBlendEquation:
103 return "lighten";
104 case kColorDodge_GrBlendEquation:
105 return "color_dodge";
106 case kColorBurn_GrBlendEquation:
107 return "color_burn";
108 case kHardLight_GrBlendEquation:
109 return "hard_light";
110 case kSoftLight_GrBlendEquation:
111 return "soft_light";
112 case kDifference_GrBlendEquation:
113 return "difference";
114 case kExclusion_GrBlendEquation:
115 return "exclusion";
116 case kMultiply_GrBlendEquation:
117 return "multiply";
118 case kHSLHue_GrBlendEquation:
119 return "hsl_hue";
120 case kHSLSaturation_GrBlendEquation:
121 return "hsl_saturation";
122 case kHSLColor_GrBlendEquation:
123 return "hsl_color";
124 case kHSLLuminosity_GrBlendEquation:
125 return "hsl_luminosity";
126 };
127 return "";
128}
129
130static const char* coeff_string(GrBlendCoeff coeff) {
131 switch (coeff) {
132 case kZero_GrBlendCoeff:
133 return "zero";
134 case kOne_GrBlendCoeff:
135 return "one";
136 case kSC_GrBlendCoeff:
137 return "src_color";
138 case kISC_GrBlendCoeff:
139 return "inv_src_color";
140 case kDC_GrBlendCoeff:
141 return "dst_color";
142 case kIDC_GrBlendCoeff:
143 return "inv_dst_color";
144 case kSA_GrBlendCoeff:
145 return "src_alpha";
146 case kISA_GrBlendCoeff:
147 return "inv_src_alpha";
148 case kDA_GrBlendCoeff:
149 return "dst_alpha";
150 case kIDA_GrBlendCoeff:
151 return "inv_dst_alpha";
152 case kConstC_GrBlendCoeff:
153 return "const_color";
154 case kIConstC_GrBlendCoeff:
155 return "inv_const_color";
156 case kConstA_GrBlendCoeff:
157 return "const_alpha";
158 case kIConstA_GrBlendCoeff:
159 return "inv_const_alpha";
160 case kS2C_GrBlendCoeff:
161 return "src2_color";
162 case kIS2C_GrBlendCoeff:
163 return "inv_src2_color";
164 case kS2A_GrBlendCoeff:
165 return "src2_alpha";
166 case kIS2A_GrBlendCoeff:
167 return "inv_src2_alpha";
168 }
169 return "";
170}
171
172SkString GrXferProcessor::BlendInfo::dump() const {
173 SkString out;
174 out.printf("write_color(%d) equation(%s) src_coeff(%s) dst_coeff:(%s) const(0x%08x)",
175 fWriteColor, equation_string(fEquation), coeff_string(fSrcBlend),
176 coeff_string(fDstBlend), fBlendConstant);
177 return out;
178}
179#endif
180
bsalomon50785a32015-02-06 07:02:37 -0800181///////////////////////////////////////////////////////////////////////////////
182
Brian Salomon92aee3d2016-12-21 09:20:25 -0500183GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineAnalysis& analysis,
cdalton86ae0a92015-06-08 15:11:04 -0700184 bool hasMixedSamples,
bsalomon6a44c6a2015-05-26 09:49:05 -0700185 const DstTexture* dstTexture,
bsalomon4b91f762015-05-19 09:29:46 -0700186 const GrCaps& caps) const {
bsalomon50785a32015-02-06 07:02:37 -0800187#ifdef SK_DEBUG
Brian Salomon92aee3d2016-12-21 09:20:25 -0500188 if (this->willReadDstColor(caps, analysis)) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700189 if (!caps.shaderCaps()->dstReadInShaderSupport()) {
bsalomon6a44c6a2015-05-26 09:49:05 -0700190 SkASSERT(dstTexture && dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800191 } else {
halcanary9d524f22016-03-29 09:03:52 -0700192 SkASSERT(!dstTexture || !dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800193 }
194 } else {
halcanary9d524f22016-03-29 09:03:52 -0700195 SkASSERT(!dstTexture || !dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800196 }
cdalton86ae0a92015-06-08 15:11:04 -0700197 SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport());
bsalomon50785a32015-02-06 07:02:37 -0800198#endif
Brian Salomon92aee3d2016-12-21 09:20:25 -0500199 return this->onCreateXferProcessor(caps, analysis, hasMixedSamples, dstTexture);
bsalomon50785a32015-02-06 07:02:37 -0800200}
201
Brian Salomon92aee3d2016-12-21 09:20:25 -0500202bool GrXPFactory::willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) const {
203 return (this->willReadDstColor(caps, analysis) && !caps.shaderCaps()->dstReadInShaderSupport());
bsalomon50785a32015-02-06 07:02:37 -0800204}
ethannicholas22793252016-01-30 09:59:10 -0800205
Brian Salomon92aee3d2016-12-21 09:20:25 -0500206bool GrXPFactory::willReadDstColor(const GrCaps& caps, const GrPipelineAnalysis& analysis) const {
207 return analysis.fUsesPLSDstRead || this->onWillReadDstColor(caps, analysis);
ethannicholas22793252016-01-30 09:59:10 -0800208}