Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / GrGLProgramDesc.cpp
1 /*
2  * Copyright 2013 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 "gl/builders/GrGLProgramBuilder.h"
9 #include "GrGLProgramDesc.h"
10 #include "GrBackendProcessorFactory.h"
11 #include "GrProcessor.h"
12 #include "GrGpuGL.h"
13 #include "GrOptDrawState.h"
14
15 #include "SkChecksum.h"
16
17 /**
18  * The key for an individual coord transform is made up of a matrix type and a bit that
19  * indicates the source of the input coords.
20  */
21 enum {
22     kMatrixTypeKeyBits   = 1,
23     kMatrixTypeKeyMask   = (1 << kMatrixTypeKeyBits) - 1,
24     kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
25     kTransformKeyBits    = kMatrixTypeKeyBits + 1,
26 };
27
28 /**
29  * We specialize the vertex code for each of these matrix types.
30  */
31 enum MatrixType {
32     kNoPersp_MatrixType  = 0,
33     kGeneral_MatrixType  = 1,
34 };
35
36 /**
37  * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are
38  * present in the texture's config. swizzleComponentMask indicates the channels present in the
39  * shader swizzle.
40  */
41 static bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
42                                              uint32_t configComponentMask,
43                                              uint32_t swizzleComponentMask) {
44     if (caps.textureSwizzleSupport()) {
45         // Any remapping is handled using texture swizzling not shader modifications.
46         return false;
47     }
48     // check if the texture is alpha-only
49     if (kA_GrColorComponentFlag == configComponentMask) {
50         if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) {
51             // we must map the swizzle 'a's to 'r'.
52             return true;
53         }
54         if (kRGB_GrColorComponentFlags & swizzleComponentMask) {
55             // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that
56             // alpha-only textures smear alpha across all four channels when read.
57             return true;
58         }
59     }
60     return false;
61 }
62
63 static uint32_t gen_attrib_key(const GrGeometryProcessor* effect) {
64     uint32_t key = 0;
65
66     const GrGeometryProcessor::VertexAttribArray& vars = effect->getVertexAttribs();
67     int numAttributes = vars.count();
68     SkASSERT(numAttributes <= 2);
69     for (int a = 0; a < numAttributes; ++a) {
70         uint32_t value = 1 << a;
71         key |= value;
72     }
73     return key;
74 }
75
76 static uint32_t gen_transform_key(const GrProcessorStage& effectStage,
77                                   bool useExplicitLocalCoords) {
78     uint32_t totalKey = 0;
79     int numTransforms = effectStage.getProcessor()->numTransforms();
80     for (int t = 0; t < numTransforms; ++t) {
81         uint32_t key = 0;
82         if (effectStage.isPerspectiveCoordTransform(t, useExplicitLocalCoords)) {
83             key |= kGeneral_MatrixType;
84         } else {
85             key |= kNoPersp_MatrixType;
86         }
87
88         const GrCoordTransform& coordTransform = effectStage.getProcessor()->coordTransform(t);
89         if (kLocal_GrCoordSet != coordTransform.sourceCoords() && useExplicitLocalCoords) {
90             key |= kPositionCoords_Flag;
91         }
92         key <<= kTransformKeyBits * t;
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* effect, const GrGLCaps& caps) {
100     uint32_t key = 0;
101     int numTextures = effect->numTextures();
102     for (int t = 0; t < numTextures; ++t) {
103         const GrTextureAccess& access = effect->textureAccess(t);
104         uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
105         if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
106             key |= 1 << t;
107         }
108     }
109     return key;
110 }
111
112 /**
113  * A function which emits a meta key into the key builder.  This is required because shader code may
114  * be dependent on properties of the effect that the effect itself doesn't use
115  * in its key (e.g. the pixel format of textures used). So we create a meta-key for
116  * every effect using this function. It is also responsible for inserting the effect's class ID
117  * which must be different for every GrProcessor subclass. It can fail if an effect uses too many
118  * textures, transforms, etc, for the space allotted in the meta-key.
119  */
120
121 static uint32_t* get_processor_meta_key(const GrProcessorStage& processorStage,
122                                         bool useExplicitLocalCoords,
123                                         const GrGLCaps& caps,
124                                         GrProcessorKeyBuilder* b) {
125
126     uint32_t textureKey = gen_texture_key(processorStage.getProcessor(), caps);
127     uint32_t transformKey = gen_transform_key(processorStage,useExplicitLocalCoords);
128     uint32_t classID = processorStage.getProcessor()->getFactory().effectClassID();
129
130     // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
131     // don't fit.
132     static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
133     if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) {
134         return NULL;
135     }
136
137     uint32_t* key = b->add32n(2);
138     key[0] = (textureKey << 16 | transformKey);
139     key[1] = (classID << 16);
140     return key;
141 }
142
143 bool GrGLProgramDesc::GetProcessorKey(const GrProcessorStage& stage,
144                                       const GrGLCaps& caps,
145                                       bool useExplicitLocalCoords,
146                                       GrProcessorKeyBuilder* b,
147                                       uint16_t* processorKeySize) {
148     const GrProcessor& effect = *stage.getProcessor();
149     const GrBackendProcessorFactory& factory = effect.getFactory();
150     factory.getGLProcessorKey(effect, caps, b);
151     size_t size = b->size();
152     if (size > SK_MaxU16) {
153         *processorKeySize = 0; // suppresses a warning.
154         return false;
155     }
156     *processorKeySize = SkToU16(size);
157     if (NULL == get_processor_meta_key(stage, useExplicitLocalCoords, caps, b)) {
158         return false;
159     }
160     return true;
161 }
162
163 bool GrGLProgramDesc::GetGeometryProcessorKey(const GrGeometryStage& stage,
164                                               const GrGLCaps& caps,
165                                               bool useExplicitLocalCoords,
166                                               GrProcessorKeyBuilder* b,
167                                               uint16_t* processorKeySize) {
168     const GrProcessor& effect = *stage.getProcessor();
169     const GrBackendProcessorFactory& factory = effect.getFactory();
170     factory.getGLProcessorKey(effect, caps, b);
171     size_t size = b->size();
172     if (size > SK_MaxU16) {
173         *processorKeySize = 0; // suppresses a warning.
174         return false;
175     }
176     *processorKeySize = SkToU16(size);
177     uint32_t* key = get_processor_meta_key(stage, useExplicitLocalCoords, caps, b);
178     if (NULL == key) {
179         return false;
180     }
181     uint32_t attribKey = gen_attrib_key(stage.getGeometryProcessor());
182
183     // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
184     // don't fit.
185     static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
186     if ((attribKey) & kMetaKeyInvalidMask) {
187        return false;
188     }
189
190     key[1] |= attribKey;
191     return true;
192 }
193
194
195 bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
196                             GrGpu::DrawType drawType,
197                             GrBlendCoeff srcCoeff,
198                             GrBlendCoeff dstCoeff,
199                             GrGpuGL* gpu,
200                             const GrDeviceCoordTexture* dstCopy,
201                             const GrGeometryStage** geometryProcessor,
202                             SkTArray<const GrFragmentStage*, true>* colorStages,
203                             SkTArray<const GrFragmentStage*, true>* coverageStages,
204                             GrGLProgramDesc* desc) {
205     colorStages->reset();
206     coverageStages->reset();
207
208     bool inputColorIsUsed = optState.inputColorIsUsed();
209     bool inputCoverageIsUsed = optState.inputCoverageIsUsed();
210
211     // The descriptor is used as a cache key. Thus when a field of the
212     // descriptor will not affect program generation (because of the attribute
213     // bindings in use or other descriptor field settings) it should be set
214     // to a canonical value to avoid duplicate programs with different keys.
215
216     bool requiresLocalCoordAttrib = optState.requiresLocalCoordAttrib();
217
218     int numStages = optState.numTotalStages();
219
220     GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t));
221     // Make room for everything up to and including the array of offsets to effect keys.
222     desc->fKey.reset();
223     desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * numStages);
224
225     int offsetAndSizeIndex = 0;
226
227     KeyHeader* header = desc->header();
228     // make sure any padding in the header is zeroed.
229     memset(desc->header(), 0, kHeaderSize);
230
231     // We can only have one effect which touches the vertex shader
232     if (optState.hasGeometryProcessor()) {
233         uint16_t* offsetAndSize =
234                 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
235                                             offsetAndSizeIndex * 2 * sizeof(uint16_t));
236
237         GrProcessorKeyBuilder b(&desc->fKey);
238         uint16_t processorKeySize;
239         uint32_t processorOffset = desc->fKey.count();
240         const GrGeometryStage& gpStage = *optState.getGeometryProcessor();
241         if (processorOffset > SK_MaxU16 ||
242                 !GetGeometryProcessorKey(gpStage, gpu->glCaps(), requiresLocalCoordAttrib, &b,
243                                          &processorKeySize)) {
244             desc->fKey.reset();
245             return false;
246         }
247
248         offsetAndSize[0] = SkToU16(processorOffset);
249         offsetAndSize[1] = processorKeySize;
250         ++offsetAndSizeIndex;
251         *geometryProcessor = &gpStage;
252         header->fHasGeometryProcessor = true;
253     }
254
255     for (int s = 0; s < optState.numColorStages(); ++s) {
256         uint16_t* offsetAndSize =
257             reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
258                                         offsetAndSizeIndex * 2 * sizeof(uint16_t));
259
260         GrProcessorKeyBuilder b(&desc->fKey);
261         uint16_t processorKeySize;
262         uint32_t processorOffset = desc->fKey.count();
263         if (processorOffset > SK_MaxU16 ||
264                 !GetProcessorKey(optState.getColorStage(s), gpu->glCaps(),
265                                  requiresLocalCoordAttrib, &b, &processorKeySize)) {
266             desc->fKey.reset();
267             return false;
268         }
269
270         offsetAndSize[0] = SkToU16(processorOffset);
271         offsetAndSize[1] = processorKeySize;
272         ++offsetAndSizeIndex;
273     }
274
275     for (int s = 0; s < optState.numCoverageStages(); ++s) {
276         uint16_t* offsetAndSize =
277             reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
278                                         offsetAndSizeIndex * 2 * sizeof(uint16_t));
279
280         GrProcessorKeyBuilder b(&desc->fKey);
281         uint16_t processorKeySize;
282         uint32_t processorOffset = desc->fKey.count();
283         if (processorOffset > SK_MaxU16 ||
284                 !GetProcessorKey(optState.getCoverageStage(s), gpu->glCaps(),
285                                  requiresLocalCoordAttrib, &b, &processorKeySize)) {
286             desc->fKey.reset();
287             return false;
288         }
289
290         offsetAndSize[0] = SkToU16(processorOffset);
291         offsetAndSize[1] = processorKeySize;
292         ++offsetAndSizeIndex;
293     }
294
295     // Because header is a pointer into the dynamic array, we can't push any new data into the key
296     // below here.
297
298
299     header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType;
300
301     // Currently the experimental GS will only work with triangle prims (and it doesn't do anything
302     // other than pass through values from the VS to the FS anyway).
303 #if GR_GL_EXPERIMENTAL_GS
304 #if 0
305     header->fExperimentalGS = gpu->caps().geometryShaderSupport();
306 #else
307     header->fExperimentalGS = false;
308 #endif
309 #endif
310
311     if (gpu->caps()->pathRenderingSupport() &&
312         GrGpu::IsPathRenderingDrawType(drawType) &&
313         gpu->glPathRendering()->texturingMode() == GrGLPathRendering::FixedFunction_TexturingMode) {
314         header->fUseFragShaderOnly = true;
315         SkASSERT(!optState.hasGeometryProcessor());
316     } else {
317         header->fUseFragShaderOnly = false;
318     }
319
320     bool defaultToUniformInputs = GrGpu::IsPathRenderingDrawType(drawType) ||
321                                   GR_GL_NO_CONSTANT_ATTRIBUTES;
322
323     if (!inputColorIsUsed) {
324         header->fColorInput = kAllOnes_ColorInput;
325     } else if (defaultToUniformInputs && !optState.hasColorVertexAttribute()) {
326         header->fColorInput = kUniform_ColorInput;
327     } else {
328         header->fColorInput = kAttribute_ColorInput;
329         SkASSERT(!header->fUseFragShaderOnly);
330     }
331
332     bool covIsSolidWhite = !optState.hasCoverageVertexAttribute() &&
333                            0xffffffff == optState.getCoverageColor();
334
335     if (covIsSolidWhite || !inputCoverageIsUsed) {
336         header->fCoverageInput = kAllOnes_ColorInput;
337     } else if (defaultToUniformInputs && !optState.hasCoverageVertexAttribute()) {
338         header->fCoverageInput = kUniform_ColorInput;
339     } else {
340         header->fCoverageInput = kAttribute_ColorInput;
341         SkASSERT(!header->fUseFragShaderOnly);
342     }
343
344     if (optState.readsDst()) {
345         SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport());
346         const GrTexture* dstCopyTexture = NULL;
347         if (dstCopy) {
348             dstCopyTexture = dstCopy->texture();
349         }
350         header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture,
351                 gpu->glCaps());
352         SkASSERT(0 != header->fDstReadKey);
353     } else {
354         header->fDstReadKey = 0;
355     }
356
357     if (optState.readsFragPosition()) {
358         header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition(
359                 optState.getRenderTarget(), gpu->glCaps());
360     } else {
361         header->fFragPosKey = 0;
362     }
363
364     // Record attribute indices
365     header->fPositionAttributeIndex = optState.positionAttributeIndex();
366     header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex();
367
368     // For constant color and coverage we need an attribute with an index beyond those already set
369     int availableAttributeIndex = optState.getVertexAttribCount();
370     if (optState.hasColorVertexAttribute()) {
371         header->fColorAttributeIndex = optState.colorVertexAttributeIndex();
372     } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) {
373         SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
374         header->fColorAttributeIndex = availableAttributeIndex;
375         availableAttributeIndex++;
376     } else {
377         header->fColorAttributeIndex = -1;
378     }
379
380     if (optState.hasCoverageVertexAttribute()) {
381         header->fCoverageAttributeIndex = optState.coverageVertexAttributeIndex();
382     } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) {
383         SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
384         header->fCoverageAttributeIndex = availableAttributeIndex;
385     } else {
386         header->fCoverageAttributeIndex = -1;
387     }
388
389     header->fPrimaryOutputType = optState.getPrimaryOutputType();
390     header->fSecondaryOutputType = optState.getSecondaryOutputType();
391
392     for (int s = 0; s < optState.numColorStages(); ++s) {
393         colorStages->push_back(&optState.getColorStage(s));
394     }
395     for (int s = 0; s < optState.numCoverageStages(); ++s) {
396         coverageStages->push_back(&optState.getCoverageStage(s));
397     }
398
399     header->fColorEffectCnt = colorStages->count();
400     header->fCoverageEffectCnt = coverageStages->count();
401
402     desc->finalize();
403     return true;
404 }
405
406 void GrGLProgramDesc::finalize() {
407     int keyLength = fKey.count();
408     SkASSERT(0 == (keyLength % 4));
409     *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength);
410
411     uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>();
412     *checksum = 0;
413     *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), keyLength);
414 }
415
416 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) {
417     size_t keyLength = other.keyLength();
418     fKey.reset(keyLength);
419     memcpy(fKey.begin(), other.fKey.begin(), keyLength);
420     return *this;
421 }