blob: 837e13e2a62ba9b8b54e1d87813f8342d5a14853 [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"
cdaltonedbb31f2015-06-08 12:14:44 -07009#include "GrProcOptInfo.h"
bsalomon50785a32015-02-06 07:02:37 -080010#include "gl/GrGLCaps.h"
11
egdanielc19cdc22015-05-10 08:45:18 -070012GrXferProcessor::GrXferProcessor()
bsalomon6a44c6a2015-05-26 09:49:05 -070013 : fWillReadDstColor(false), fReadsCoverage(true), fDstTextureOffset() {
bsalomon50785a32015-02-06 07:02:37 -080014}
15
bsalomon6a44c6a2015-05-26 09:49:05 -070016GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture, bool willReadDstColor)
bsalomon50785a32015-02-06 07:02:37 -080017 : fWillReadDstColor(willReadDstColor)
egdanielc19cdc22015-05-10 08:45:18 -070018 , fReadsCoverage(true)
bsalomon6a44c6a2015-05-26 09:49:05 -070019 , fDstTextureOffset() {
20 if (dstTexture && dstTexture->texture()) {
cdaltonedbb31f2015-06-08 12:14:44 -070021 SkASSERT(willReadDstColor);
bsalomon6a44c6a2015-05-26 09:49:05 -070022 fDstTexture.reset(dstTexture->texture());
23 fDstTextureOffset = dstTexture->offset();
24 this->addTextureAccess(&fDstTexture);
egdaniel060a52c2015-04-07 07:31:11 -070025 this->setWillReadFragmentPosition();
bsalomon50785a32015-02-06 07:02:37 -080026 }
27}
28
egdanielc19cdc22015-05-10 08:45:18 -070029GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
30 const GrProcOptInfo& coveragePOI,
31 bool doesStencilWrite,
32 GrColor* overrideColor,
bsalomon4b91f762015-05-19 09:29:46 -070033 const GrCaps& caps) {
egdanielc19cdc22015-05-10 08:45:18 -070034 GrXferProcessor::OptFlags flags = this->onGetOptimizations(colorPOI,
35 coveragePOI,
36 doesStencilWrite,
37 overrideColor,
38 caps);
39
cdaltonedbb31f2015-06-08 12:14:44 -070040 if (this->willReadDstColor()) {
41 // When performing a dst read we handle coverage in the base class.
42 SkASSERT(!(flags & GrXferProcessor::kIgnoreCoverage_OptFlag));
43 if (coveragePOI.isSolidWhite()) {
44 flags |= GrXferProcessor::kIgnoreCoverage_OptFlag;
45 }
46 }
egdanielc19cdc22015-05-10 08:45:18 -070047 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
48 fReadsCoverage = false;
49 }
50 return flags;
51}
52
cdaltonedbb31f2015-06-08 12:14:44 -070053bool GrXferProcessor::hasSecondaryOutput() const {
54 if (!this->willReadDstColor()) {
55 return this->onHasSecondaryOutput();
56 }
57 return false;
58}
59
60void GrXferProcessor::getBlendInfo(BlendInfo* blendInfo) const {
61 blendInfo->reset();
62 if (!this->willReadDstColor()) {
63 this->onGetBlendInfo(blendInfo);
64 }
65}
66
jvanverthcfc18862015-04-28 08:48:20 -070067void GrXferProcessor::getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
bsalomon50785a32015-02-06 07:02:37 -080068 uint32_t key = this->willReadDstColor() ? 0x1 : 0x0;
cdaltonedbb31f2015-06-08 12:14:44 -070069 if (key) {
70 if (this->getDstTexture()) {
71 key |= 0x2;
72 }
73 if (kTopLeft_GrSurfaceOrigin == this->getDstTexture()->origin()) {
74 key |= 0x4;
75 }
76 if (this->readsCoverage()) {
77 key |= 0x8;
78 }
bsalomon50785a32015-02-06 07:02:37 -080079 }
80 b->add32(key);
81 this->onGetGLProcessorKey(caps, b);
82}
83
cdalton9954bc32015-04-29 14:17:00 -070084bool GrXferProcessor::willNeedXferBarrier(const GrRenderTarget* rt,
bsalomon4b91f762015-05-19 09:29:46 -070085 const GrCaps& caps,
cdalton9954bc32015-04-29 14:17:00 -070086 GrXferBarrierType* outBarrierType) const {
bsalomon6a44c6a2015-05-26 09:49:05 -070087 if (static_cast<const GrSurface*>(rt) == this->getDstTexture()) {
cdalton9954bc32015-04-29 14:17:00 -070088 // Texture barriers are required when a shader reads and renders to the same texture.
89 SkASSERT(rt);
90 SkASSERT(caps.textureBarrierSupport());
91 *outBarrierType = kTexture_GrXferBarrierType;
92 return true;
93 }
cdalton8917d622015-05-06 13:40:21 -070094 return this->onWillNeedXferBarrier(rt, caps, outBarrierType);
cdalton9954bc32015-04-29 14:17:00 -070095}
96
bsalomonf7cc8772015-05-11 11:21:14 -070097#ifdef SK_DEBUG
98static const char* equation_string(GrBlendEquation eq) {
99 switch (eq) {
100 case kAdd_GrBlendEquation:
101 return "add";
102 case kSubtract_GrBlendEquation:
103 return "subtract";
104 case kReverseSubtract_GrBlendEquation:
105 return "reverse_subtract";
106 case kScreen_GrBlendEquation:
107 return "screen";
108 case kOverlay_GrBlendEquation:
109 return "overlay";
110 case kDarken_GrBlendEquation:
111 return "darken";
112 case kLighten_GrBlendEquation:
113 return "lighten";
114 case kColorDodge_GrBlendEquation:
115 return "color_dodge";
116 case kColorBurn_GrBlendEquation:
117 return "color_burn";
118 case kHardLight_GrBlendEquation:
119 return "hard_light";
120 case kSoftLight_GrBlendEquation:
121 return "soft_light";
122 case kDifference_GrBlendEquation:
123 return "difference";
124 case kExclusion_GrBlendEquation:
125 return "exclusion";
126 case kMultiply_GrBlendEquation:
127 return "multiply";
128 case kHSLHue_GrBlendEquation:
129 return "hsl_hue";
130 case kHSLSaturation_GrBlendEquation:
131 return "hsl_saturation";
132 case kHSLColor_GrBlendEquation:
133 return "hsl_color";
134 case kHSLLuminosity_GrBlendEquation:
135 return "hsl_luminosity";
136 };
137 return "";
138}
139
140static const char* coeff_string(GrBlendCoeff coeff) {
141 switch (coeff) {
142 case kZero_GrBlendCoeff:
143 return "zero";
144 case kOne_GrBlendCoeff:
145 return "one";
146 case kSC_GrBlendCoeff:
147 return "src_color";
148 case kISC_GrBlendCoeff:
149 return "inv_src_color";
150 case kDC_GrBlendCoeff:
151 return "dst_color";
152 case kIDC_GrBlendCoeff:
153 return "inv_dst_color";
154 case kSA_GrBlendCoeff:
155 return "src_alpha";
156 case kISA_GrBlendCoeff:
157 return "inv_src_alpha";
158 case kDA_GrBlendCoeff:
159 return "dst_alpha";
160 case kIDA_GrBlendCoeff:
161 return "inv_dst_alpha";
162 case kConstC_GrBlendCoeff:
163 return "const_color";
164 case kIConstC_GrBlendCoeff:
165 return "inv_const_color";
166 case kConstA_GrBlendCoeff:
167 return "const_alpha";
168 case kIConstA_GrBlendCoeff:
169 return "inv_const_alpha";
170 case kS2C_GrBlendCoeff:
171 return "src2_color";
172 case kIS2C_GrBlendCoeff:
173 return "inv_src2_color";
174 case kS2A_GrBlendCoeff:
175 return "src2_alpha";
176 case kIS2A_GrBlendCoeff:
177 return "inv_src2_alpha";
178 }
179 return "";
180}
181
182SkString GrXferProcessor::BlendInfo::dump() const {
183 SkString out;
184 out.printf("write_color(%d) equation(%s) src_coeff(%s) dst_coeff:(%s) const(0x%08x)",
185 fWriteColor, equation_string(fEquation), coeff_string(fSrcBlend),
186 coeff_string(fDstBlend), fBlendConstant);
187 return out;
188}
189#endif
190
bsalomon50785a32015-02-06 07:02:37 -0800191///////////////////////////////////////////////////////////////////////////////
192
193GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI,
194 const GrProcOptInfo& coveragePOI,
bsalomon6a44c6a2015-05-26 09:49:05 -0700195 const DstTexture* dstTexture,
bsalomon4b91f762015-05-19 09:29:46 -0700196 const GrCaps& caps) const {
bsalomon50785a32015-02-06 07:02:37 -0800197#ifdef SK_DEBUG
egdaniel3ad65702015-02-17 11:15:47 -0800198 if (this->willReadDstColor(caps, colorPOI, coveragePOI)) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700199 if (!caps.shaderCaps()->dstReadInShaderSupport()) {
bsalomon6a44c6a2015-05-26 09:49:05 -0700200 SkASSERT(dstTexture && dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800201 } else {
bsalomon6a44c6a2015-05-26 09:49:05 -0700202 SkASSERT(!dstTexture || !dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800203 }
204 } else {
bsalomon6a44c6a2015-05-26 09:49:05 -0700205 SkASSERT(!dstTexture || !dstTexture->texture());
bsalomon50785a32015-02-06 07:02:37 -0800206 }
207#endif
bsalomon6a44c6a2015-05-26 09:49:05 -0700208 return this->onCreateXferProcessor(caps, colorPOI, coveragePOI, dstTexture);
bsalomon50785a32015-02-06 07:02:37 -0800209}
210
bsalomon6a44c6a2015-05-26 09:49:05 -0700211bool GrXPFactory::willNeedDstTexture(const GrCaps& caps, const GrProcOptInfo& colorPOI,
212 const GrProcOptInfo& coveragePOI) const {
jvanverthe9c0fc62015-04-29 11:18:05 -0700213 return (this->willReadDstColor(caps, colorPOI, coveragePOI)
214 && !caps.shaderCaps()->dstReadInShaderSupport());
bsalomon50785a32015-02-06 07:02:37 -0800215}