blob: 3bccd6e3f76a4f20c24c5040b43d49814c482a8f [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"
cdalton86ae0a92015-06-08 15:11:04 -070010#include "GrPipelineBuilder.h"
cdaltonedbb31f2015-06-08 12:14:44 -070011#include "GrProcOptInfo.h"
bsalomon50785a32015-02-06 07:02:37 -080012#include "gl/GrGLCaps.h"
13
egdanielc19cdc22015-05-10 08:45:18 -070014GrXferProcessor::GrXferProcessor()
cdalton86ae0a92015-06-08 15:11:04 -070015 : fWillReadDstColor(false)
16 , fDstReadUsesMixedSamples(false)
17 , fReadsCoverage(true)
18 , fDstTextureOffset() {
bsalomon50785a32015-02-06 07:02:37 -080019}
20
cdalton86ae0a92015-06-08 15:11:04 -070021GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture,
22 bool willReadDstColor,
23 bool hasMixedSamples)
bsalomon50785a32015-02-06 07:02:37 -080024 : fWillReadDstColor(willReadDstColor)
cdalton86ae0a92015-06-08 15:11:04 -070025 , fDstReadUsesMixedSamples(willReadDstColor && hasMixedSamples)
egdanielc19cdc22015-05-10 08:45:18 -070026 , fReadsCoverage(true)
bsalomon6a44c6a2015-05-26 09:49:05 -070027 , fDstTextureOffset() {
28 if (dstTexture && dstTexture->texture()) {
cdaltonedbb31f2015-06-08 12:14:44 -070029 SkASSERT(willReadDstColor);
bsalomon6a44c6a2015-05-26 09:49:05 -070030 fDstTexture.reset(dstTexture->texture());
31 fDstTextureOffset = dstTexture->offset();
32 this->addTextureAccess(&fDstTexture);
egdaniel060a52c2015-04-07 07:31:11 -070033 this->setWillReadFragmentPosition();
bsalomon50785a32015-02-06 07:02:37 -080034 }
35}
36
ethannicholasde4166a2015-11-30 08:57:38 -080037GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(
38 const GrPipelineOptimizations& optimizations,
39 bool doesStencilWrite,
40 GrColor* overrideColor,
41 const GrCaps& caps) {
42 GrXferProcessor::OptFlags flags = this->onGetOptimizations(optimizations,
egdanielc19cdc22015-05-10 08:45:18 -070043 doesStencilWrite,
44 overrideColor,
45 caps);
46
cdaltonedbb31f2015-06-08 12:14:44 -070047 if (this->willReadDstColor()) {
48 // When performing a dst read we handle coverage in the base class.
49 SkASSERT(!(flags & GrXferProcessor::kIgnoreCoverage_OptFlag));
ethannicholasde4166a2015-11-30 08:57:38 -080050 if (optimizations.fCoveragePOI.isSolidWhite()) {
cdaltonedbb31f2015-06-08 12:14:44 -070051 flags |= GrXferProcessor::kIgnoreCoverage_OptFlag;
52 }
53 }
egdanielc19cdc22015-05-10 08:45:18 -070054 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
55 fReadsCoverage = false;
56 }
57 return flags;
58}
59
cdaltonedbb31f2015-06-08 12:14:44 -070060bool GrXferProcessor::hasSecondaryOutput() const {
61 if (!this->willReadDstColor()) {
62 return this->onHasSecondaryOutput();
63 }
cdalton86ae0a92015-06-08 15:11:04 -070064 return this->dstReadUsesMixedSamples();
cdaltonedbb31f2015-06-08 12:14:44 -070065}
66
67void GrXferProcessor::getBlendInfo(BlendInfo* blendInfo) const {
68 blendInfo->reset();
69 if (!this->willReadDstColor()) {
70 this->onGetBlendInfo(blendInfo);
cdalton86ae0a92015-06-08 15:11:04 -070071 } else if (this->dstReadUsesMixedSamples()) {
72 blendInfo->fDstBlend = kIS2A_GrBlendCoeff;
cdaltonedbb31f2015-06-08 12:14:44 -070073 }
74}
75
egdaniel57d3b032015-11-13 11:57:27 -080076void GrXferProcessor::getGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
bsalomon50785a32015-02-06 07:02:37 -080077 uint32_t key = this->willReadDstColor() ? 0x1 : 0x0;
cdaltonedbb31f2015-06-08 12:14:44 -070078 if (key) {
cdalton827bae12015-06-08 13:43:33 -070079 if (const GrTexture* dstTexture = this->getDstTexture()) {
cdaltonedbb31f2015-06-08 12:14:44 -070080 key |= 0x2;
cdalton827bae12015-06-08 13:43:33 -070081 if (kTopLeft_GrSurfaceOrigin == dstTexture->origin()) {
82 key |= 0x4;
83 }
cdaltonedbb31f2015-06-08 12:14:44 -070084 }
85 if (this->readsCoverage()) {
86 key |= 0x8;
87 }
cdalton86ae0a92015-06-08 15:11:04 -070088 if (this->dstReadUsesMixedSamples()) {
89 key |= 0x10;
90 }
bsalomon50785a32015-02-06 07:02:37 -080091 }
92 b->add32(key);
egdaniel57d3b032015-11-13 11:57:27 -080093 this->onGetGLSLProcessorKey(caps, b);
bsalomon50785a32015-02-06 07:02:37 -080094}
95
bsalomoncb02b382015-08-12 11:14:50 -070096GrXferBarrierType GrXferProcessor::xferBarrierType(const GrRenderTarget* rt,
97 const GrCaps& caps) const {
98 SkASSERT(rt);
bsalomon6a44c6a2015-05-26 09:49:05 -070099 if (static_cast<const GrSurface*>(rt) == this->getDstTexture()) {
cdalton9954bc32015-04-29 14:17:00 -0700100 // Texture barriers are required when a shader reads and renders to the same texture.
cdalton9954bc32015-04-29 14:17:00 -0700101 SkASSERT(caps.textureBarrierSupport());
bsalomoncb02b382015-08-12 11:14:50 -0700102 return kTexture_GrXferBarrierType;
cdalton9954bc32015-04-29 14:17:00 -0700103 }
bsalomoncb02b382015-08-12 11:14:50 -0700104 return this->onXferBarrier(rt, caps);
cdalton9954bc32015-04-29 14:17:00 -0700105}
106
bsalomonf7cc8772015-05-11 11:21:14 -0700107#ifdef SK_DEBUG
108static const char* equation_string(GrBlendEquation eq) {
109 switch (eq) {
110 case kAdd_GrBlendEquation:
111 return "add";
112 case kSubtract_GrBlendEquation:
113 return "subtract";
114 case kReverseSubtract_GrBlendEquation:
115 return "reverse_subtract";
116 case kScreen_GrBlendEquation:
117 return "screen";
118 case kOverlay_GrBlendEquation:
119 return "overlay";
120 case kDarken_GrBlendEquation:
121 return "darken";
122 case kLighten_GrBlendEquation:
123 return "lighten";
124 case kColorDodge_GrBlendEquation:
125 return "color_dodge";
126 case kColorBurn_GrBlendEquation:
127 return "color_burn";
128 case kHardLight_GrBlendEquation:
129 return "hard_light";
130 case kSoftLight_GrBlendEquation:
131 return "soft_light";
132 case kDifference_GrBlendEquation:
133 return "difference";
134 case kExclusion_GrBlendEquation:
135 return "exclusion";
136 case kMultiply_GrBlendEquation:
137 return "multiply";
138 case kHSLHue_GrBlendEquation:
139 return "hsl_hue";
140 case kHSLSaturation_GrBlendEquation:
141 return "hsl_saturation";
142 case kHSLColor_GrBlendEquation:
143 return "hsl_color";
144 case kHSLLuminosity_GrBlendEquation:
145 return "hsl_luminosity";
146 };
147 return "";
148}
149
150static const char* coeff_string(GrBlendCoeff coeff) {
151 switch (coeff) {
152 case kZero_GrBlendCoeff:
153 return "zero";
154 case kOne_GrBlendCoeff:
155 return "one";
156 case kSC_GrBlendCoeff:
157 return "src_color";
158 case kISC_GrBlendCoeff:
159 return "inv_src_color";
160 case kDC_GrBlendCoeff:
161 return "dst_color";
162 case kIDC_GrBlendCoeff:
163 return "inv_dst_color";
164 case kSA_GrBlendCoeff:
165 return "src_alpha";
166 case kISA_GrBlendCoeff:
167 return "inv_src_alpha";
168 case kDA_GrBlendCoeff:
169 return "dst_alpha";
170 case kIDA_GrBlendCoeff:
171 return "inv_dst_alpha";
172 case kConstC_GrBlendCoeff:
173 return "const_color";
174 case kIConstC_GrBlendCoeff:
175 return "inv_const_color";
176 case kConstA_GrBlendCoeff:
177 return "const_alpha";
178 case kIConstA_GrBlendCoeff:
179 return "inv_const_alpha";
180 case kS2C_GrBlendCoeff:
181 return "src2_color";
182 case kIS2C_GrBlendCoeff:
183 return "inv_src2_color";
184 case kS2A_GrBlendCoeff:
185 return "src2_alpha";
186 case kIS2A_GrBlendCoeff:
187 return "inv_src2_alpha";
188 }
189 return "";
190}
191
192SkString GrXferProcessor::BlendInfo::dump() const {
193 SkString out;
194 out.printf("write_color(%d) equation(%s) src_coeff(%s) dst_coeff:(%s) const(0x%08x)",
195 fWriteColor, equation_string(fEquation), coeff_string(fSrcBlend),
196 coeff_string(fDstBlend), fBlendConstant);
197 return out;
198}
199#endif
200
bsalomon50785a32015-02-06 07:02:37 -0800201///////////////////////////////////////////////////////////////////////////////
202
ethannicholasde4166a2015-11-30 08:57:38 -0800203GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineOptimizations& optimizations,
cdalton86ae0a92015-06-08 15:11:04 -0700204 bool hasMixedSamples,
bsalomon6a44c6a2015-05-26 09:49:05 -0700205 const DstTexture* dstTexture,
bsalomon4b91f762015-05-19 09:29:46 -0700206 const GrCaps& caps) const {
bsalomon50785a32015-02-06 07:02:37 -0800207#ifdef SK_DEBUG
ethannicholasde4166a2015-11-30 08:57:38 -0800208 if (this->willReadDstColor(caps, optimizations, hasMixedSamples)) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700209 if (!caps.shaderCaps()->dstReadInShaderSupport()) {
bsalomon6a44c6a2015-05-26 09:49:05 -0700210 SkASSERT(dstTexture && dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800211 } else {
bsalomon6a44c6a2015-05-26 09:49:05 -0700212 SkASSERT(!dstTexture || !dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800213 }
214 } else {
bsalomon6a44c6a2015-05-26 09:49:05 -0700215 SkASSERT(!dstTexture || !dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800216 }
cdalton86ae0a92015-06-08 15:11:04 -0700217 SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport());
bsalomon50785a32015-02-06 07:02:37 -0800218#endif
ethannicholasde4166a2015-11-30 08:57:38 -0800219 return this->onCreateXferProcessor(caps, optimizations, hasMixedSamples, dstTexture);
bsalomon50785a32015-02-06 07:02:37 -0800220}
221
cdalton86ae0a92015-06-08 15:11:04 -0700222bool GrXPFactory::willNeedDstTexture(const GrCaps& caps,
ethannicholasde4166a2015-11-30 08:57:38 -0800223 const GrPipelineOptimizations& optimizations,
cdalton86ae0a92015-06-08 15:11:04 -0700224 bool hasMixedSamples) const {
ethannicholasde4166a2015-11-30 08:57:38 -0800225 return (this->willReadDstColor(caps, optimizations, hasMixedSamples) &&
cdalton86ae0a92015-06-08 15:11:04 -0700226 !caps.shaderCaps()->dstReadInShaderSupport());
bsalomon50785a32015-02-06 07:02:37 -0800227}