1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/gl/GrGLProgram.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,206 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 + 1.12 +#ifndef GrGLProgram_DEFINED 1.13 +#define GrGLProgram_DEFINED 1.14 + 1.15 +#include "GrDrawState.h" 1.16 +#include "GrGLContext.h" 1.17 +#include "GrGLProgramDesc.h" 1.18 +#include "GrGLShaderBuilder.h" 1.19 +#include "GrGLSL.h" 1.20 +#include "GrGLTexture.h" 1.21 +#include "GrGLUniformManager.h" 1.22 + 1.23 +#include "SkString.h" 1.24 +#include "SkXfermode.h" 1.25 + 1.26 +class GrBinHashKeyBuilder; 1.27 +class GrGLEffect; 1.28 +class GrGLProgramEffects; 1.29 +class GrGLShaderBuilder; 1.30 + 1.31 +/** 1.32 + * This class manages a GPU program and records per-program information. 1.33 + * We can specify the attribute locations so that they are constant 1.34 + * across our shaders. But the driver determines the uniform locations 1.35 + * at link time. We don't need to remember the sampler uniform location 1.36 + * because we will bind a texture slot to it and never change it 1.37 + * Uniforms are program-local so we can't rely on fHWState to hold the 1.38 + * previous uniform state after a program change. 1.39 + */ 1.40 +class GrGLProgram : public SkRefCnt { 1.41 +public: 1.42 + SK_DECLARE_INST_COUNT(GrGLProgram) 1.43 + 1.44 + static GrGLProgram* Create(GrGpuGL* gpu, 1.45 + const GrGLProgramDesc& desc, 1.46 + const GrEffectStage* colorStages[], 1.47 + const GrEffectStage* coverageStages[]); 1.48 + 1.49 + virtual ~GrGLProgram(); 1.50 + 1.51 + /** 1.52 + * Call to abandon GL objects owned by this program. 1.53 + */ 1.54 + void abandon(); 1.55 + 1.56 + /** 1.57 + * The shader may modify the blend coefficients. Params are in/out. 1.58 + */ 1.59 + void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const; 1.60 + 1.61 + const GrGLProgramDesc& getDesc() { return fDesc; } 1.62 + 1.63 + /** 1.64 + * Gets the GL program ID for this program. 1.65 + */ 1.66 + GrGLuint programID() const { return fProgramID; } 1.67 + 1.68 + bool hasVertexShader() const { return fHasVertexShader; } 1.69 + 1.70 + /** 1.71 + * Some GL state that is relevant to programs is not stored per-program. In particular color 1.72 + * and coverage attributes can be global state. This struct is read and updated by 1.73 + * GrGLProgram::setColor and GrGLProgram::setCoverage to allow us to avoid setting this state 1.74 + * redundantly. 1.75 + */ 1.76 + struct SharedGLState { 1.77 + GrColor fConstAttribColor; 1.78 + int fConstAttribColorIndex; 1.79 + GrColor fConstAttribCoverage; 1.80 + int fConstAttribCoverageIndex; 1.81 + 1.82 + SharedGLState() { this->invalidate(); } 1.83 + void invalidate() { 1.84 + fConstAttribColor = GrColor_ILLEGAL; 1.85 + fConstAttribColorIndex = -1; 1.86 + fConstAttribCoverage = GrColor_ILLEGAL; 1.87 + fConstAttribCoverageIndex = -1; 1.88 + } 1.89 + }; 1.90 + 1.91 + /** 1.92 + * The GrDrawState's view matrix along with the aspects of the render target determine the 1.93 + * matrix sent to GL. The size of the render target affects the GL matrix because we must 1.94 + * convert from Skia device coords to GL's normalized coords. Also the origin of the render 1.95 + * target may require us to perform a mirror-flip. 1.96 + */ 1.97 + struct MatrixState { 1.98 + SkMatrix fViewMatrix; 1.99 + SkISize fRenderTargetSize; 1.100 + GrSurfaceOrigin fRenderTargetOrigin; 1.101 + 1.102 + MatrixState() { this->invalidate(); } 1.103 + void invalidate() { 1.104 + fViewMatrix = SkMatrix::InvalidMatrix(); 1.105 + fRenderTargetSize.fWidth = -1; 1.106 + fRenderTargetSize.fHeight = -1; 1.107 + fRenderTargetOrigin = (GrSurfaceOrigin) -1; 1.108 + } 1.109 + template<int Size> void getGLMatrix(GrGLfloat* destMatrix) { 1.110 + SkMatrix combined; 1.111 + if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) { 1.112 + combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1, 1.113 + 0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1, 1.114 + 0, 0, SkMatrix::I()[8]); 1.115 + } else { 1.116 + combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1, 1.117 + 0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1, 1.118 + 0, 0, SkMatrix::I()[8]); 1.119 + } 1.120 + combined.setConcat(combined, fViewMatrix); 1.121 + GrGLGetMatrix<Size>(destMatrix, combined); 1.122 + } 1.123 + }; 1.124 + 1.125 + /** 1.126 + * This function uploads uniforms and calls each GrGLEffect's setData. It is called before a 1.127 + * draw occurs using the program after the program has already been bound. It also uses the 1.128 + * GrGpuGL object to bind the textures required by the GrGLEffects. The color and coverage 1.129 + * stages come from GrGLProgramDesc::Build(). 1.130 + */ 1.131 + void setData(GrDrawState::BlendOptFlags, 1.132 + const GrEffectStage* colorStages[], 1.133 + const GrEffectStage* coverageStages[], 1.134 + const GrDeviceCoordTexture* dstCopy, // can be NULL 1.135 + SharedGLState*); 1.136 + 1.137 +private: 1.138 + typedef GrGLUniformManager::UniformHandle UniformHandle; 1.139 + 1.140 + // handles for uniforms (aside from per-effect samplers) 1.141 + struct UniformHandles { 1.142 + UniformHandle fViewMatrixUni; 1.143 + UniformHandle fColorUni; 1.144 + UniformHandle fCoverageUni; 1.145 + 1.146 + // We use the render target height to provide a y-down frag coord when specifying 1.147 + // origin_upper_left is not supported. 1.148 + UniformHandle fRTHeightUni; 1.149 + 1.150 + // Uniforms for computing texture coords to do the dst-copy lookup 1.151 + UniformHandle fDstCopyTopLeftUni; 1.152 + UniformHandle fDstCopyScaleUni; 1.153 + UniformHandle fDstCopySamplerUni; 1.154 + }; 1.155 + 1.156 + GrGLProgram(GrGpuGL* gpu, 1.157 + const GrGLProgramDesc& desc, 1.158 + const GrEffectStage* colorStages[], 1.159 + const GrEffectStage* coverageStages[]); 1.160 + 1.161 + bool succeeded() const { return 0 != fProgramID; } 1.162 + 1.163 + /** 1.164 + * This is the heavy initialization routine for building a GLProgram. colorStages and 1.165 + * coverageStages correspond to the output of GrGLProgramDesc::Build(). 1.166 + */ 1.167 + bool genProgram(GrGLShaderBuilder* builder, 1.168 + const GrEffectStage* colorStages[], 1.169 + const GrEffectStage* coverageStages[]); 1.170 + 1.171 + // Sets the texture units for samplers 1.172 + void initSamplerUniforms(); 1.173 + 1.174 + // Helper for setData(). Makes GL calls to specify the initial color when there is not 1.175 + // per-vertex colors. 1.176 + void setColor(const GrDrawState&, GrColor color, SharedGLState*); 1.177 + 1.178 + // Helper for setData(). Makes GL calls to specify the initial coverage when there is not 1.179 + // per-vertex coverages. 1.180 + void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*); 1.181 + 1.182 + // Helper for setData() that sets the view matrix and loads the render target height uniform 1.183 + void setMatrixAndRenderTargetHeight(const GrDrawState&); 1.184 + 1.185 + // GL program ID 1.186 + GrGLuint fProgramID; 1.187 + 1.188 + // these reflect the current values of uniforms (GL uniform values travel with program) 1.189 + MatrixState fMatrixState; 1.190 + GrColor fColor; 1.191 + GrColor fCoverage; 1.192 + int fDstCopyTexUnit; 1.193 + 1.194 + SkAutoTDelete<GrGLProgramEffects> fColorEffects; 1.195 + SkAutoTDelete<GrGLProgramEffects> fCoverageEffects; 1.196 + 1.197 + GrGLProgramDesc fDesc; 1.198 + GrGpuGL* fGpu; 1.199 + 1.200 + GrGLUniformManager fUniformManager; 1.201 + UniformHandles fUniformHandles; 1.202 + 1.203 + bool fHasVertexShader; 1.204 + int fNumTexCoordSets; 1.205 + 1.206 + typedef SkRefCnt INHERITED; 1.207 +}; 1.208 + 1.209 +#endif