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 GrProgramInfo; 22 class GrRenderTarget; 23 class 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 */ 29 class GrGLProgram : public SkRefCnt { 30 public: 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 */ programID()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 RenderTargetStateRenderTargetState88 RenderTargetState() { this->invalidate(); } invalidateRenderTargetState89 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 */ getRTAdjustmentVecRenderTargetState102 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, calls each GrGLSL*Processor's setData. It binds all fragment 117 * processor textures. Primitive process textures can be bound using this function or by 118 * calling updatePrimitiveProcessorTextureBindings. 119 * 120 * It is the caller's responsibility to ensure the program is bound before calling. 121 */ 122 void updateUniformsAndTextureBindings(const GrRenderTarget*, const GrProgramInfo&); 123 124 void updatePrimitiveProcessorTextureBindings(const GrPrimitiveProcessor&, 125 const GrTextureProxy* const[]); 126 vertexStride()127 int vertexStride() const { return fVertexStride; } instanceStride()128 int instanceStride() const { return fInstanceStride; } 129 numVertexAttributes()130 int numVertexAttributes() const { return fVertexAttributeCnt; } vertexAttribute(int i)131 const Attribute& vertexAttribute(int i) const { 132 SkASSERT(i >= 0 && i < fVertexAttributeCnt); 133 return fAttributes[i]; 134 } 135 numInstanceAttributes()136 int numInstanceAttributes() const { return fInstanceAttributeCnt; } instanceAttribute(int i)137 const Attribute& instanceAttribute(int i) const { 138 SkASSERT(i >= 0 && i < fInstanceAttributeCnt); 139 return fAttributes[i + fVertexAttributeCnt]; 140 } 141 142 private: 143 // A helper to loop over effects, set the transforms (via subclass) and bind textures 144 void setFragmentData(const GrPipeline&, int* nextTexSamplerIdx); 145 146 // Helper for setData() that sets the view matrix and loads the render target height uniform 147 void setRenderTargetState(const GrRenderTarget*, GrSurfaceOrigin, const GrPrimitiveProcessor&); 148 149 // these reflect the current values of uniforms (GL uniform values travel with program) 150 RenderTargetState fRenderTargetState; 151 GrGLSLBuiltinUniformHandles fBuiltinUniformHandles; 152 GrGLuint fProgramID; 153 154 // the installed effects 155 std::unique_ptr<GrGLSLPrimitiveProcessor> fPrimitiveProcessor; 156 std::unique_ptr<GrGLSLXferProcessor> fXferProcessor; 157 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors; 158 int fFragmentProcessorCnt; 159 160 std::unique_ptr<Attribute[]> fAttributes; 161 int fVertexAttributeCnt; 162 int fInstanceAttributeCnt; 163 int fVertexStride; 164 int fInstanceStride; 165 166 GrGLGpu* fGpu; 167 GrGLProgramDataManager fProgramDataManager; 168 169 int fNumTextureSamplers; 170 171 typedef SkRefCnt INHERITED; 172 }; 173 174 #endif 175