130ba436f04e61d4505fb854d5fc56079636e0788joshualitt/*
230ba436f04e61d4505fb854d5fc56079636e0788joshualitt * Copyright 2014 Google Inc.
330ba436f04e61d4505fb854d5fc56079636e0788joshualitt *
430ba436f04e61d4505fb854d5fc56079636e0788joshualitt * Use of this source code is governed by a BSD-style license that can be
530ba436f04e61d4505fb854d5fc56079636e0788joshualitt * found in the LICENSE file.
630ba436f04e61d4505fb854d5fc56079636e0788joshualitt */
730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
830ba436f04e61d4505fb854d5fc56079636e0788joshualitt#ifndef GrGLShaderBuilder_DEFINED
930ba436f04e61d4505fb854d5fc56079636e0788joshualitt#define GrGLShaderBuilder_DEFINED
1030ba436f04e61d4505fb854d5fc56079636e0788joshualitt
1130ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/GrGLProgramDesc.h"
1230ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/GrGLProgramEffects.h"
1330ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/GrGLSL.h"
1430ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/GrGLProgramDataManager.h"
15b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrBackendProcessorFactory.h"
1630ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "GrColor.h"
17b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrProcessor.h"
1830ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "SkTypes.h"
1930ba436f04e61d4505fb854d5fc56079636e0788joshualitt
2030ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include <stdarg.h>
2130ba436f04e61d4505fb854d5fc56079636e0788joshualitt
2230ba436f04e61d4505fb854d5fc56079636e0788joshualittclass GrGLContextInfo;
23b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrProcessorStage;
2430ba436f04e61d4505fb854d5fc56079636e0788joshualittclass GrGLProgramDesc;
2530ba436f04e61d4505fb854d5fc56079636e0788joshualittclass GrGLProgramBuilder;
2630ba436f04e61d4505fb854d5fc56079636e0788joshualittclass GrGLFullProgramBuilder;
2730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
2830ba436f04e61d4505fb854d5fc56079636e0788joshualitt/**
2930ba436f04e61d4505fb854d5fc56079636e0788joshualitt  base class for all shaders builders
3030ba436f04e61d4505fb854d5fc56079636e0788joshualitt*/
3130ba436f04e61d4505fb854d5fc56079636e0788joshualittclass GrGLShaderBuilder {
3230ba436f04e61d4505fb854d5fc56079636e0788joshualittpublic:
33b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrGLProcessor::TransformedCoordsArray TransformedCoordsArray;
34b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrGLProcessor::TextureSampler TextureSampler;
3530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLShaderBuilder(GrGLProgramBuilder* program);
3630ba436f04e61d4505fb854d5fc56079636e0788joshualitt
3730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void addInput(GrGLShaderVar i) { fInputs.push_back(i); }
3830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void addOutput(GrGLShaderVar i) { fOutputs.push_back(i); }
3930ba436f04e61d4505fb854d5fc56079636e0788joshualitt
4030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    /*
4130ba436f04e61d4505fb854d5fc56079636e0788joshualitt     * We put texture lookups in the base class because it is TECHNICALLY possible to do texture
4230ba436f04e61d4505fb854d5fc56079636e0788joshualitt     * lookups in any kind of shader.  However, for the time being using these calls on non-fragment
4330ba436f04e61d4505fb854d5fc56079636e0788joshualitt     * shaders will result in a shader compilation error as texture sampler uniforms are only
4430ba436f04e61d4505fb854d5fc56079636e0788joshualitt     * visible to the fragment shader.  It would not be hard to change this behavior, if someone
4530ba436f04e61d4505fb854d5fc56079636e0788joshualitt     * actually wants to do texture lookups in a non-fragment shader
4630ba436f04e61d4505fb854d5fc56079636e0788joshualitt     *
4730ba436f04e61d4505fb854d5fc56079636e0788joshualitt     * TODO if append texture lookup is used on a non-fragment shader, sampler uniforms should be
4830ba436f04e61d4505fb854d5fc56079636e0788joshualitt     * made visible to that shaders
4930ba436f04e61d4505fb854d5fc56079636e0788joshualitt     */
5030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
5130ba436f04e61d4505fb854d5fc56079636e0788joshualitt        Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
5230ba436f04e61d4505fb854d5fc56079636e0788joshualitt        order of the result depends on the GrTextureAccess associated with the TextureSampler. */
5330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void appendTextureLookup(SkString* out,
5430ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             const TextureSampler&,
5530ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             const char* coordName,
5630ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             GrSLType coordType = kVec2f_GrSLType) const;
5730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
5830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    /** Version of above that appends the result to the fragment shader code instead.*/
5930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void appendTextureLookup(const TextureSampler&,
6030ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             const char* coordName,
6130ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             GrSLType coordType = kVec2f_GrSLType);
6230ba436f04e61d4505fb854d5fc56079636e0788joshualitt
6330ba436f04e61d4505fb854d5fc56079636e0788joshualitt
6430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
6530ba436f04e61d4505fb854d5fc56079636e0788joshualitt        always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
6630ba436f04e61d4505fb854d5fc56079636e0788joshualitt        float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
6730ba436f04e61d4505fb854d5fc56079636e0788joshualitt        called. */
6830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void appendTextureLookupAndModulate(const char* modulation,
6930ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                        const TextureSampler&,
7030ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                        const char* coordName,
7130ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                        GrSLType coordType = kVec2f_GrSLType);
7230ba436f04e61d4505fb854d5fc56079636e0788joshualitt
7330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    /** If texture swizzling is available using tex parameters then it is preferred over mangling
7430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        the generated shader code. This potentially allows greater reuse of cached shaders. */
7530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
7630ba436f04e61d4505fb854d5fc56079636e0788joshualitt
7730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    /**
78b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    * Called by GrGLProcessors to add code to one of the shaders.
7930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    */
8030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void codeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
8130ba436f04e61d4505fb854d5fc56079636e0788joshualitt       va_list args;
8230ba436f04e61d4505fb854d5fc56079636e0788joshualitt       va_start(args, format);
8330ba436f04e61d4505fb854d5fc56079636e0788joshualitt       fCode.appendVAList(format, args);
8430ba436f04e61d4505fb854d5fc56079636e0788joshualitt       va_end(args);
8530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
8630ba436f04e61d4505fb854d5fc56079636e0788joshualitt
8730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void codeAppend(const char* str) { fCode.append(str); }
8830ba436f04e61d4505fb854d5fc56079636e0788joshualitt
8930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void codePrependf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
9030ba436f04e61d4505fb854d5fc56079636e0788joshualitt       va_list args;
9130ba436f04e61d4505fb854d5fc56079636e0788joshualitt       va_start(args, format);
9230ba436f04e61d4505fb854d5fc56079636e0788joshualitt       fCode.prependVAList(format, args);
9330ba436f04e61d4505fb854d5fc56079636e0788joshualitt       va_end(args);
9430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
9530ba436f04e61d4505fb854d5fc56079636e0788joshualitt
96b2f94d1f4a74f82ea4dd3feb1690ef6d05892afbegdaniel    /**
97b2f94d1f4a74f82ea4dd3feb1690ef6d05892afbegdaniel     * Appends a variable declaration to one of the shaders
98b2f94d1f4a74f82ea4dd3feb1690ef6d05892afbegdaniel     */
99b2f94d1f4a74f82ea4dd3feb1690ef6d05892afbegdaniel    void declAppend(const GrGLShaderVar& var);
100b2f94d1f4a74f82ea4dd3feb1690ef6d05892afbegdaniel
10130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    /** Emits a helper function outside of main() in the fragment shader. */
10230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void emitFunction(GrSLType returnType,
10330ba436f04e61d4505fb854d5fc56079636e0788joshualitt                      const char* name,
10430ba436f04e61d4505fb854d5fc56079636e0788joshualitt                      int argCnt,
10530ba436f04e61d4505fb854d5fc56079636e0788joshualitt                      const GrGLShaderVar* args,
10630ba436f04e61d4505fb854d5fc56079636e0788joshualitt                      const char* body,
10730ba436f04e61d4505fb854d5fc56079636e0788joshualitt                      SkString* outName);
10830ba436f04e61d4505fb854d5fc56079636e0788joshualitt
10930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    /*
11030ba436f04e61d4505fb854d5fc56079636e0788joshualitt     * Get parent builder for adding uniforms
11130ba436f04e61d4505fb854d5fc56079636e0788joshualitt     */
11230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLProgramBuilder* getProgramBuilder() { return fProgramBuilder; }
11330ba436f04e61d4505fb854d5fc56079636e0788joshualitt
11430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    /**
11530ba436f04e61d4505fb854d5fc56079636e0788joshualitt     * Helper for begining and ending a block in the fragment code.
11630ba436f04e61d4505fb854d5fc56079636e0788joshualitt     */
11730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    class ShaderBlock {
11830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    public:
11930ba436f04e61d4505fb854d5fc56079636e0788joshualitt        ShaderBlock(GrGLShaderBuilder* builder) : fBuilder(builder) {
12049f085dddff10473b6ebf832a974288300224e60bsalomon            SkASSERT(builder);
12130ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fBuilder->codeAppend("{");
12230ba436f04e61d4505fb854d5fc56079636e0788joshualitt        }
12330ba436f04e61d4505fb854d5fc56079636e0788joshualitt
12430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        ~ShaderBlock() {
12530ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fBuilder->codeAppend("}");
12630ba436f04e61d4505fb854d5fc56079636e0788joshualitt        }
12730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    private:
12830ba436f04e61d4505fb854d5fc56079636e0788joshualitt        GrGLShaderBuilder* fBuilder;
12930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    };
13030ba436f04e61d4505fb854d5fc56079636e0788joshualittprotected:
13130ba436f04e61d4505fb854d5fc56079636e0788joshualitt
13230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    /*
13330ba436f04e61d4505fb854d5fc56079636e0788joshualitt     * this super low level function is just for use internally to builders
13430ba436f04e61d4505fb854d5fc56079636e0788joshualitt     */
13530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void appendTextureLookup(const char* samplerName,
13630ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             const char* coordName,
13730ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             uint32_t configComponentMask,
13830ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             const char* swizzle);
13930ba436f04e61d4505fb854d5fc56079636e0788joshualitt
14030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    /*
14130ba436f04e61d4505fb854d5fc56079636e0788joshualitt     * A general function which enables an extension in a shader if the feature bit is not present
14230ba436f04e61d4505fb854d5fc56079636e0788joshualitt     */
14330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    void addFeature(uint32_t featureBit, const char* extensionName);
14430ba436f04e61d4505fb854d5fc56079636e0788joshualitt
14530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    typedef GrTAllocator<GrGLShaderVar> VarArray;
14630ba436f04e61d4505fb854d5fc56079636e0788joshualitt
14730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLProgramBuilder* fProgramBuilder;
14830ba436f04e61d4505fb854d5fc56079636e0788joshualitt
14930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkString fCode;
15030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkString fFunctions;
15130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkString fExtensions;
15230ba436f04e61d4505fb854d5fc56079636e0788joshualitt
15330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    VarArray fInputs;
15430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    VarArray fOutputs;
15530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    uint32_t fFeaturesAddedMask;
15630ba436f04e61d4505fb854d5fc56079636e0788joshualitt};
15730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
15830ba436f04e61d4505fb854d5fc56079636e0788joshualitt
15930ba436f04e61d4505fb854d5fc56079636e0788joshualitt/*
16030ba436f04e61d4505fb854d5fc56079636e0788joshualitt * Full Shader builder is the base class for shaders which are only accessible through full program
16130ba436f04e61d4505fb854d5fc56079636e0788joshualitt * builder, ie vertex, geometry, and later TCU / TES.  Using this base class, they can access the
16230ba436f04e61d4505fb854d5fc56079636e0788joshualitt * full program builder functionality through the full program pointer
16330ba436f04e61d4505fb854d5fc56079636e0788joshualitt */
16430ba436f04e61d4505fb854d5fc56079636e0788joshualittclass GrGLFullShaderBuilder : public GrGLShaderBuilder {
16530ba436f04e61d4505fb854d5fc56079636e0788joshualittpublic:
16630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLFullShaderBuilder(GrGLFullProgramBuilder* program);
16730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
16830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLFullProgramBuilder* fullProgramBuilder() { return fFullProgramBuilder; }
16930ba436f04e61d4505fb854d5fc56079636e0788joshualittprotected:
17030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLFullProgramBuilder* fFullProgramBuilder;
17130ba436f04e61d4505fb854d5fc56079636e0788joshualittprivate:
17230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    typedef GrGLShaderBuilder INHERITED;
17330ba436f04e61d4505fb854d5fc56079636e0788joshualitt};
17430ba436f04e61d4505fb854d5fc56079636e0788joshualitt#endif
175