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 "GrProcessor.h" | 9 #include "GrProcessor.h" |
10 #include "GrGLGpu.h" | 10 #include "GrGLGpu.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 /** | 39 /** |
40 * A function which emits a meta key into the key builder. This is required bec
ause shader code may | 40 * A function which emits a meta key into the key builder. This is required bec
ause shader code may |
41 * be dependent on properties of the effect that the effect itself doesn't use | 41 * be dependent on properties of the effect that the effect itself doesn't use |
42 * in its key (e.g. the pixel format of textures used). So we create a meta-key
for | 42 * in its key (e.g. the pixel format of textures used). So we create a meta-key
for |
43 * every effect using this function. It is also responsible for inserting the ef
fect's class ID | 43 * every effect using this function. It is also responsible for inserting the ef
fect's class ID |
44 * which must be different for every GrProcessor subclass. It can fail if an eff
ect uses too many | 44 * which must be different for every GrProcessor subclass. It can fail if an eff
ect uses too many |
45 * transforms, etc, for the space allotted in the meta-key. NOTE, both FPs and
GPs share this | 45 * transforms, etc, for the space allotted in the meta-key. NOTE, both FPs and
GPs share this |
46 * function because it is hairy, though FPs do not have attribs, and GPs do not
have transforms | 46 * function because it is hairy, though FPs do not have attribs, and GPs do not
have transforms |
47 */ | 47 */ |
48 static bool gen_meta_key(const GrProcessor& proc, | 48 static bool gen_meta_key(const GrProcessor& proc, |
49 const GrGLCaps& caps, | 49 const GrGLSLCaps& glslCaps, |
50 uint32_t transformKey, | 50 uint32_t transformKey, |
51 GrProcessorKeyBuilder* b) { | 51 GrProcessorKeyBuilder* b) { |
52 size_t processorKeySize = b->size(); | 52 size_t processorKeySize = b->size(); |
53 uint32_t classID = proc.classID(); | 53 uint32_t classID = proc.classID(); |
54 | 54 |
55 // Currently we allow 16 bits for the class id and the overall processor key
size. | 55 // Currently we allow 16 bits for the class id and the overall processor key
size. |
56 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); | 56 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); |
57 if ((processorKeySize | classID) & kMetaKeyInvalidMask) { | 57 if ((processorKeySize | classID) & kMetaKeyInvalidMask) { |
58 return false; | 58 return false; |
59 } | 59 } |
60 | 60 |
61 add_texture_key(b, proc, *caps.glslCaps()); | 61 add_texture_key(b, proc, glslCaps); |
62 | 62 |
63 uint32_t* key = b->add32n(2); | 63 uint32_t* key = b->add32n(2); |
64 key[0] = (classID << 16) | SkToU32(processorKeySize); | 64 key[0] = (classID << 16) | SkToU32(processorKeySize); |
65 key[1] = transformKey; | 65 key[1] = transformKey; |
66 return true; | 66 return true; |
67 } | 67 } |
68 | 68 |
69 static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc, | 69 static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc, |
70 const GrFragmentProcessor& fp, | 70 const GrFragmentProcessor& fp, |
71 const GrGLCaps& caps, | 71 const GrGLSLCaps& glslCaps, |
72 GrProcessorKeyBuilder* b) { | 72 GrProcessorKeyBuilder* b) { |
73 for (int i = 0; i < fp.numChildProcessors(); ++i) { | 73 for (int i = 0; i < fp.numChildProcessors(); ++i) { |
74 if (!gen_frag_proc_and_meta_keys(primProc, fp.childProcessor(i), caps, b
)) { | 74 if (!gen_frag_proc_and_meta_keys(primProc, fp.childProcessor(i), glslCap
s, b)) { |
75 return false; | 75 return false; |
76 } | 76 } |
77 } | 77 } |
78 | 78 |
79 fp.getGLSLProcessorKey(*caps.glslCaps(), b); | 79 fp.getGLSLProcessorKey(glslCaps, b); |
80 | 80 |
81 //**** use glslCaps here? | 81 return gen_meta_key(fp, glslCaps, primProc.getTransformKey(fp.coordTransform
s(), |
82 return gen_meta_key(fp, caps, primProc.getTransformKey(fp.coordTransforms(), | 82 fp.numTransformsE
xclChildren()), b); |
83 fp.numTransformsExclC
hildren()), b); | |
84 } | 83 } |
85 | 84 |
86 bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc, | 85 bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc, |
87 const GrPrimitiveProcessor& primProc, | 86 const GrPrimitiveProcessor& primProc, |
88 const GrPipeline& pipeline, | 87 const GrPipeline& pipeline, |
89 const GrGLGpu* gpu) { | 88 const GrGLSLCaps& glslCaps) { |
90 // The descriptor is used as a cache key. Thus when a field of the | 89 // The descriptor is used as a cache key. Thus when a field of the |
91 // descriptor will not affect program generation (because of the attribute | 90 // descriptor will not affect program generation (because of the attribute |
92 // bindings in use or other descriptor field settings) it should be set | 91 // bindings in use or other descriptor field settings) it should be set |
93 // to a canonical value to avoid duplicate programs with different keys. | 92 // to a canonical value to avoid duplicate programs with different keys. |
94 | 93 |
95 GrGLProgramDesc* glDesc = (GrGLProgramDesc*) desc; | 94 GrGLProgramDesc* glDesc = (GrGLProgramDesc*) desc; |
96 | 95 |
97 GR_STATIC_ASSERT(0 == kProcessorKeysOffset % sizeof(uint32_t)); | 96 GR_STATIC_ASSERT(0 == kProcessorKeysOffset % sizeof(uint32_t)); |
98 // Make room for everything up to the effect keys. | 97 // Make room for everything up to the effect keys. |
99 glDesc->key().reset(); | 98 glDesc->key().reset(); |
100 glDesc->key().push_back_n(kProcessorKeysOffset); | 99 glDesc->key().push_back_n(kProcessorKeysOffset); |
101 | 100 |
102 GrProcessorKeyBuilder b(&glDesc->key()); | 101 GrProcessorKeyBuilder b(&glDesc->key()); |
103 | 102 |
104 primProc.getGLSLProcessorKey(*gpu->glCaps().glslCaps(), &b); | 103 primProc.getGLSLProcessorKey(glslCaps, &b); |
105 //**** use glslCaps here? | 104 if (!gen_meta_key(primProc, glslCaps, 0, &b)) { |
106 if (!gen_meta_key(primProc, gpu->glCaps(), 0, &b)) { | |
107 glDesc->key().reset(); | 105 glDesc->key().reset(); |
108 return false; | 106 return false; |
109 } | 107 } |
110 | 108 |
111 for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) { | 109 for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) { |
112 const GrFragmentProcessor& fp = pipeline.getFragmentProcessor(i); | 110 const GrFragmentProcessor& fp = pipeline.getFragmentProcessor(i); |
113 if (!gen_frag_proc_and_meta_keys(primProc, fp, gpu->glCaps(), &b)) { | 111 if (!gen_frag_proc_and_meta_keys(primProc, fp, glslCaps, &b)) { |
114 glDesc->key().reset(); | 112 glDesc->key().reset(); |
115 return false; | 113 return false; |
116 } | 114 } |
117 } | 115 } |
118 | 116 |
119 const GrXferProcessor& xp = pipeline.getXferProcessor(); | 117 const GrXferProcessor& xp = pipeline.getXferProcessor(); |
120 xp.getGLSLProcessorKey(*gpu->glCaps().glslCaps(), &b); | 118 xp.getGLSLProcessorKey(glslCaps, &b); |
121 //**** use glslCaps here? | 119 if (!gen_meta_key(xp, glslCaps, 0, &b)) { |
122 if (!gen_meta_key(xp, gpu->glCaps(), 0, &b)) { | |
123 glDesc->key().reset(); | 120 glDesc->key().reset(); |
124 return false; | 121 return false; |
125 } | 122 } |
126 | 123 |
127 // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------
------------------- | 124 // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------
------------------- |
128 // Because header is a pointer into the dynamic array, we can't push any new
data into the key | 125 // Because header is a pointer into the dynamic array, we can't push any new
data into the key |
129 // below here. | 126 // below here. |
130 KeyHeader* header = glDesc->atOffset<KeyHeader, kHeaderOffset>(); | 127 KeyHeader* header = glDesc->atOffset<KeyHeader, kHeaderOffset>(); |
131 | 128 |
132 // make sure any padding in the header is zeroed. | 129 // make sure any padding in the header is zeroed. |
133 memset(header, 0, kHeaderSize); | 130 memset(header, 0, kHeaderSize); |
134 | 131 |
135 if (pipeline.readsFragPosition()) { | 132 if (pipeline.readsFragPosition()) { |
136 header->fFragPosKey = | 133 header->fFragPosKey = |
137 GrGLSLFragmentShaderBuilder::KeyForFragmentPosition(pipeline.get
RenderTarget()); | 134 GrGLSLFragmentShaderBuilder::KeyForFragmentPosition(pipeline.get
RenderTarget()); |
138 } else { | 135 } else { |
139 header->fFragPosKey = 0; | 136 header->fFragPosKey = 0; |
140 } | 137 } |
141 | 138 |
| 139 header->fOutputSwizzle = |
| 140 glslCaps.configOutputSwizzle(pipeline.getRenderTarget()->config()).asKey
(); |
| 141 |
142 if (pipeline.ignoresCoverage()) { | 142 if (pipeline.ignoresCoverage()) { |
143 header->fIgnoresCoverage = 1; | 143 header->fIgnoresCoverage = 1; |
144 } else { | 144 } else { |
145 header->fIgnoresCoverage = 0; | 145 header->fIgnoresCoverage = 0; |
146 } | 146 } |
147 | 147 |
148 header->fSnapVerticesToPixelCenters = pipeline.snapVerticesToPixelCenters(); | 148 header->fSnapVerticesToPixelCenters = pipeline.snapVerticesToPixelCenters(); |
149 header->fColorEffectCnt = pipeline.numColorFragmentProcessors(); | 149 header->fColorEffectCnt = pipeline.numColorFragmentProcessors(); |
150 header->fCoverageEffectCnt = pipeline.numCoverageFragmentProcessors(); | 150 header->fCoverageEffectCnt = pipeline.numCoverageFragmentProcessors(); |
151 glDesc->finalize(); | 151 glDesc->finalize(); |
152 return true; | 152 return true; |
153 } | 153 } |
OLD | NEW |