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 "builders/GrGLProgramBuilder.h"
13 #include "GrGLContext.h"
14 #include "GrGLProgramDesc.h"
15 #include "GrGLSL.h"
16 #include "GrGLTexture.h"
17 #include "GrGLProgramDataManager.h"
18 
19 #include "SkString.h"
20 #include "SkXfermode.h"
21 
22 class GrGLProcessor;
23 class GrGLInstalledProcessors;
24 class GrGLProgramBuilder;
25 class GrPipeline;
26 
27 /**
28  * This class manages a GPU program and records per-program information.
29  * We can specify the attribute locations so that they are constant
30  * across our shaders. But the driver determines the uniform locations
31  * at link time. We don't need to remember the sampler uniform location
32  * because we will bind a texture slot to it and never change it
33  * Uniforms are program-local so we can't rely on fHWState to hold the
34  * previous uniform state after a program change.
35  */
36 class GrGLProgram : public SkRefCnt {
37 public:
38     SK_DECLARE_INST_COUNT(GrGLProgram)
39 
40     typedef GrGLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
41 
42     virtual ~GrGLProgram();
43 
44     /**
45      * Call to abandon GL objects owned by this program.
46      */
47     void abandon();
48 
getDesc()49     const GrProgramDesc& getDesc() { return fDesc; }
50 
51     /**
52      * Gets the GL program ID for this program.
53      */
programID()54     GrGLuint programID() const { return fProgramID; }
55 
56     /**
57      * We use the RT's size and origin to adjust from Skia device space to OpenGL normalized device
58      * space and to make device space positions have the correct origin for processors that require
59      * them.
60      */
61     struct RenderTargetState {
62         SkISize         fRenderTargetSize;
63         GrSurfaceOrigin fRenderTargetOrigin;
64 
RenderTargetStateRenderTargetState65         RenderTargetState() { this->invalidate(); }
invalidateRenderTargetState66         void invalidate() {
67             fRenderTargetSize.fWidth = -1;
68             fRenderTargetSize.fHeight = -1;
69             fRenderTargetOrigin = (GrSurfaceOrigin) -1;
70         }
71 
72         /**
73          * Gets a vec4 that adjusts the position from Skia device coords to GL's normalized device
74          * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is
75          * applied as such:
76          * pos.x = dot(v.xy, pos.xz)
77          * pos.y = dot(v.zq, pos.yz)
78          */
getRTAdjustmentVecRenderTargetState79         void getRTAdjustmentVec(GrGLfloat* destVec) {
80             destVec[0] = 2.f / fRenderTargetSize.fWidth;
81             destVec[1] = -1.f;
82             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
83                 destVec[2] = -2.f / fRenderTargetSize.fHeight;
84                 destVec[3] = 1.f;
85             } else {
86                 destVec[2] = 2.f / fRenderTargetSize.fHeight;
87                 destVec[3] = -1.f;
88             }
89         }
90     };
91 
92     /**
93      * This function uploads uniforms and calls each GrGLProcessor's setData. It is called before a
94      * draw occurs using the program after the program has already been bound. It also uses the
95      * GrGLGpu object to bind the textures required by the GrGLProcessors. The color and coverage
96      * stages come from GrGLProgramDesc::Build().
97      */
98     void setData(const GrPrimitiveProcessor&, const GrPipeline&, const GrBatchTracker&);
99 
100 protected:
101     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
102     typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
103 
104     GrGLProgram(GrGLGpu*,
105                 const GrProgramDesc&,
106                 const BuiltinUniformHandles&,
107                 GrGLuint programID,
108                 const UniformInfoArray&,
109                 GrGLInstalledGeoProc* geometryProcessor,
110                 GrGLInstalledXferProc* xferProcessor,
111                 GrGLInstalledFragProcs* fragmentProcessors);
112 
113     // Sets the texture units for samplers.
114     void initSamplerUniforms();
115     template <class Proc>
116     void initSamplers(Proc*, int* texUnitIdx);
117 
118     // A templated helper to loop over effects, set the transforms(via subclass) and bind textures
119     void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&);
120     virtual void setTransformData(const GrPrimitiveProcessor&,
121                                   const GrPendingFragmentStage&,
122                                   int index,
123                                   GrGLInstalledFragProc*);
124     template <class Proc>
125     void bindTextures(const Proc*, const GrProcessor&);
126 
127     /*
128      * Legacy NVPR needs a hook here to flush path tex gen settings.
129      * TODO when legacy nvpr is removed, remove this call.
130      */
didSetData()131     virtual void didSetData() {}
132 
133     // Helper for setData() that sets the view matrix and loads the render target height uniform
134     void setRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
135     virtual void onSetRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
136 
137     // these reflect the current values of uniforms (GL uniform values travel with program)
138     RenderTargetState fRenderTargetState;
139     GrColor fColor;
140     uint8_t fCoverage;
141     int fDstCopyTexUnit;
142     BuiltinUniformHandles fBuiltinUniformHandles;
143     GrGLuint fProgramID;
144 
145     // the installed effects
146     SkAutoTDelete<GrGLInstalledGeoProc> fGeometryProcessor;
147     SkAutoTDelete<GrGLInstalledXferProc> fXferProcessor;
148     SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
149 
150     GrProgramDesc fDesc;
151     GrGLGpu* fGpu;
152     GrGLProgramDataManager fProgramDataManager;
153 
154     friend class GrGLProgramBuilder;
155 
156     typedef SkRefCnt INHERITED;
157 };
158 
159 /*
160  * Below are slight specializations of the program object for the different types of programs
161  * The default GrGL programs consist of at the very least a vertex and fragment shader.
162  * Legacy Nvpr only has a fragment shader, 1.3+ Nvpr ignores the vertex shader, but both require
163  * specialized methods for setting transform data. Both types of NVPR also require setting the
164  * projection matrix through a special function call
165  */
166 class GrGLNvprProgram : public GrGLProgram {
167 protected:
168     GrGLNvprProgram(GrGLGpu*,
169                     const GrProgramDesc&,
170                     const BuiltinUniformHandles&,
171                     GrGLuint programID,
172                     const UniformInfoArray&,
173                     GrGLInstalledGeoProc*,
174                     GrGLInstalledXferProc* xferProcessor,
175                     GrGLInstalledFragProcs* fragmentProcessors);
176 
177 private:
178     void didSetData() override;
179     virtual void setTransformData(const GrPrimitiveProcessor&,
180                                   const GrPendingFragmentStage&,
181                                   int index,
182                                   GrGLInstalledFragProc*) override;
183     virtual void onSetRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
184 
185     friend class GrGLNvprProgramBuilder;
186 
187     typedef GrGLProgram INHERITED;
188 };
189 
190 #endif
191