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