Index: src/gpu/gl/builders/GrGLShaderBuilder.h |
diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.h b/src/gpu/gl/builders/GrGLShaderBuilder.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1d0fa6a7906d9d01b902b94895d501b9ee5f6617 |
--- /dev/null |
+++ b/src/gpu/gl/builders/GrGLShaderBuilder.h |
@@ -0,0 +1,170 @@ |
+/* |
+ * Copyright 2014 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#ifndef GrGLShaderBuilder_DEFINED |
+#define GrGLShaderBuilder_DEFINED |
+ |
+#include "gl/GrGLProgramDesc.h" |
+#include "gl/GrGLProgramEffects.h" |
+#include "gl/GrGLSL.h" |
+#include "gl/GrGLProgramDataManager.h" |
+#include "GrAllocator.h" |
+#include "GrBackendEffectFactory.h" |
+#include "GrColor.h" |
+#include "GrEffect.h" |
+#include "SkTypes.h" |
+ |
+#include <stdarg.h> |
+ |
+class GrGLContextInfo; |
+class GrEffectStage; |
+class GrGLProgramDesc; |
+class GrGLProgramBuilder; |
+class GrGLFullProgramBuilder; |
+ |
+/** |
+ base class for all shaders builders |
+*/ |
+class GrGLShaderBuilder { |
+public: |
+ typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray; |
+ typedef GrGLProgramEffects::TextureSampler TextureSampler; |
+ GrGLShaderBuilder(GrGLProgramBuilder* program); |
+ |
+ void addInput(GrGLShaderVar i) { fInputs.push_back(i); } |
+ void addOutput(GrGLShaderVar i) { fOutputs.push_back(i); } |
+ |
+ /* |
+ * We put texture lookups in the base class because it is TECHNICALLY possible to do texture |
+ * lookups in any kind of shader. However, for the time being using these calls on non-fragment |
+ * shaders will result in a shader compilation error as texture sampler uniforms are only |
+ * visible to the fragment shader. It would not be hard to change this behavior, if someone |
+ * actually wants to do texture lookups in a non-fragment shader |
+ * |
+ * TODO if append texture lookup is used on a non-fragment shader, sampler uniforms should be |
+ * made visible to that shaders |
+ */ |
+ /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or |
+ Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle |
+ order of the result depends on the GrTextureAccess associated with the TextureSampler. */ |
+ void appendTextureLookup(SkString* out, |
+ const TextureSampler&, |
+ const char* coordName, |
+ GrSLType coordType = kVec2f_GrSLType) const; |
+ |
+ /** Version of above that appends the result to the fragment shader code instead.*/ |
+ void appendTextureLookup(const TextureSampler&, |
+ const char* coordName, |
+ GrSLType coordType = kVec2f_GrSLType); |
+ |
+ |
+ /** Does the work of appendTextureLookup and modulates the result by modulation. The result is |
+ always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or |
+ float. If modulation is "" or NULL it this function acts as though appendTextureLookup were |
+ called. */ |
+ void appendTextureLookupAndModulate(const char* modulation, |
+ const TextureSampler&, |
+ const char* coordName, |
+ GrSLType coordType = kVec2f_GrSLType); |
+ |
+ /** If texture swizzling is available using tex parameters then it is preferred over mangling |
+ the generated shader code. This potentially allows greater reuse of cached shaders. */ |
+ static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps); |
+ |
+ /** |
+ * Called by GrGLEffects to add code to one of the shaders. |
+ */ |
+ void codeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { |
+ va_list args; |
+ va_start(args, format); |
+ fCode.appendVAList(format, args); |
+ va_end(args); |
+ } |
+ |
+ void codeAppend(const char* str) { fCode.append(str); } |
+ |
+ void codePrependf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { |
+ va_list args; |
+ va_start(args, format); |
+ fCode.prependVAList(format, args); |
+ va_end(args); |
+ } |
+ |
+ /** Emits a helper function outside of main() in the fragment shader. */ |
+ void emitFunction(GrSLType returnType, |
+ const char* name, |
+ int argCnt, |
+ const GrGLShaderVar* args, |
+ const char* body, |
+ SkString* outName); |
+ |
+ /* |
+ * Get parent builder for adding uniforms |
+ */ |
+ GrGLProgramBuilder* getProgramBuilder() { return fProgramBuilder; } |
+ |
+ /** |
+ * Helper for begining and ending a block in the fragment code. |
+ */ |
+ class ShaderBlock { |
+ public: |
+ ShaderBlock(GrGLShaderBuilder* builder) : fBuilder(builder) { |
+ SkASSERT(NULL != builder); |
+ fBuilder->codeAppend("{"); |
+ } |
+ |
+ ~ShaderBlock() { |
+ fBuilder->codeAppend("}"); |
+ } |
+ private: |
+ GrGLShaderBuilder* fBuilder; |
+ }; |
+protected: |
+ |
+ /* |
+ * this super low level function is just for use internally to builders |
+ */ |
+ void appendTextureLookup(const char* samplerName, |
+ const char* coordName, |
+ uint32_t configComponentMask, |
+ const char* swizzle); |
+ |
+ /* |
+ * A general function which enables an extension in a shader if the feature bit is not present |
+ */ |
+ void addFeature(uint32_t featureBit, const char* extensionName); |
+ |
+ typedef GrTAllocator<GrGLShaderVar> VarArray; |
+ |
+ GrGLProgramBuilder* fProgramBuilder; |
+ |
+ SkString fCode; |
+ SkString fFunctions; |
+ SkString fExtensions; |
+ |
+ VarArray fInputs; |
+ VarArray fOutputs; |
+ uint32_t fFeaturesAddedMask; |
+}; |
+ |
+ |
+/* |
+ * Full Shader builder is the base class for shaders which are only accessible through full program |
+ * builder, ie vertex, geometry, and later TCU / TES. Using this base class, they can access the |
+ * full program builder functionality through the full program pointer |
+ */ |
+class GrGLFullShaderBuilder : public GrGLShaderBuilder { |
+public: |
+ GrGLFullShaderBuilder(GrGLFullProgramBuilder* program); |
+ |
+ GrGLFullProgramBuilder* fullProgramBuilder() { return fFullProgramBuilder; } |
+protected: |
+ GrGLFullProgramBuilder* fFullProgramBuilder; |
+private: |
+ typedef GrGLShaderBuilder INHERITED; |
+}; |
+#endif |