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 "GrGLContext.h" 13 #include "GrProgramDesc.h" 14 #include "GrGLTexture.h" 15 #include "GrGLProgramDataManager.h" 16 #include "glsl/GrGLSLProgramDataManager.h" 17 #include "glsl/GrGLSLUniformHandler.h" 18 19 #include "SkString.h" 20 21 #include "builders/GrGLProgramBuilder.h" 22 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 typedef GrGLSLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles; 39 40 ~GrGLProgram(); 41 42 /** 43 * Call to abandon GL objects owned by this program. 44 */ 45 void abandon(); 46 47 const GrProgramDesc& getDesc() { return fDesc; } 48 49 /** 50 * Gets the GL program ID for this program. 51 */ 52 GrGLuint programID() const { return fProgramID; } 53 54 /** 55 * We use the RT's size and origin to adjust from Skia device space to OpenGL normalized device 56 * space and to make device space positions have the correct origin for processors that require 57 * them. 58 */ 59 struct RenderTargetState { 60 SkISize fRenderTargetSize; 61 GrSurfaceOrigin fRenderTargetOrigin; 62 63 RenderTargetState() { this->invalidate(); } 64 void invalidate() { 65 fRenderTargetSize.fWidth = -1; 66 fRenderTargetSize.fHeight = -1; 67 fRenderTargetOrigin = (GrSurfaceOrigin) -1; 68 } 69 70 /** 71 * Gets a float4 that adjusts the position from Skia device coords to GL's normalized device 72 * coords. Assuming the transformed position, pos, is a homogeneous float3, the vec, v, is 73 * applied as such: 74 * pos.x = dot(v.xy, pos.xz) 75 * pos.y = dot(v.zw, pos.yz) 76 */ 77 void getRTAdjustmentVec(float* destVec) { 78 destVec[0] = 2.f / fRenderTargetSize.fWidth; 79 destVec[1] = -1.f; 80 if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) { 81 destVec[2] = -2.f / fRenderTargetSize.fHeight; 82 destVec[3] = 1.f; 83 } else { 84 destVec[2] = 2.f / fRenderTargetSize.fHeight; 85 destVec[3] = -1.f; 86 } 87 } 88 }; 89 90 /** 91 * This function uploads uniforms, calls each GrGL*Processor's setData, and retrieves the 92 * textures that need to be bound on each unit. It is the caller's responsibility to ensure 93 * the program is bound before calling, and to bind the outgoing textures to their respective 94 * units upon return. (Each index in the array corresponds to its matching GL texture unit.) 95 */ 96 void setData(const GrPrimitiveProcessor&, const GrPipeline&); 97 98 /** 99 * This function retrieves the textures that need to be used by each GrGL*Processor, and 100 * ensures that any textures requiring mipmaps have their mipmaps correctly built. 101 */ 102 void generateMipmaps(const GrPrimitiveProcessor&, const GrPipeline&); 103 104 protected: 105 using UniformHandle = GrGLSLProgramDataManager::UniformHandle ; 106 using UniformInfoArray = GrGLProgramDataManager::UniformInfoArray; 107 using VaryingInfoArray = GrGLProgramDataManager::VaryingInfoArray; 108 109 GrGLProgram(GrGLGpu*, 110 const GrProgramDesc&, 111 const BuiltinUniformHandles&, 112 GrGLuint programID, 113 const UniformInfoArray& uniforms, 114 const UniformInfoArray& textureSamplers, 115 const UniformInfoArray& texelBuffers, 116 const VaryingInfoArray&, // used for NVPR only currently 117 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor, 118 std::unique_ptr<GrGLSLXferProcessor> xferProcessor, 119 const GrGLSLFragProcs& fragmentProcessors); 120 121 // A helper to loop over effects, set the transforms (via subclass) and bind textures 122 void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextTexSamplerIdx, 123 int* nextTexelBufferIdx); 124 125 // Helper for setData() that sets the view matrix and loads the render target height uniform 126 void setRenderTargetState(const GrPrimitiveProcessor&, const GrRenderTargetProxy*); 127 128 // Helper for setData() that binds textures and texel buffers to the appropriate texture units 129 void bindTextures(const GrResourceIOProcessor&, bool allowSRGBInputs, int* nextSamplerIdx, 130 int* nextTexelBufferIdx); 131 132 // Helper for generateMipmaps() that ensures mipmaps are up to date 133 void generateMipmaps(const GrResourceIOProcessor&, bool allowSRGBInputs); 134 135 // these reflect the current values of uniforms (GL uniform values travel with program) 136 RenderTargetState fRenderTargetState; 137 BuiltinUniformHandles fBuiltinUniformHandles; 138 GrGLuint fProgramID; 139 140 // the installed effects 141 std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor; 142 std::unique_ptr<GrGLSLXferProcessor> fXferProcessor; 143 GrGLSLFragProcs fFragmentProcessors; 144 145 GrProgramDesc fDesc; 146 GrGLGpu* fGpu; 147 GrGLProgramDataManager fProgramDataManager; 148 149 int fNumTextureSamplers; 150 int fNumTexelBuffers; 151 152 friend class GrGLProgramBuilder; 153 154 typedef SkRefCnt INHERITED; 155 }; 156 157 #endif 158