GrGLProgram.h revision 09aa1fce69b214714171db12c341aebd78dd29ea
1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8
9#ifndef GrGLProgram_DEFINED
10#define GrGLProgram_DEFINED
11
12#include "GrGLContext.h"
13#include "GrGLProgramDesc.h"
14#include "GrGLTexture.h"
15#include "GrGLProgramDataManager.h"
16#include "glsl/GrGLSLProgramDataManager.h"
17#include "glsl/GrGLSLUniformHandler.h"
18
19#include "SkString.h"
20#include "SkXfermode.h"
21
22#include "builders/GrGLProgramBuilder.h"
23
24class GrGLInstalledProcessors;
25class GrGLProgramBuilder;
26class GrPipeline;
27
28/**
29 * This class manages a GPU program and records per-program information.
30 * We can specify the attribute locations so that they are constant
31 * across our shaders. But the driver determines the uniform locations
32 * at link time. We don't need to remember the sampler uniform location
33 * because we will bind a texture slot to it and never change it
34 * Uniforms are program-local so we can't rely on fHWState to hold the
35 * previous uniform state after a program change.
36 */
37class GrGLProgram : public SkRefCnt {
38public:
39    typedef GrGLSLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
40
41    ~GrGLProgram();
42
43    /**
44     * Call to abandon GL objects owned by this program.
45     */
46    void abandon();
47
48    const GrProgramDesc& getDesc() { return fDesc; }
49
50    /**
51     * Gets the GL program ID for this program.
52     */
53    GrGLuint programID() const { return fProgramID; }
54
55    /**
56     * We use the RT's size and origin to adjust from Skia device space to OpenGL normalized device
57     * space and to make device space positions have the correct origin for processors that require
58     * them.
59     */
60    struct RenderTargetState {
61        SkISize         fRenderTargetSize;
62        GrSurfaceOrigin fRenderTargetOrigin;
63
64        RenderTargetState() { this->invalidate(); }
65        void invalidate() {
66            fRenderTargetSize.fWidth = -1;
67            fRenderTargetSize.fHeight = -1;
68            fRenderTargetOrigin = (GrSurfaceOrigin) -1;
69        }
70
71        /**
72         * Gets a vec4 that adjusts the position from Skia device coords to GL's normalized device
73         * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is
74         * applied as such:
75         * pos.x = dot(v.xy, pos.xz)
76         * pos.y = dot(v.zw, pos.yz)
77         */
78        void getRTAdjustmentVec(float* destVec) {
79            destVec[0] = 2.f / fRenderTargetSize.fWidth;
80            destVec[1] = -1.f;
81            if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
82                destVec[2] = -2.f / fRenderTargetSize.fHeight;
83                destVec[3] = 1.f;
84            } else {
85                destVec[2] = 2.f / fRenderTargetSize.fHeight;
86                destVec[3] = -1.f;
87            }
88        }
89    };
90
91    /**
92     * This function uploads uniforms, calls each GrGL*Processor's setData, and retrieves the
93     * textures that need to be bound on each unit. It is the caller's responsibility to ensure
94     * the program is bound before calling, and to bind the outgoing textures to their respective
95     * units upon return. (Each index in the array corresponds to its matching GL texture unit.)
96     */
97    void setData(const GrPrimitiveProcessor&, const GrPipeline&);
98
99protected:
100    typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
101    typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
102    typedef GrGLProgramDataManager::VaryingInfoArray VaryingInfoArray;
103
104    GrGLProgram(GrGLGpu*,
105                const GrProgramDesc&,
106                const BuiltinUniformHandles&,
107                GrGLuint programID,
108                const UniformInfoArray&,
109                const SkTArray<GrGLSampler>&,
110                const VaryingInfoArray&, // used for NVPR only currently
111                GrGLSLPrimitiveProcessor* geometryProcessor,
112                GrGLSLXferProcessor* xferProcessor,
113                const GrGLSLFragProcs& fragmentProcessors);
114
115    // A helper to loop over effects, set the transforms (via subclass) and bind textures
116    void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextSamplerIdx);
117    void setTransformData(const GrPrimitiveProcessor&, const GrFragmentProcessor&, int index);
118
119    // Helper for setData() that sets the view matrix and loads the render target height uniform
120    void setRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
121
122    // Helper for setData() that binds textures and texel buffers to the appropriate texture units
123    void bindTextures(const GrProcessor&, bool allowSRGBInputs, int* nextSamplerIdx);
124
125    // these reflect the current values of uniforms (GL uniform values travel with program)
126    RenderTargetState fRenderTargetState;
127    BuiltinUniformHandles fBuiltinUniformHandles;
128    GrGLuint fProgramID;
129
130    // the installed effects
131    SkAutoTDelete<GrGLSLPrimitiveProcessor> fGeometryProcessor;
132    SkAutoTDelete<GrGLSLXferProcessor> fXferProcessor;
133    GrGLSLFragProcs fFragmentProcessors;
134
135    GrProgramDesc fDesc;
136    GrGLGpu* fGpu;
137    GrGLProgramDataManager fProgramDataManager;
138
139    friend class GrGLProgramBuilder;
140
141    typedef SkRefCnt INHERITED;
142};
143
144#endif
145