blob: 6e7e22bcada30523988609e8c35da87db23373fd [file] [log] [blame]
junov@google.comf93e7172011-03-31 21:26:24 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * 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.
junov@google.comf93e7172011-03-31 21:26:24 +00006 */
7
epoger@google.comec3ed6a2011-07-28 14:26:00 +00008
junov@google.comf93e7172011-03-31 21:26:24 +00009#ifndef GrGLProgram_DEFINED
10#define GrGLProgram_DEFINED
11
joshualitt30ba4362014-08-21 20:18:45 -070012#include "builders/GrGLProgramBuilder.h"
joshualitt47bb3822014-10-07 16:43:25 -070013#include "builders/GrGLNvprProgramBuilder.h"
tomhudson@google.comd8f856c2012-05-10 12:13:36 +000014#include "GrDrawState.h"
robertphillips@google.com6177e692013-02-28 20:16:25 +000015#include "GrGLContext.h"
bsalomon@google.com31ec7982013-03-27 18:14:57 +000016#include "GrGLProgramDesc.h"
tomhudson@google.com086e5352011-12-08 14:44:10 +000017#include "GrGLSL.h"
bsalomon@google.com890e3b52012-06-01 19:01:37 +000018#include "GrGLTexture.h"
kkinnunen7510b222014-07-30 00:04:16 -070019#include "GrGLProgramDataManager.h"
junov@google.comf93e7172011-03-31 21:26:24 +000020
bsalomon@google.comf0a104e2012-07-10 17:51:07 +000021#include "SkString.h"
Scroggo97c88c22011-05-11 14:05:25 +000022#include "SkXfermode.h"
23
joshualittb0a8a372014-09-23 09:50:21 -070024class GrGLProcessor;
joshualitt47bb3822014-10-07 16:43:25 -070025class GrGLInstalledProcessors;
joshualitt30ba4362014-08-21 20:18:45 -070026class GrGLProgramBuilder;
junov@google.comf93e7172011-03-31 21:26:24 +000027
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 */
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +000037class GrGLProgram : public SkRefCnt {
junov@google.comf93e7172011-03-31 21:26:24 +000038public:
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000039 SK_DECLARE_INST_COUNT(GrGLProgram)
bsalomon@google.com4fa66942011-09-20 19:06:12 +000040
joshualitt30ba4362014-08-21 20:18:45 -070041 typedef GrGLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
kkinnunendddc18a2014-08-03 23:19:46 -070042
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000043 virtual ~GrGLProgram();
junov@google.comf93e7172011-03-31 21:26:24 +000044
bsalomon@google.com34cccde2013-01-04 18:34:30 +000045 /**
46 * Call to abandon GL objects owned by this program.
47 */
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000048 void abandon();
49
joshualitt79f8fae2014-10-28 17:59:26 -070050 const GrProgramDesc& getDesc() { return fDesc; }
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000051
bsalomon@google.com271cffc2011-05-20 14:13:56 +000052 /**
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +000053 * Gets the GL program ID for this program.
54 */
kkinnunendddc18a2014-08-03 23:19:46 -070055 GrGLuint programID() const { return fProgramID; }
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +000056
joshualitt47bb3822014-10-07 16:43:25 -070057 /*
58 * The base class always has a vertex shader, only the NVPR variants may omit a vertex shader
59 */
60 virtual bool hasVertexShader() const { return true; }
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +000061
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +000062 /**
joshualittee2af952014-12-30 09:04:15 -080063 * We use the RT's size and origin to adjust from Skia device space to OpenGL normalized device
64 * space and to make device space positions have the correct origin for processors that require
65 * them.
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +000066 */
joshualittee2af952014-12-30 09:04:15 -080067 struct RenderTargetState {
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +000068 SkISize fRenderTargetSize;
69 GrSurfaceOrigin fRenderTargetOrigin;
70
joshualittee2af952014-12-30 09:04:15 -080071 RenderTargetState() { this->invalidate(); }
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +000072 void invalidate() {
bsalomon@google.com45a412e2013-02-13 16:13:13 +000073 fRenderTargetSize.fWidth = -1;
74 fRenderTargetSize.fHeight = -1;
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +000075 fRenderTargetOrigin = (GrSurfaceOrigin) -1;
76 }
commit-bot@chromium.org47c66dd2014-05-29 01:12:10 +000077
78 /**
commit-bot@chromium.org47c66dd2014-05-29 01:12:10 +000079 * Gets a vec4 that adjusts the position from Skia device coords to GL's normalized device
80 * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is
81 * applied as such:
82 * pos.x = dot(v.xy, pos.xz)
83 * pos.y = dot(v.zq, pos.yz)
84 */
85 void getRTAdjustmentVec(GrGLfloat* destVec) {
86 destVec[0] = 2.f / fRenderTargetSize.fWidth;
87 destVec[1] = -1.f;
88 if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
89 destVec[2] = -2.f / fRenderTargetSize.fHeight;
90 destVec[3] = 1.f;
91 } else {
92 destVec[2] = 2.f / fRenderTargetSize.fHeight;
93 destVec[3] = -1.f;
94 }
95 }
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +000096 };
97
98 /**
joshualittb0a8a372014-09-23 09:50:21 -070099 * This function uploads uniforms and calls each GrGLProcessor's setData. It is called before a
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000100 * draw occurs using the program after the program has already been bound. It also uses the
bsalomon861e1032014-12-16 07:33:49 -0800101 * GrGLGpu object to bind the textures required by the GrGLProcessors. The color and coverage
bsalomon@google.com2c84aa32013-06-06 20:28:57 +0000102 * stages come from GrGLProgramDesc::Build().
bsalomon@google.com4285acc2012-10-22 14:11:24 +0000103 */
joshualittdafa4d02014-12-04 08:59:10 -0800104 void setData(const GrOptDrawState&);
bsalomon@google.com91961302011-05-09 18:39:58 +0000105
joshualitt47bb3822014-10-07 16:43:25 -0700106protected:
kkinnunen7510b222014-07-30 00:04:16 -0700107 typedef GrGLProgramDataManager::UniformHandle UniformHandle;
joshualitt47bb3822014-10-07 16:43:25 -0700108 typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000109
bsalomon861e1032014-12-16 07:33:49 -0800110 GrGLProgram(GrGLGpu*,
joshualitt79f8fae2014-10-28 17:59:26 -0700111 const GrProgramDesc&,
joshualitt47bb3822014-10-07 16:43:25 -0700112 const BuiltinUniformHandles&,
113 GrGLuint programID,
114 const UniformInfoArray&,
joshualitta5305a12014-10-10 17:47:00 -0700115 GrGLInstalledGeoProc* geometryProcessor,
egdanielc2304142014-12-11 13:15:13 -0800116 GrGLInstalledXferProc* xferProcessor,
joshualitta5305a12014-10-10 17:47:00 -0700117 GrGLInstalledFragProcs* fragmentProcessors);
bsalomon@google.com2c84aa32013-06-06 20:28:57 +0000118
commit-bot@chromium.orga05fa062014-05-30 18:55:03 +0000119 // Sets the texture units for samplers.
bsalomon@google.com2c84aa32013-06-06 20:28:57 +0000120 void initSamplerUniforms();
joshualitta5305a12014-10-10 17:47:00 -0700121 void initSamplers(GrGLInstalledProc*, int* texUnitIdx);
bsalomon@google.com2c84aa32013-06-06 20:28:57 +0000122
joshualitt47bb3822014-10-07 16:43:25 -0700123 // A templated helper to loop over effects, set the transforms(via subclass) and bind textures
joshualitta5305a12014-10-10 17:47:00 -0700124 void setFragmentData(const GrOptDrawState&);
joshualitt290c09b2014-12-19 13:45:20 -0800125 virtual void setTransformData(const GrPendingFragmentStage&,
126 const SkMatrix& localMatrix,
127 GrGLInstalledFragProc*);
joshualitta5305a12014-10-10 17:47:00 -0700128 void bindTextures(const GrGLInstalledProc*, const GrProcessor&);
joshualitt47bb3822014-10-07 16:43:25 -0700129
130 /*
131 * Legacy NVPR needs a hook here to flush path tex gen settings.
132 * TODO when legacy nvpr is removed, remove this call.
133 */
134 virtual void didSetData(GrGpu::DrawType);
135
bsalomon@google.com2c84aa32013-06-06 20:28:57 +0000136 // Helper for setData() that sets the view matrix and loads the render target height uniform
joshualittee2af952014-12-30 09:04:15 -0800137 void setRenderTargetState(const GrOptDrawState&);
138 virtual void onSetRenderTargetState(const GrOptDrawState&);
bsalomon@google.com2c84aa32013-06-06 20:28:57 +0000139
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000140 // these reflect the current values of uniforms (GL uniform values travel with program)
joshualittee2af952014-12-30 09:04:15 -0800141 RenderTargetState fRenderTargetState;
joshualitt47bb3822014-10-07 16:43:25 -0700142 GrColor fColor;
egdaniel37b4d862014-11-03 10:07:07 -0800143 uint8_t fCoverage;
joshualitt47bb3822014-10-07 16:43:25 -0700144 int fDstCopyTexUnit;
145 BuiltinUniformHandles fBuiltinUniformHandles;
146 GrGLuint fProgramID;
junov@google.comf93e7172011-03-31 21:26:24 +0000147
joshualitt47bb3822014-10-07 16:43:25 -0700148 // the installed effects
joshualitta5305a12014-10-10 17:47:00 -0700149 SkAutoTDelete<GrGLInstalledGeoProc> fGeometryProcessor;
egdanielc2304142014-12-11 13:15:13 -0800150 SkAutoTDelete<GrGLInstalledXferProc> fXferProcessor;
joshualitta5305a12014-10-10 17:47:00 -0700151 SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
skia.committer@gmail.com9681eeb2014-05-30 03:06:10 +0000152
joshualitt79f8fae2014-10-28 17:59:26 -0700153 GrProgramDesc fDesc;
bsalomon861e1032014-12-16 07:33:49 -0800154 GrGLGpu* fGpu;
joshualitt47bb3822014-10-07 16:43:25 -0700155 GrGLProgramDataManager fProgramDataManager;
junov@google.comf93e7172011-03-31 21:26:24 +0000156
joshualitt47bb3822014-10-07 16:43:25 -0700157 friend class GrGLProgramBuilder;
commit-bot@chromium.org6b30e452013-10-04 20:02:53 +0000158
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000159 typedef SkRefCnt INHERITED;
junov@google.comf93e7172011-03-31 21:26:24 +0000160};
161
joshualitt47bb3822014-10-07 16:43:25 -0700162/*
163 * Below are slight specializations of the program object for the different types of programs
164 * The default GrGL programs consist of at the very least a vertex and fragment shader.
165 * Legacy Nvpr only has a fragment shader, 1.3+ Nvpr ignores the vertex shader, but both require
166 * specialized methods for setting transform data. Both types of NVPR also require setting the
167 * projection matrix through a special function call
168 */
169class GrGLNvprProgramBase : public GrGLProgram {
170protected:
bsalomon861e1032014-12-16 07:33:49 -0800171 GrGLNvprProgramBase(GrGLGpu*,
joshualitt79f8fae2014-10-28 17:59:26 -0700172 const GrProgramDesc&,
joshualitt47bb3822014-10-07 16:43:25 -0700173 const BuiltinUniformHandles&,
174 GrGLuint programID,
175 const UniformInfoArray&,
joshualitt9b989322014-12-15 14:16:27 -0800176 GrGLInstalledGeoProc*,
egdanielc2304142014-12-11 13:15:13 -0800177 GrGLInstalledXferProc* xferProcessor,
joshualitta5305a12014-10-10 17:47:00 -0700178 GrGLInstalledFragProcs* fragmentProcessors);
joshualittee2af952014-12-30 09:04:15 -0800179 virtual void onSetRenderTargetState(const GrOptDrawState&);
joshualitt47bb3822014-10-07 16:43:25 -0700180
181 typedef GrGLProgram INHERITED;
182};
183
184class GrGLNvprProgram : public GrGLNvprProgramBase {
185public:
bsalomonae59b772014-11-19 08:23:49 -0800186 virtual bool hasVertexShader() const SK_OVERRIDE { return true; }
joshualitt47bb3822014-10-07 16:43:25 -0700187
188private:
189 typedef GrGLNvprProgramBuilder::SeparableVaryingInfo SeparableVaryingInfo;
190 typedef GrGLNvprProgramBuilder::SeparableVaryingInfoArray SeparableVaryingInfoArray;
bsalomon861e1032014-12-16 07:33:49 -0800191 GrGLNvprProgram(GrGLGpu*,
joshualitt79f8fae2014-10-28 17:59:26 -0700192 const GrProgramDesc&,
joshualitt47bb3822014-10-07 16:43:25 -0700193 const BuiltinUniformHandles&,
194 GrGLuint programID,
195 const UniformInfoArray&,
joshualitt9b989322014-12-15 14:16:27 -0800196 GrGLInstalledGeoProc*,
egdanielc2304142014-12-11 13:15:13 -0800197 GrGLInstalledXferProc* xferProcessor,
joshualitta5305a12014-10-10 17:47:00 -0700198 GrGLInstalledFragProcs* fragmentProcessors,
joshualitt47bb3822014-10-07 16:43:25 -0700199 const SeparableVaryingInfoArray& separableVaryings);
200 virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
bsalomonae59b772014-11-19 08:23:49 -0800201 virtual void setTransformData(const GrPendingFragmentStage&,
joshualitt290c09b2014-12-19 13:45:20 -0800202 const SkMatrix& localMatrix,
bsalomonae59b772014-11-19 08:23:49 -0800203 GrGLInstalledFragProc*) SK_OVERRIDE;
joshualitt47bb3822014-10-07 16:43:25 -0700204
205 struct Varying {
206 GrGLint fLocation;
207 SkDEBUGCODE(
208 GrSLType fType;
209 );
210 };
211 SkTArray<Varying, true> fVaryings;
212
213 friend class GrGLNvprProgramBuilder;
214
215 typedef GrGLNvprProgramBase INHERITED;
216};
217
218class GrGLLegacyNvprProgram : public GrGLNvprProgramBase {
219public:
220 virtual bool hasVertexShader() const SK_OVERRIDE { return false; }
221
222private:
bsalomon861e1032014-12-16 07:33:49 -0800223 GrGLLegacyNvprProgram(GrGLGpu* gpu,
joshualitt79f8fae2014-10-28 17:59:26 -0700224 const GrProgramDesc& desc,
joshualitt47bb3822014-10-07 16:43:25 -0700225 const BuiltinUniformHandles&,
226 GrGLuint programID,
227 const UniformInfoArray&,
joshualitt9b989322014-12-15 14:16:27 -0800228 GrGLInstalledGeoProc*,
egdanielc2304142014-12-11 13:15:13 -0800229 GrGLInstalledXferProc* xp,
230 GrGLInstalledFragProcs* fps,
joshualitt47bb3822014-10-07 16:43:25 -0700231 int texCoordSetCnt);
232 virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
bsalomonae59b772014-11-19 08:23:49 -0800233 virtual void setTransformData(const GrPendingFragmentStage&,
joshualitt290c09b2014-12-19 13:45:20 -0800234 const SkMatrix& localMatrix,
bsalomonae59b772014-11-19 08:23:49 -0800235 GrGLInstalledFragProc*) SK_OVERRIDE;
joshualitt47bb3822014-10-07 16:43:25 -0700236
237 int fTexCoordSetCnt;
238
239 friend class GrGLLegacyNvprProgramBuilder;
240
241 typedef GrGLNvprProgramBase INHERITED;
242};
243
junov@google.comf93e7172011-03-31 21:26:24 +0000244#endif