Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(362)

Side by Side Diff: src/gpu/gl/builders/GrGLProgramBuilder.h

Issue 1416423003: Make GrGLSLProgramBuilder base class for ProgramBuilder (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: nit Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 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 7
8 #ifndef GrGLProgramBuilder_DEFINED 8 #ifndef GrGLProgramBuilder_DEFINED
9 #define GrGLProgramBuilder_DEFINED 9 #define GrGLProgramBuilder_DEFINED
10 10
11 #include "GrGLFragmentShaderBuilder.h"
12 #include "GrGLGeometryShaderBuilder.h"
13 #include "GrGLVertexShaderBuilder.h"
14 #include "gl/GrGLProgramDataManager.h" 11 #include "gl/GrGLProgramDataManager.h"
12 #include "glsl/GrGLSLProgramBuilder.h"
15 #include "glsl/GrGLSLProgramDataManager.h" 13 #include "glsl/GrGLSLProgramDataManager.h"
16 #include "glsl/GrGLSLTextureSampler.h" 14 #include "glsl/GrGLSLTextureSampler.h"
17 #include "../GrGLPrimitiveProcessor.h" 15 #include "../GrGLPrimitiveProcessor.h"
18 #include "../GrGLXferProcessor.h" 16 #include "../GrGLXferProcessor.h"
19 #include "../../GrPipeline.h" 17 #include "../../GrPipeline.h"
20 18
21 class GrFragmentProcessor; 19 class GrFragmentProcessor;
22 class GrGLContextInfo; 20 class GrGLContextInfo;
21 class GrGLShaderBuilder;
23 class GrGLSLCaps; 22 class GrGLSLCaps;
24 23
25 // Enough precision to represent 1 / 2048 accurately in printf 24 // Enough precision to represent 1 / 2048 accurately in printf
26 #define GR_SIGNIFICANT_POW2_DECIMAL_DIG 11 25 #define GR_SIGNIFICANT_POW2_DECIMAL_DIG 11
27 26
28 /*
29 * This is the base class for a series of interfaces. This base class *MUST* re main abstract with
30 * NO data members because it is used in multiple interface inheritance.
31 * Heirarchy:
32 * GrGLUniformBuilder
33 * / \
34 * GrGLFPBuilder GrGLGPBuilder
35 * \ /
36 * GrGLProgramBuilder(internal use only)
37 */
38 class GrGLUniformBuilder {
39 public:
40 enum ShaderVisibility {
41 kVertex_Visibility = 1 << kVertex_GrShaderType,
42 kGeometry_Visibility = 1 << kGeometry_GrShaderType,
43 kFragment_Visibility = 1 << kFragment_GrShaderType,
44 };
45
46 virtual ~GrGLUniformBuilder() {}
47
48 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
49 typedef GrGLSLProgramDataManager::SeparableVaryingHandle SeparableVaryingHan dle;
50
51 /** Add a uniform variable to the current program, that has visibility in on e or more shaders.
52 visibility is a bitfield of ShaderVisibility values indicating from whic h shaders the
53 uniform should be accessible. At least one bit must be set. Geometry sha der uniforms are not
54 supported at this time. The actual uniform name will be mangled. If outN ame is not nullptr then
55 it will refer to the final uniform name after return. Use the addUniform Array variant to add
56 an array of uniforms. */
57 UniformHandle addUniform(uint32_t visibility,
58 GrSLType type,
59 GrSLPrecision precision,
60 const char* name,
61 const char** outName = nullptr) {
62 return this->addUniformArray(visibility, type, precision, name, 0, outNa me);
63 }
64
65 virtual UniformHandle addUniformArray(
66 uint32_t visibility,
67 GrSLType type,
68 GrSLPrecision precision,
69 const char* name,
70 int arrayCount,
71 const char** outName = nullptr) {
72 return this->internalAddUniformArray(visibility, type, precision, name, true, arrayCount,
73 outName);
74 }
75
76
77 virtual const GrGLSLShaderVar& getUniformVariable(UniformHandle u) const = 0 ;
78
79 /**
80 * Shortcut for getUniformVariable(u).c_str()
81 */
82 virtual const char* getUniformCStr(UniformHandle u) const = 0;
83
84 virtual const GrGLContextInfo& ctxInfo() const = 0;
85
86 virtual const GrGLSLCaps* glslCaps() const = 0;
87
88 virtual GrGLGpu* gpu() const = 0;
89
90 /*
91 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
92 */
93 private:
94 virtual UniformHandle internalAddUniformArray(
95 uint32_t visibility,
96 GrSLType type,
97 GrSLPrecision precision,
98 const char* name,
99 bool mangleName,
100 int arrayCount,
101 const char** outName) = 0;
102 };
103
104 // TODO move this into GrGLGPBuilder and move them both out of this file
105 class GrGLVarying {
106 public:
107 bool vsVarying() const { return kVertToFrag_Varying == fVarying ||
108 kVertToGeo_Varying == fVarying; }
109 bool fsVarying() const { return kVertToFrag_Varying == fVarying ||
110 kGeoToFrag_Varying == fVarying; }
111 const char* vsOut() const { return fVsOut; }
112 const char* gsIn() const { return fGsIn; }
113 const char* gsOut() const { return fGsOut; }
114 const char* fsIn() const { return fFsIn; }
115 GrSLType type() const { return fType; }
116
117 protected:
118 enum Varying {
119 kVertToFrag_Varying,
120 kVertToGeo_Varying,
121 kGeoToFrag_Varying,
122 };
123
124 GrGLVarying(GrSLType type, Varying varying)
125 : fVarying(varying), fType(type), fVsOut(nullptr), fGsIn(nullptr), fGsOu t(nullptr),
126 fFsIn(nullptr) {}
127
128 Varying fVarying;
129
130 private:
131 GrSLType fType;
132 const char* fVsOut;
133 const char* fGsIn;
134 const char* fGsOut;
135 const char* fFsIn;
136
137 friend class GrGLVertexBuilder;
138 friend class GrGLGeometryBuilder;
139 friend class GrGLXferBuilder;
140 friend class GrGLFragmentShaderBuilder;
141 };
142
143 struct GrGLVertToFrag : public GrGLVarying {
144 GrGLVertToFrag(GrSLType type)
145 : GrGLVarying(type, kVertToFrag_Varying) {}
146 };
147
148 struct GrGLVertToGeo : public GrGLVarying {
149 GrGLVertToGeo(GrSLType type)
150 : GrGLVarying(type, kVertToGeo_Varying) {}
151 };
152
153 struct GrGLGeoToFrag : public GrGLVarying {
154 GrGLGeoToFrag(GrSLType type)
155 : GrGLVarying(type, kGeoToFrag_Varying) {}
156 };
157
158 /* a specialization of the above for GPs. Lets the user add uniforms, varyings, and VS / FS code */
159 class GrGLGPBuilder : public virtual GrGLUniformBuilder {
160 public:
161 /*
162 * addVarying allows fine grained control for setting up varyings between st ages. If you just
163 * need to take an attribute and pass it through to an output value in a fra gment shader, use
164 * addPassThroughAttribute.
165 * TODO convert most uses of addVarying to addPassThroughAttribute
166 */
167 virtual void addVarying(const char* name,
168 GrGLVarying*,
169 GrSLPrecision precision = kDefault_GrSLPrecision) = 0;
170
171 /*
172 * This call can be used by GP to pass an attribute through all shaders dire ctly to 'output' in
173 * the fragment shader. Though this call effects both the vertex shader and fragment shader,
174 * it expects 'output' to be defined in the fragment shader before this call is made.
175 * TODO it might be nicer behavior to have a flag to declare output inside t his call
176 */
177 virtual void addPassThroughAttribute(const GrGeometryProcessor::Attribute*,
178 const char* output) = 0;
179
180 /*
181 * Creates a fragment shader varying that can be referred to.
182 * Comparable to GrGLUniformBuilder::addUniform().
183 */
184 virtual SeparableVaryingHandle addSeparableVarying(
185 const char* name, GrGLVertToFrag*, GrSLPrecision fsPrecision = kDefault_ GrSLPrecision) = 0;
186
187 // TODO rename getFragmentBuilder
188 virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0;
189 virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0;
190
191 /*
192 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
193 */
194 };
195
196 /* a specializations for FPs. Lets the user add uniforms and FS code */
197 class GrGLFPBuilder : public virtual GrGLUniformBuilder {
198 public:
199 virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0;
200
201 /*
202 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
203 */
204 };
205
206 /* a specializations for XPs. Lets the user add uniforms and FS code */
207 class GrGLXPBuilder : public virtual GrGLUniformBuilder {
208 public:
209 virtual GrGLXPFragmentBuilder* getFragmentShaderBuilder() = 0;
210
211 /*
212 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
213 */
214 };
215
216 /** 27 /**
217 * The below struct represent processors installed in programs. 28 * The below struct represent processors installed in programs.
218 */ 29 */
219 template <class Proc> 30 template <class Proc>
220 struct GrGLInstalledProc { 31 struct GrGLInstalledProc {
221 SkDEBUGCODE(int fSamplersIdx;) 32 SkDEBUGCODE(int fSamplersIdx;)
222 SkAutoTDelete<Proc> fGLProc; 33 SkAutoTDelete<Proc> fGLProc;
223 }; 34 };
224 35
225 typedef GrGLInstalledProc<GrGLPrimitiveProcessor> GrGLInstalledGeoProc; 36 typedef GrGLInstalledProc<GrGLPrimitiveProcessor> GrGLInstalledGeoProc;
226 typedef GrGLInstalledProc<GrGLXferProcessor> GrGLInstalledXferProc; 37 typedef GrGLInstalledProc<GrGLXferProcessor> GrGLInstalledXferProc;
227 typedef GrGLInstalledProc<GrGLFragmentProcessor> GrGLInstalledFragProc; 38 typedef GrGLInstalledProc<GrGLFragmentProcessor> GrGLInstalledFragProc;
228 39
229 struct GrGLInstalledFragProcs : public SkRefCnt { 40 struct GrGLInstalledFragProcs : public SkRefCnt {
230 virtual ~GrGLInstalledFragProcs(); 41 virtual ~GrGLInstalledFragProcs();
231 SkSTArray<8, GrGLInstalledFragProc*, true> fProcs; 42 SkSTArray<8, GrGLInstalledFragProc*, true> fProcs;
232 }; 43 };
233 44
234 /* 45 /*
235 * Please note - no diamond problems because of virtual inheritance. Also, both base classes 46 * Please note - no diamond problems because of virtual inheritance. Also, both base classes
236 * are pure virtual with no data members. This is the base class for program bu ilding. 47 * are pure virtual with no data members. This is the base class for program bu ilding.
237 * Subclasses are nearly identical but each has their own way of emitting transf orms. State for 48 * Subclasses are nearly identical but each has their own way of emitting transf orms. State for
238 * each of the elements of the shader pipeline, ie vertex, fragment, geometry, e tc, lives in those 49 * each of the elements of the shader pipeline, ie vertex, fragment, geometry, e tc, lives in those
239 * respective builders 50 * respective builders
240 */ 51 */
241 class GrGLProgramBuilder : public GrGLGPBuilder, 52 class GrGLProgramBuilder : public GrGLSLProgramBuilder {
242 public GrGLFPBuilder,
243 public GrGLXPBuilder {
244 public: 53 public:
245 typedef GrGpu::DrawArgs DrawArgs;
246 /** Generates a shader program. 54 /** Generates a shader program.
247 * 55 *
248 * The program implements what is specified in the stages given as input. 56 * The program implements what is specified in the stages given as input.
249 * After successful generation, the builder result objects are available 57 * After successful generation, the builder result objects are available
250 * to be used. 58 * to be used.
251 * @return true if generation was successful. 59 * @return true if generation was successful.
252 */ 60 */
253 static GrGLProgram* CreateProgram(const DrawArgs&, GrGLGpu*); 61 static GrGLProgram* CreateProgram(const DrawArgs&, GrGLGpu*);
254 62
255 const GrGLSLShaderVar& getUniformVariable(UniformHandle u) const override { 63 const GrGLSLShaderVar& getUniformVariable(UniformHandle u) const override {
256 return fUniforms[u.toIndex()].fVariable; 64 return fUniforms[u.toIndex()].fVariable;
257 } 65 }
258 66
259 const char* getUniformCStr(UniformHandle u) const override { 67 const char* getUniformCStr(UniformHandle u) const override {
260 return this->getUniformVariable(u).c_str(); 68 return this->getUniformVariable(u).c_str();
261 } 69 }
262 70
263 const GrGLContextInfo& ctxInfo() const override;
264
265 const GrGLSLCaps* glslCaps() const override; 71 const GrGLSLCaps* glslCaps() const override;
266 72
267 GrGLGpu* gpu() const override { return fGpu; } 73 GrGLGpu* gpu() const { return fGpu; }
268
269 GrGLXPFragmentBuilder* getFragmentShaderBuilder() override { return &fFS; }
270 GrGLVertexBuilder* getVertexShaderBuilder() override { return &fVS; }
271 74
272 void addVarying( 75 void addVarying(
273 const char* name, 76 const char* name,
274 GrGLVarying*, 77 GrGLSLVarying*,
275 GrSLPrecision precision = kDefault_GrSLPrecision) override; 78 GrSLPrecision precision = kDefault_GrSLPrecision) override;
276 79
277 void addPassThroughAttribute(const GrPrimitiveProcessor::Attribute*, 80 void addPassThroughAttribute(const GrPrimitiveProcessor::Attribute*,
278 const char* output) override; 81 const char* output) override;
279 82
280 SeparableVaryingHandle addSeparableVarying( 83 SeparableVaryingHandle addSeparableVarying(
281 const char* name, 84 const char* name,
282 GrGLVertToFrag*, 85 GrGLSLVertToFrag*,
283 GrSLPrecision fsPrecision = kDefault_GrSLPrecision) override; 86 GrSLPrecision fsPrecision = kDefault_GrSLPrecision) override;
284 87
285 // Handles for program uniforms (other than per-effect uniforms) 88 private:
286 struct BuiltinUniformHandles {
287 UniformHandle fRTAdjustmentUni;
288
289 // We use the render target height to provide a y-down frag coord when s pecifying
290 // origin_upper_left is not supported.
291 UniformHandle fRTHeightUni;
292 };
293
294 protected:
295 typedef GrGLProgramDataManager::UniformInfo UniformInfo; 89 typedef GrGLProgramDataManager::UniformInfo UniformInfo;
296 typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray; 90 typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
297 typedef GrGLProgramDataManager::SeparableVaryingInfo SeparableVaryingInfo; 91 typedef GrGLProgramDataManager::SeparableVaryingInfo SeparableVaryingInfo;
298 typedef GrGLProgramDataManager::SeparableVaryingInfoArray SeparableVaryingIn foArray; 92 typedef GrGLProgramDataManager::SeparableVaryingInfoArray SeparableVaryingIn foArray;
299 93
300 GrGLProgramBuilder(GrGLGpu*, const DrawArgs&); 94 GrGLProgramBuilder(GrGLGpu*, const DrawArgs&);
301 95
302 const GrPrimitiveProcessor& primitiveProcessor() const { return *fArgs.fPrim itiveProcessor; }
303 const GrPipeline& pipeline() const { return *fArgs.fPipeline; }
304 const GrProgramDesc& desc() const { return *fArgs.fDesc; }
305 const GrProgramDesc::KeyHeader& header() const { return fArgs.fDesc->header( ); }
306
307 UniformHandle internalAddUniformArray(uint32_t visibility, 96 UniformHandle internalAddUniformArray(uint32_t visibility,
308 GrSLType type, 97 GrSLType type,
309 GrSLPrecision precision, 98 GrSLPrecision precision,
310 const char* name, 99 const char* name,
311 bool mangleName, 100 bool mangleName,
312 int arrayCount, 101 int arrayCount,
313 const char** outName) override; 102 const char** outName) override;
314 103
315 // Used to add a uniform for frag position without mangling the name of the uniform inside of a
316 // stage.
317 UniformHandle addFragPosUniform(uint32_t visibility,
318 GrSLType type,
319 GrSLPrecision precision,
320 const char* name,
321 const char** outName) {
322 return this->internalAddUniformArray(visibility, type, precision, name, false, 0, outName);
323 }
324
325 // Generates a name for a variable. The generated string will be name prefix ed by the prefix
326 // char (unless the prefix is '\0'). It also will mangle the name to be stag e-specific unless
327 // explicitly asked not to.
328 void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true);
329 // Generates a possibly mangled name for a stage variable and writes it to t he fragment shader. 104 // Generates a possibly mangled name for a stage variable and writes it to t he fragment shader.
330 // If GrGLSLExpr4 has a valid name then it will use that instead 105 // If GrGLSLExpr4 has a valid name then it will use that instead
331 void nameExpression(GrGLSLExpr4*, const char* baseName); 106 void nameExpression(GrGLSLExpr4*, const char* baseName);
332 bool emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage ); 107 bool emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage );
333 void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOu t); 108 void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOu t);
334 void emitAndInstallProc(const GrFragmentProcessor&, 109 void emitAndInstallProc(const GrFragmentProcessor&,
335 int index, 110 int index,
336 const GrGLSLExpr4& input, 111 const GrGLSLExpr4& input,
337 GrGLSLExpr4* output); 112 GrGLSLExpr4* output);
338 113
(...skipping 19 matching lines...) Expand all
358 template <class Proc> 133 template <class Proc>
359 void emitSamplers(const GrProcessor&, 134 void emitSamplers(const GrProcessor&,
360 GrGLSLTextureSampler::TextureSamplerArray* outSamplers, 135 GrGLSLTextureSampler::TextureSamplerArray* outSamplers,
361 GrGLInstalledProc<Proc>*); 136 GrGLInstalledProc<Proc>*);
362 137
363 bool compileAndAttachShaders(GrGLShaderBuilder& shader, 138 bool compileAndAttachShaders(GrGLShaderBuilder& shader,
364 GrGLuint programId, 139 GrGLuint programId,
365 GrGLenum type, 140 GrGLenum type,
366 SkTDArray<GrGLuint>* shaderIds); 141 SkTDArray<GrGLuint>* shaderIds);
367 GrGLProgram* finalize(); 142 GrGLProgram* finalize();
368 virtual void bindProgramResourceLocations(GrGLuint programID); 143 void bindProgramResourceLocations(GrGLuint programID);
369 bool checkLinkStatus(GrGLuint programID); 144 bool checkLinkStatus(GrGLuint programID);
370 virtual void resolveProgramResourceLocations(GrGLuint programID); 145 void resolveProgramResourceLocations(GrGLuint programID);
371 void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs ); 146 void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs );
372 void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs); 147 void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs);
373 148
374 // Subclasses create different programs 149 // Subclasses create different programs
375 virtual GrGLProgram* createProgram(GrGLuint programID); 150 GrGLProgram* createProgram(GrGLuint programID);
376 151
377 void appendUniformDecls(ShaderVisibility, SkString*) const; 152 void onAppendUniformDecls(ShaderVisibility visibility, SkString* out) const override;
378 153
379 // reset is called by program creator between each processor's emit code. I t increments the 154 // reset is called by program creator between each processor's emit code. I t increments the
380 // stage offset for variable name mangling, and also ensures verfication var iables in the 155 // stage offset for variable name mangling, and also ensures verfication var iables in the
381 // fragment shader are cleared. 156 // fragment shader are cleared.
382 void reset() { 157 void reset() {
383 this->addStage(); 158 this->addStage();
384 fFS.reset(); 159 fFS.reset();
385 } 160 }
386 void addStage() { fStageIndex++; } 161 void addStage() { fStageIndex++; }
387 162
388 class AutoStageAdvance { 163 class AutoStageAdvance {
389 public: 164 public:
390 AutoStageAdvance(GrGLProgramBuilder* pb) 165 AutoStageAdvance(GrGLProgramBuilder* pb)
391 : fPB(pb) { 166 : fPB(pb) {
392 fPB->reset(); 167 fPB->reset();
393 // Each output to the fragment processor gets its own code section 168 // Each output to the fragment processor gets its own code section
394 fPB->fFS.nextStage(); 169 fPB->fFS.nextStage();
395 } 170 }
396 ~AutoStageAdvance() {} 171 ~AutoStageAdvance() {}
397 private: 172 private:
398 GrGLProgramBuilder* fPB; 173 GrGLProgramBuilder* fPB;
399 }; 174 };
400 int stageIndex() const { return fStageIndex; }
401
402 const char* rtAdjustment() const { return "rtAdjustment"; }
403
404 // number of each input/output type in a single allocation block, used by ma ny builders
405 static const int kVarsPerBlock;
406
407 BuiltinUniformHandles fUniformHandles;
408 GrGLVertexBuilder fVS;
409 GrGLGeometryBuilder fGS;
410 GrGLFragmentShaderBuilder fFS;
411 int fStageIndex;
412 175
413 GrGLInstalledGeoProc* fGeometryProcessor; 176 GrGLInstalledGeoProc* fGeometryProcessor;
414 GrGLInstalledXferProc* fXferProcessor; 177 GrGLInstalledXferProc* fXferProcessor;
415 SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors; 178 SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
416 179
417 const DrawArgs& fArgs;
418 GrGLGpu* fGpu; 180 GrGLGpu* fGpu;
419 UniformInfoArray fUniforms; 181 UniformInfoArray fUniforms;
420 GrGLPrimitiveProcessor::TransformsIn fCoordTransforms; 182 GrGLPrimitiveProcessor::TransformsIn fCoordTransforms;
421 GrGLPrimitiveProcessor::TransformsOut fOutCoords; 183 GrGLPrimitiveProcessor::TransformsOut fOutCoords;
422 SkTArray<UniformHandle> fSamplerUniforms; 184 SkTArray<UniformHandle> fSamplerUniforms;
423 SeparableVaryingInfoArray fSeparableVaryingInfos; 185 SeparableVaryingInfoArray fSeparableVaryingInfos;
424 186
425 friend class GrGLShaderBuilder; 187 friend class GrGLShaderBuilder;
426 friend class GrGLVertexBuilder; 188 friend class GrGLVertexBuilder;
427 friend class GrGLFragmentShaderBuilder; 189 friend class GrGLFragmentShaderBuilder;
428 friend class GrGLGeometryBuilder; 190 friend class GrGLGeometryBuilder;
191
192 typedef GrGLSLProgramBuilder INHERITED;
429 }; 193 };
430 #endif 194 #endif
OLDNEW
« no previous file with comments | « src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp ('k') | src/gpu/gl/builders/GrGLProgramBuilder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698