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 "GrProgramDesc.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 
21 #include "builders/GrGLProgramBuilder.h"
22 
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     typedef GrGLSLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
39 
40     ~GrGLProgram();
41 
42     /**
43      * Call to abandon GL objects owned by this program.
44      */
45     void abandon();
46 
47     const GrProgramDesc& getDesc() { return fDesc; }
48 
49     /**
50      * Gets the GL program ID for this program.
51      */
52     GrGLuint programID() const { return fProgramID; }
53 
54     /**
55      * We use the RT's size and origin to adjust from Skia device space to OpenGL normalized device
56      * space and to make device space positions have the correct origin for processors that require
57      * them.
58      */
59     struct RenderTargetState {
60         SkISize         fRenderTargetSize;
61         GrSurfaceOrigin fRenderTargetOrigin;
62 
63         RenderTargetState() { this->invalidate(); }
64         void invalidate() {
65             fRenderTargetSize.fWidth = -1;
66             fRenderTargetSize.fHeight = -1;
67             fRenderTargetOrigin = (GrSurfaceOrigin) -1;
68         }
69 
70         /**
71          * Gets a float4 that adjusts the position from Skia device coords to GL's normalized device
72          * coords. Assuming the transformed position, pos, is a homogeneous float3, the vec, v, is
73          * applied as such:
74          * pos.x = dot(v.xy, pos.xz)
75          * pos.y = dot(v.zw, pos.yz)
76          */
77         void getRTAdjustmentVec(float* destVec) {
78             destVec[0] = 2.f / fRenderTargetSize.fWidth;
79             destVec[1] = -1.f;
80             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
81                 destVec[2] = -2.f / fRenderTargetSize.fHeight;
82                 destVec[3] = 1.f;
83             } else {
84                 destVec[2] = 2.f / fRenderTargetSize.fHeight;
85                 destVec[3] = -1.f;
86             }
87         }
88     };
89 
90     /**
91      * This function uploads uniforms, calls each GrGL*Processor's setData, and retrieves the
92      * textures that need to be bound on each unit. It is the caller's responsibility to ensure
93      * the program is bound before calling, and to bind the outgoing textures to their respective
94      * units upon return. (Each index in the array corresponds to its matching GL texture unit.)
95      */
96     void setData(const GrPrimitiveProcessor&, const GrPipeline&);
97 
98     /**
99      * This function retrieves the textures that need to be used by each GrGL*Processor, and
100      * ensures that any textures requiring mipmaps have their mipmaps correctly built.
101      */
102     void generateMipmaps(const GrPrimitiveProcessor&, const GrPipeline&);
103 
104 protected:
105     using UniformHandle    = GrGLSLProgramDataManager::UniformHandle ;
106     using UniformInfoArray = GrGLProgramDataManager::UniformInfoArray;
107     using VaryingInfoArray = GrGLProgramDataManager::VaryingInfoArray;
108 
109     GrGLProgram(GrGLGpu*,
110                 const GrProgramDesc&,
111                 const BuiltinUniformHandles&,
112                 GrGLuint programID,
113                 const UniformInfoArray& uniforms,
114                 const UniformInfoArray& textureSamplers,
115                 const UniformInfoArray& texelBuffers,
116                 const VaryingInfoArray&, // used for NVPR only currently
117                 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
118                 std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
119                 const GrGLSLFragProcs& fragmentProcessors);
120 
121     // A helper to loop over effects, set the transforms (via subclass) and bind textures
122     void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextTexSamplerIdx,
123                          int* nextTexelBufferIdx);
124 
125     // Helper for setData() that sets the view matrix and loads the render target height uniform
126     void setRenderTargetState(const GrPrimitiveProcessor&, const GrRenderTargetProxy*);
127 
128     // Helper for setData() that binds textures and texel buffers to the appropriate texture units
129     void bindTextures(const GrResourceIOProcessor&, bool allowSRGBInputs, int* nextSamplerIdx,
130                       int* nextTexelBufferIdx);
131 
132     // Helper for generateMipmaps() that ensures mipmaps are up to date
133     void generateMipmaps(const GrResourceIOProcessor&, bool allowSRGBInputs);
134 
135     // these reflect the current values of uniforms (GL uniform values travel with program)
136     RenderTargetState fRenderTargetState;
137     BuiltinUniformHandles fBuiltinUniformHandles;
138     GrGLuint fProgramID;
139 
140     // the installed effects
141     std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
142     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
143     GrGLSLFragProcs fFragmentProcessors;
144 
145     GrProgramDesc fDesc;
146     GrGLGpu* fGpu;
147     GrGLProgramDataManager fProgramDataManager;
148 
149     int fNumTextureSamplers;
150     int fNumTexelBuffers;
151 
152     friend class GrGLProgramBuilder;
153 
154     typedef SkRefCnt INHERITED;
155 };
156 
157 #endif
158