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