blob: 2769c1810ee3ff62bfd5674eb5235f8c4f823259 [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);
egdaniel060a52c2015-04-07 07:31:11 -070030 this->setWillReadFragmentPosition();
bsalomon50785a32015-02-06 07:02:37 -080031 }
32}
33
ethannicholasde4166a2015-11-30 08:57:38 -080034GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(
35 const GrPipelineOptimizations& optimizations,
36 bool doesStencilWrite,
37 GrColor* overrideColor,
egdaniel56cf6dc2015-11-30 10:15:58 -080038 const GrCaps& caps) const {
ethannicholasde4166a2015-11-30 08:57:38 -080039 GrXferProcessor::OptFlags flags = this->onGetOptimizations(optimizations,
egdanielc19cdc22015-05-10 08:45:18 -070040 doesStencilWrite,
41 overrideColor,
42 caps);
43
cdaltonedbb31f2015-06-08 12:14:44 -070044 if (this->willReadDstColor()) {
45 // When performing a dst read we handle coverage in the base class.
46 SkASSERT(!(flags & GrXferProcessor::kIgnoreCoverage_OptFlag));
ethannicholasde4166a2015-11-30 08:57:38 -080047 if (optimizations.fCoveragePOI.isSolidWhite()) {
cdaltonedbb31f2015-06-08 12:14:44 -070048 flags |= GrXferProcessor::kIgnoreCoverage_OptFlag;
49 }
50 }
egdanielc19cdc22015-05-10 08:45:18 -070051 return flags;
52}
53
cdaltonedbb31f2015-06-08 12:14:44 -070054bool GrXferProcessor::hasSecondaryOutput() const {
55 if (!this->willReadDstColor()) {
56 return this->onHasSecondaryOutput();
57 }
cdalton86ae0a92015-06-08 15:11:04 -070058 return this->dstReadUsesMixedSamples();
cdaltonedbb31f2015-06-08 12:14:44 -070059}
60
61void GrXferProcessor::getBlendInfo(BlendInfo* blendInfo) const {
62 blendInfo->reset();
63 if (!this->willReadDstColor()) {
64 this->onGetBlendInfo(blendInfo);
cdalton86ae0a92015-06-08 15:11:04 -070065 } else if (this->dstReadUsesMixedSamples()) {
66 blendInfo->fDstBlend = kIS2A_GrBlendCoeff;
cdaltonedbb31f2015-06-08 12:14:44 -070067 }
68}
69
egdaniel57d3b032015-11-13 11:57:27 -080070void GrXferProcessor::getGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
bsalomon50785a32015-02-06 07:02:37 -080071 uint32_t key = this->willReadDstColor() ? 0x1 : 0x0;
cdaltonedbb31f2015-06-08 12:14:44 -070072 if (key) {
cdalton827bae12015-06-08 13:43:33 -070073 if (const GrTexture* dstTexture = this->getDstTexture()) {
cdaltonedbb31f2015-06-08 12:14:44 -070074 key |= 0x2;
cdalton827bae12015-06-08 13:43:33 -070075 if (kTopLeft_GrSurfaceOrigin == dstTexture->origin()) {
76 key |= 0x4;
77 }
cdaltonedbb31f2015-06-08 12:14:44 -070078 }
cdalton86ae0a92015-06-08 15:11:04 -070079 if (this->dstReadUsesMixedSamples()) {
egdaniel56cf6dc2015-11-30 10:15:58 -080080 key |= 0x8;
cdalton86ae0a92015-06-08 15:11:04 -070081 }
bsalomon50785a32015-02-06 07:02:37 -080082 }
83 b->add32(key);
egdaniel57d3b032015-11-13 11:57:27 -080084 this->onGetGLSLProcessorKey(caps, b);
bsalomon50785a32015-02-06 07:02:37 -080085}
86
bsalomoncb02b382015-08-12 11:14:50 -070087GrXferBarrierType GrXferProcessor::xferBarrierType(const GrRenderTarget* rt,
88 const GrCaps& caps) const {
89 SkASSERT(rt);
bsalomon6a44c6a2015-05-26 09:49:05 -070090 if (static_cast<const GrSurface*>(rt) == this->getDstTexture()) {
cdalton9954bc32015-04-29 14:17:00 -070091 // Texture barriers are required when a shader reads and renders to the same texture.
cdalton9954bc32015-04-29 14:17:00 -070092 SkASSERT(caps.textureBarrierSupport());
bsalomoncb02b382015-08-12 11:14:50 -070093 return kTexture_GrXferBarrierType;
cdalton9954bc32015-04-29 14:17:00 -070094 }
bsalomoncb02b382015-08-12 11:14:50 -070095 return this->onXferBarrier(rt, caps);
cdalton9954bc32015-04-29 14:17:00 -070096}
97
bsalomonf7cc8772015-05-11 11:21:14 -070098#ifdef SK_DEBUG
99static const char* equation_string(GrBlendEquation eq) {
100 switch (eq) {
101 case kAdd_GrBlendEquation:
102 return "add";
103 case kSubtract_GrBlendEquation:
104 return "subtract";
105 case kReverseSubtract_GrBlendEquation:
106 return "reverse_subtract";
107 case kScreen_GrBlendEquation:
108 return "screen";
109 case kOverlay_GrBlendEquation:
110 return "overlay";
111 case kDarken_GrBlendEquation:
112 return "darken";
113 case kLighten_GrBlendEquation:
114 return "lighten";
115 case kColorDodge_GrBlendEquation:
116 return "color_dodge";
117 case kColorBurn_GrBlendEquation:
118 return "color_burn";
119 case kHardLight_GrBlendEquation:
120 return "hard_light";
121 case kSoftLight_GrBlendEquation:
122 return "soft_light";
123 case kDifference_GrBlendEquation:
124 return "difference";
125 case kExclusion_GrBlendEquation:
126 return "exclusion";
127 case kMultiply_GrBlendEquation:
128 return "multiply";
129 case kHSLHue_GrBlendEquation:
130 return "hsl_hue";
131 case kHSLSaturation_GrBlendEquation:
132 return "hsl_saturation";
133 case kHSLColor_GrBlendEquation:
134 return "hsl_color";
135 case kHSLLuminosity_GrBlendEquation:
136 return "hsl_luminosity";
137 };
138 return "";
139}
140
141static const char* coeff_string(GrBlendCoeff coeff) {
142 switch (coeff) {
143 case kZero_GrBlendCoeff:
144 return "zero";
145 case kOne_GrBlendCoeff:
146 return "one";
147 case kSC_GrBlendCoeff:
148 return "src_color";
149 case kISC_GrBlendCoeff:
150 return "inv_src_color";
151 case kDC_GrBlendCoeff:
152 return "dst_color";
153 case kIDC_GrBlendCoeff:
154 return "inv_dst_color";
155 case kSA_GrBlendCoeff:
156 return "src_alpha";
157 case kISA_GrBlendCoeff:
158 return "inv_src_alpha";
159 case kDA_GrBlendCoeff:
160 return "dst_alpha";
161 case kIDA_GrBlendCoeff:
162 return "inv_dst_alpha";
163 case kConstC_GrBlendCoeff:
164 return "const_color";
165 case kIConstC_GrBlendCoeff:
166 return "inv_const_color";
167 case kConstA_GrBlendCoeff:
168 return "const_alpha";
169 case kIConstA_GrBlendCoeff:
170 return "inv_const_alpha";
171 case kS2C_GrBlendCoeff:
172 return "src2_color";
173 case kIS2C_GrBlendCoeff:
174 return "inv_src2_color";
175 case kS2A_GrBlendCoeff:
176 return "src2_alpha";
177 case kIS2A_GrBlendCoeff:
178 return "inv_src2_alpha";
179 }
180 return "";
181}
182
183SkString GrXferProcessor::BlendInfo::dump() const {
184 SkString out;
185 out.printf("write_color(%d) equation(%s) src_coeff(%s) dst_coeff:(%s) const(0x%08x)",
186 fWriteColor, equation_string(fEquation), coeff_string(fSrcBlend),
187 coeff_string(fDstBlend), fBlendConstant);
188 return out;
189}
190#endif
191
bsalomon50785a32015-02-06 07:02:37 -0800192///////////////////////////////////////////////////////////////////////////////
193
ethannicholasde4166a2015-11-30 08:57:38 -0800194GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineOptimizations& optimizations,
cdalton86ae0a92015-06-08 15:11:04 -0700195 bool hasMixedSamples,
bsalomon6a44c6a2015-05-26 09:49:05 -0700196 const DstTexture* dstTexture,
bsalomon4b91f762015-05-19 09:29:46 -0700197 const GrCaps& caps) const {
bsalomon50785a32015-02-06 07:02:37 -0800198#ifdef SK_DEBUG
cdalton3ccf2e72016-05-06 09:41:16 -0700199 if (this->willReadDstColor(caps, optimizations)) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700200 if (!caps.shaderCaps()->dstReadInShaderSupport()) {
bsalomon6a44c6a2015-05-26 09:49:05 -0700201 SkASSERT(dstTexture && dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800202 } else {
halcanary9d524f22016-03-29 09:03:52 -0700203 SkASSERT(!dstTexture || !dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800204 }
205 } else {
halcanary9d524f22016-03-29 09:03:52 -0700206 SkASSERT(!dstTexture || !dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800207 }
cdalton86ae0a92015-06-08 15:11:04 -0700208 SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport());
bsalomon50785a32015-02-06 07:02:37 -0800209#endif
ethannicholasde4166a2015-11-30 08:57:38 -0800210 return this->onCreateXferProcessor(caps, optimizations, hasMixedSamples, dstTexture);
bsalomon50785a32015-02-06 07:02:37 -0800211}
212
cdalton86ae0a92015-06-08 15:11:04 -0700213bool GrXPFactory::willNeedDstTexture(const GrCaps& caps,
cdalton3ccf2e72016-05-06 09:41:16 -0700214 const GrPipelineOptimizations& optimizations) const {
215 return (this->willReadDstColor(caps, optimizations) &&
cdalton86ae0a92015-06-08 15:11:04 -0700216 !caps.shaderCaps()->dstReadInShaderSupport());
bsalomon50785a32015-02-06 07:02:37 -0800217}
ethannicholas22793252016-01-30 09:59:10 -0800218
219bool GrXPFactory::willReadDstColor(const GrCaps& caps,
cdalton3ccf2e72016-05-06 09:41:16 -0700220 const GrPipelineOptimizations& optimizations) const {
221 return optimizations.fOverrides.fUsePLSDstRead || this->onWillReadDstColor(caps, optimizations);
ethannicholas22793252016-01-30 09:59:10 -0800222}