• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "src/gpu/gl/GrGLProgramDataManager.h"
13 #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
14 #include "src/gpu/glsl/GrGLSLUniformHandler.h"
15 
16 class GrGLSLFragmentProcessor;
17 class GrGLSLPrimitiveProcessor;
18 class GrGLSLXferProcessor;
19 class GrPipeline;
20 class GrPrimitiveProcessor;
21 class GrRenderTarget;
22 class GrTextureProxy;
23 
24 /**
25  * This class manages a GPU program and records per-program information. It also records the vertex
26  * and instance attribute layouts that are to be used with the program.
27  */
28 class GrGLProgram : public SkRefCnt {
29 public:
30     /**
31      * This class has its own Attribute representation as it does not need the name and we don't
32      * want to worry about copying the name string to memory with life time of GrGLProgram.
33      * Additionally, these store the attribute location.
34      */
35     struct Attribute {
36         GrVertexAttribType fCPUType;
37         GrSLType fGPUType;
38         size_t fOffset;
39         GrGLint fLocation;
40     };
41 
42     using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
43     using UniformInfoArray = GrGLProgramDataManager::UniformInfoArray;
44     using VaryingInfoArray = GrGLProgramDataManager::VaryingInfoArray;
45 
46     /**
47      * The attribute array consists of vertexAttributeCnt + instanceAttributeCnt elements with
48      * the vertex attributes preceding the instance attributes.
49      */
50     GrGLProgram(GrGLGpu*,
51                 const GrGLSLBuiltinUniformHandles&,
52                 GrGLuint programID,
53                 const UniformInfoArray& uniforms,
54                 const UniformInfoArray& textureSamplers,
55                 const VaryingInfoArray&, // used for NVPR only currently
56                 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
57                 std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
58                 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
59                 int fragmentProcessorCnt,
60                 std::unique_ptr<Attribute[]>,
61                 int vertexAttributeCnt,
62                 int instanceAttributeCnt,
63                 int vertexStride,
64                 int instanceStride);
65 
66     ~GrGLProgram();
67 
68     /**
69      * Call to abandon GL objects owned by this program.
70      */
71     void abandon();
72 
73     /**
74      * Gets the GL program ID for this program.
75      */
programID()76     GrGLuint programID() const { return fProgramID; }
77 
78     /**
79      * We use the RT's size and origin to adjust from Skia device space to OpenGL normalized device
80      * space and to make device space positions have the correct origin for processors that require
81      * them.
82      */
83     struct RenderTargetState {
84         SkISize         fRenderTargetSize;
85         GrSurfaceOrigin fRenderTargetOrigin;
86 
RenderTargetStateRenderTargetState87         RenderTargetState() { this->invalidate(); }
invalidateRenderTargetState88         void invalidate() {
89             fRenderTargetSize.fWidth = -1;
90             fRenderTargetSize.fHeight = -1;
91             fRenderTargetOrigin = (GrSurfaceOrigin) -1;
92         }
93 
94         /**
95          * Gets a float4 that adjusts the position from Skia device coords to GL's normalized device
96          * coords. Assuming the transformed position, pos, is a homogeneous float3, the vec, v, is
97          * applied as such:
98          * pos.x = dot(v.xy, pos.xz)
99          * pos.y = dot(v.zw, pos.yz)
100          */
getRTAdjustmentVecRenderTargetState101         void getRTAdjustmentVec(float* destVec) {
102             destVec[0] = 2.f / fRenderTargetSize.fWidth;
103             destVec[1] = -1.f;
104             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
105                 destVec[2] = -2.f / fRenderTargetSize.fHeight;
106                 destVec[3] = 1.f;
107             } else {
108                 destVec[2] = 2.f / fRenderTargetSize.fHeight;
109                 destVec[3] = -1.f;
110             }
111         }
112     };
113 
114     /**
115      * This function uploads uniforms, calls each GrGLSL*Processor's setData. It binds all fragment
116      * processor textures. Primitive process textures can be bound using this function or by
117      * calling updatePrimitiveProcessorTextureBindings.
118      *
119      * It is the caller's responsibility to ensure the program is bound before calling.
120      */
121     void updateUniformsAndTextureBindings(const GrRenderTarget*, GrSurfaceOrigin,
122                                           const GrPrimitiveProcessor&, const GrPipeline&,
123                                           const GrTextureProxy* const primitiveProcessorTextures[]);
124 
125     void updatePrimitiveProcessorTextureBindings(const GrPrimitiveProcessor&,
126                                                  const GrTextureProxy* const[]);
127 
vertexStride()128     int vertexStride() const { return fVertexStride; }
instanceStride()129     int instanceStride() const { return fInstanceStride; }
130 
numVertexAttributes()131     int numVertexAttributes() const { return fVertexAttributeCnt; }
vertexAttribute(int i)132     const Attribute& vertexAttribute(int i) const {
133         SkASSERT(i >= 0 && i < fVertexAttributeCnt);
134         return fAttributes[i];
135     }
136 
numInstanceAttributes()137     int numInstanceAttributes() const { return fInstanceAttributeCnt; }
instanceAttribute(int i)138     const Attribute& instanceAttribute(int i) const {
139         SkASSERT(i >= 0 && i < fInstanceAttributeCnt);
140         return fAttributes[i + fVertexAttributeCnt];
141     }
142 
143 private:
144     // A helper to loop over effects, set the transforms (via subclass) and bind textures
145     void setFragmentData(const GrPipeline&, int* nextTexSamplerIdx);
146 
147     // Helper for setData() that sets the view matrix and loads the render target height uniform
148     void setRenderTargetState(const GrRenderTarget*, GrSurfaceOrigin, const GrPrimitiveProcessor&);
149 
150     // these reflect the current values of uniforms (GL uniform values travel with program)
151     RenderTargetState fRenderTargetState;
152     GrGLSLBuiltinUniformHandles fBuiltinUniformHandles;
153     GrGLuint fProgramID;
154 
155     // the installed effects
156     std::unique_ptr<GrGLSLPrimitiveProcessor> fPrimitiveProcessor;
157     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
158     std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
159     int fFragmentProcessorCnt;
160 
161     std::unique_ptr<Attribute[]> fAttributes;
162     int fVertexAttributeCnt;
163     int fInstanceAttributeCnt;
164     int fVertexStride;
165     int fInstanceStride;
166 
167     GrGLGpu* fGpu;
168     GrGLProgramDataManager fProgramDataManager;
169 
170     int fNumTextureSamplers;
171 
172     typedef SkRefCnt INHERITED;
173 };
174 
175 #endif
176