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