OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #include "GrGLProgramDesc.h" | 7 #include "GrGLProgramDesc.h" |
8 | 8 |
9 #include "GrGLProcessor.h" | 9 #include "GrGLProcessor.h" |
10 #include "GrProcessor.h" | 10 #include "GrProcessor.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 } | 33 } |
34 if (kRGB_GrColorComponentFlags & swizzleComponentMask) { | 34 if (kRGB_GrColorComponentFlags & swizzleComponentMask) { |
35 // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our
semantics that | 35 // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our
semantics that |
36 // alpha-only textures smear alpha across all four channels when rea
d. | 36 // alpha-only textures smear alpha across all four channels when rea
d. |
37 return true; | 37 return true; |
38 } | 38 } |
39 } | 39 } |
40 return false; | 40 return false; |
41 } | 41 } |
42 | 42 |
43 /** | |
44 * The key for an individual coord transform is made up of a matrix type, a prec
ision, and a bit | |
45 * that indicates the source of the input coords. | |
46 */ | |
47 enum { | |
48 kMatrixTypeKeyBits = 1, | |
49 kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1, | |
50 | |
51 kPrecisionBits = 2, | |
52 kPrecisionShift = kMatrixTypeKeyBits, | |
53 | |
54 kPositionCoords_Flag = (1 << (kPrecisionShift + kPrecisionBits)), | |
55 kDeviceCoords_Flag = kPositionCoords_Flag + kPositionCoords_Flag, | |
56 | |
57 kTransformKeyBits = kMatrixTypeKeyBits + kPrecisionBits + 2, | |
58 }; | |
59 | |
60 GR_STATIC_ASSERT(kHigh_GrSLPrecision < (1 << kPrecisionBits)); | |
61 | |
62 /** | |
63 * We specialize the vertex code for each of these matrix types. | |
64 */ | |
65 enum MatrixType { | |
66 kNoPersp_MatrixType = 0, | |
67 kGeneral_MatrixType = 1, | |
68 }; | |
69 | |
70 static uint32_t gen_transform_key(const GrPendingFragmentStage& stage, bool useE
xplicitLocalCoords) { | |
71 uint32_t totalKey = 0; | |
72 int numTransforms = stage.processor()->numTransforms(); | |
73 for (int t = 0; t < numTransforms; ++t) { | |
74 uint32_t key = 0; | |
75 if (stage.isPerspectiveCoordTransform(t)) { | |
76 key |= kGeneral_MatrixType; | |
77 } else { | |
78 key |= kNoPersp_MatrixType; | |
79 } | |
80 | |
81 const GrCoordTransform& coordTransform = stage.processor()->coordTransfo
rm(t); | |
82 if (kLocal_GrCoordSet == coordTransform.sourceCoords() && !useExplicitLo
calCoords) { | |
83 key |= kPositionCoords_Flag; | |
84 } else if (kDevice_GrCoordSet == coordTransform.sourceCoords()) { | |
85 key |= kDeviceCoords_Flag; | |
86 } | |
87 | |
88 GR_STATIC_ASSERT(kGrSLPrecisionCount <= (1 << kPrecisionBits)); | |
89 key |= (coordTransform.precision() << kPrecisionShift); | |
90 | |
91 key <<= kTransformKeyBits * t; | |
92 | |
93 SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to
overlap | |
94 totalKey |= key; | |
95 } | |
96 return totalKey; | |
97 } | |
98 | |
99 static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) { | 43 static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) { |
100 uint32_t key = 0; | 44 uint32_t key = 0; |
101 int numTextures = proc.numTextures(); | 45 int numTextures = proc.numTextures(); |
102 for (int t = 0; t < numTextures; ++t) { | 46 for (int t = 0; t < numTextures; ++t) { |
103 const GrTextureAccess& access = proc.textureAccess(t); | 47 const GrTextureAccess& access = proc.textureAccess(t); |
104 uint32_t configComponentMask = GrPixelConfigComponentMask(access.getText
ure()->config()); | 48 uint32_t configComponentMask = GrPixelConfigComponentMask(access.getText
ure()->config()); |
105 if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.s
wizzleMask())) { | 49 if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.s
wizzleMask())) { |
106 key |= 1 << t; | 50 key |= 1 << t; |
107 } | 51 } |
108 } | 52 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState, | 89 bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState, |
146 const GrProgramDesc::DescInfo& descInfo, | 90 const GrProgramDesc::DescInfo& descInfo, |
147 GrGpu::DrawType drawType, | 91 GrGpu::DrawType drawType, |
148 GrGLGpu* gpu, | 92 GrGLGpu* gpu, |
149 GrProgramDesc* desc) { | 93 GrProgramDesc* desc) { |
150 // The descriptor is used as a cache key. Thus when a field of the | 94 // The descriptor is used as a cache key. Thus when a field of the |
151 // descriptor will not affect program generation (because of the attribute | 95 // descriptor will not affect program generation (because of the attribute |
152 // bindings in use or other descriptor field settings) it should be set | 96 // bindings in use or other descriptor field settings) it should be set |
153 // to a canonical value to avoid duplicate programs with different keys. | 97 // to a canonical value to avoid duplicate programs with different keys. |
154 | 98 |
155 bool requiresLocalCoordAttrib = descInfo.fRequiresLocalCoordAttrib; | |
156 | |
157 GR_STATIC_ASSERT(0 == kProcessorKeysOffset % sizeof(uint32_t)); | 99 GR_STATIC_ASSERT(0 == kProcessorKeysOffset % sizeof(uint32_t)); |
158 // Make room for everything up to the effect keys. | 100 // Make room for everything up to the effect keys. |
159 desc->fKey.reset(); | 101 desc->fKey.reset(); |
160 desc->fKey.push_back_n(kProcessorKeysOffset); | 102 desc->fKey.push_back_n(kProcessorKeysOffset); |
161 | 103 |
162 GrProcessorKeyBuilder b(&desc->fKey); | 104 GrProcessorKeyBuilder b(&desc->fKey); |
163 | 105 |
164 const GrPrimitiveProcessor& primProc = *optState.getPrimitiveProcessor(); | 106 const GrPrimitiveProcessor& primProc = *optState.getPrimitiveProcessor(); |
165 primProc.getGLProcessorKey(optState.getBatchTracker(), gpu->glCaps(), &b); | 107 primProc.getGLProcessorKey(optState.getBatchTracker(), gpu->glCaps(), &b); |
166 if (!get_meta_key(primProc, gpu->glCaps(), 0, &b)) { | 108 if (!get_meta_key(primProc, gpu->glCaps(), 0, &b)) { |
167 desc->fKey.reset(); | 109 desc->fKey.reset(); |
168 return false; | 110 return false; |
169 } | 111 } |
170 | 112 |
171 for (int s = 0; s < optState.numFragmentStages(); ++s) { | 113 for (int s = 0; s < optState.numFragmentStages(); ++s) { |
172 const GrPendingFragmentStage& fps = optState.getFragmentStage(s); | 114 const GrPendingFragmentStage& fps = optState.getFragmentStage(s); |
173 const GrFragmentProcessor& fp = *fps.processor(); | 115 const GrFragmentProcessor& fp = *fps.processor(); |
174 fp.getGLProcessorKey(gpu->glCaps(), &b); | 116 fp.getGLProcessorKey(gpu->glCaps(), &b); |
175 if (!get_meta_key(fp, gpu->glCaps(), | 117 if (!get_meta_key(fp, gpu->glCaps(), primProc.getTransformKey(fp.coordTr
ansforms()), &b)) { |
176 gen_transform_key(fps, requiresLocalCoordAttrib), &b))
{ | |
177 desc->fKey.reset(); | 118 desc->fKey.reset(); |
178 return false; | 119 return false; |
179 } | 120 } |
180 } | 121 } |
181 | 122 |
182 const GrXferProcessor& xp = *optState.getXferProcessor(); | 123 const GrXferProcessor& xp = *optState.getXferProcessor(); |
183 xp.getGLProcessorKey(gpu->glCaps(), &b); | 124 xp.getGLProcessorKey(gpu->glCaps(), &b); |
184 if (!get_meta_key(xp, gpu->glCaps(), 0, &b)) { | 125 if (!get_meta_key(xp, gpu->glCaps(), 0, &b)) { |
185 desc->fKey.reset(); | 126 desc->fKey.reset(); |
186 return false; | 127 return false; |
187 } | 128 } |
188 | 129 |
189 // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------
------------------- | 130 // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------
------------------- |
190 // Because header is a pointer into the dynamic array, we can't push any new
data into the key | 131 // Because header is a pointer into the dynamic array, we can't push any new
data into the key |
191 // below here. | 132 // below here. |
192 GLKeyHeader* header = desc->atOffset<GLKeyHeader, kHeaderOffset>(); | 133 GLKeyHeader* header = desc->atOffset<GLKeyHeader, kHeaderOffset>(); |
193 | 134 |
194 // make sure any padding in the header is zeroed. | 135 // make sure any padding in the header is zeroed. |
195 memset(header, 0, kHeaderSize); | 136 memset(header, 0, kHeaderSize); |
196 | 137 |
197 bool isPathRendering = GrGpu::IsPathRenderingDrawType(drawType); | 138 bool isPathRendering = GrGpu::IsPathRenderingDrawType(drawType); |
198 if (gpu->caps()->pathRenderingSupport() && isPathRendering) { | 139 if (gpu->caps()->pathRenderingSupport() && isPathRendering) { |
199 header->fUseNvpr = true; | 140 header->fUseNvpr = true; |
200 SkASSERT(!optState.hasGeometryProcessor()); | |
201 } else { | 141 } else { |
202 header->fUseNvpr = false; | 142 header->fUseNvpr = false; |
203 } | 143 } |
204 | 144 |
205 if (descInfo.fReadsDst) { | 145 if (descInfo.fReadsDst) { |
206 const GrDeviceCoordTexture* dstCopy = optState.getDstCopy(); | 146 const GrDeviceCoordTexture* dstCopy = optState.getDstCopy(); |
207 SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport()); | 147 SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport()); |
208 const GrTexture* dstCopyTexture = NULL; | 148 const GrTexture* dstCopyTexture = NULL; |
209 if (dstCopy) { | 149 if (dstCopy) { |
210 dstCopyTexture = dstCopy->texture(); | 150 dstCopyTexture = dstCopy->texture(); |
(...skipping 11 matching lines...) Expand all Loading... |
222 gpu->glCaps())
; | 162 gpu->glCaps())
; |
223 } else { | 163 } else { |
224 header->fFragPosKey = 0; | 164 header->fFragPosKey = 0; |
225 } | 165 } |
226 | 166 |
227 header->fColorEffectCnt = optState.numColorStages(); | 167 header->fColorEffectCnt = optState.numColorStages(); |
228 header->fCoverageEffectCnt = optState.numCoverageStages(); | 168 header->fCoverageEffectCnt = optState.numCoverageStages(); |
229 desc->finalize(); | 169 desc->finalize(); |
230 return true; | 170 return true; |
231 } | 171 } |
OLD | NEW |