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#include "src/gpu/gl/GrGLProgram.h" 9 10#include "src/gpu/GrFragmentProcessor.h" 11#include "src/gpu/GrGeometryProcessor.h" 12#include "src/gpu/GrPipeline.h" 13#include "src/gpu/GrProcessor.h" 14#include "src/gpu/GrProgramInfo.h" 15#include "src/gpu/GrTexture.h" 16#include "src/gpu/GrXferProcessor.h" 17#include "src/gpu/effects/GrTextureEffect.h" 18#include "src/gpu/gl/GrGLBuffer.h" 19#include "src/gpu/gl/GrGLGpu.h" 20#include "src/sksl/SkSLCompiler.h" 21 22#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) 23#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) 24 25/////////////////////////////////////////////////////////////////////////////////////////////////// 26 27sk_sp<GrGLProgram> GrGLProgram::Make( 28 GrGLGpu* gpu, 29 const GrGLSLBuiltinUniformHandles& builtinUniforms, 30 GrGLuint programID, 31 const UniformInfoArray& uniforms, 32 const UniformInfoArray& textureSamplers, 33 std::unique_ptr<GrGeometryProcessor::ProgramImpl> gpImpl, 34 std::unique_ptr<GrXferProcessor::ProgramImpl> xpImpl, 35 std::vector<std::unique_ptr<GrFragmentProcessor::ProgramImpl>> fpImpls, 36 std::unique_ptr<Attribute[]> attributes, 37 int vertexAttributeCnt, 38 int instanceAttributeCnt, 39 int vertexStride, 40 int instanceStride) { 41 sk_sp<GrGLProgram> program(new GrGLProgram(gpu, 42 builtinUniforms, 43 programID, 44 uniforms, 45 textureSamplers, 46 std::move(gpImpl), 47 std::move(xpImpl), 48 std::move(fpImpls), 49 std::move(attributes), 50 vertexAttributeCnt, 51 instanceAttributeCnt, 52 vertexStride, 53 instanceStride)); 54 // Assign texture units to sampler uniforms one time up front. 55 gpu->flushProgram(program); 56 program->fProgramDataManager.setSamplerUniforms(textureSamplers, 0); 57 return program; 58} 59 60GrGLProgram::GrGLProgram(GrGLGpu* gpu, 61 const GrGLSLBuiltinUniformHandles& builtinUniforms, 62 GrGLuint programID, 63 const UniformInfoArray& uniforms, 64 const UniformInfoArray& textureSamplers, 65 std::unique_ptr<GrGeometryProcessor::ProgramImpl> gpImpl, 66 std::unique_ptr<GrXferProcessor::ProgramImpl> xpImpl, 67 std::vector<std::unique_ptr<GrFragmentProcessor::ProgramImpl>> fpImpls, 68 std::unique_ptr<Attribute[]> attributes, 69 int vertexAttributeCnt, 70 int instanceAttributeCnt, 71 int vertexStride, 72 int instanceStride) 73 : fBuiltinUniformHandles(builtinUniforms) 74 , fProgramID(programID) 75 , fGPImpl(std::move(gpImpl)) 76 , fXPImpl(std::move(xpImpl)) 77 , fFPImpls(std::move(fpImpls)) 78 , fAttributes(std::move(attributes)) 79 , fVertexAttributeCnt(vertexAttributeCnt) 80 , fInstanceAttributeCnt(instanceAttributeCnt) 81 , fVertexStride(vertexStride) 82 , fInstanceStride(instanceStride) 83 , fGpu(gpu) 84 , fProgramDataManager(gpu, uniforms) 85 , fNumTextureSamplers(textureSamplers.count()) {} 86 87GrGLProgram::~GrGLProgram() { 88 if (fProgramID) { 89 GL_CALL(DeleteProgram(fProgramID)); 90 } 91} 92 93void GrGLProgram::abandon() { 94 fProgramID = 0; 95} 96 97/////////////////////////////////////////////////////////////////////////////// 98 99void GrGLProgram::updateUniforms(const GrRenderTarget* renderTarget, 100 const GrProgramInfo& programInfo) { 101 this->setRenderTargetState(renderTarget, programInfo.origin(), programInfo.geomProc()); 102 103 // we set the uniforms for installed processors in a generic way, but subclasses of GLProgram 104 // determine how to set coord transforms 105 106 // We must bind to texture units in the same order in which we set the uniforms in 107 // GrGLProgramDataManager. That is, we bind textures for processors in this order: 108 // primProc, fragProcs, XP. 109 fGPImpl->setData(fProgramDataManager, *fGpu->caps()->shaderCaps(), programInfo.geomProc()); 110 111 for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) { 112 const auto& fp = programInfo.pipeline().getFragmentProcessor(i); 113 fp.visitWithImpls([&](const GrFragmentProcessor& fp, 114 GrFragmentProcessor::ProgramImpl& impl) { 115 impl.setData(fProgramDataManager, fp); 116 }, *fFPImpls[i]); 117 } 118 119 programInfo.pipeline().setDstTextureUniforms(fProgramDataManager, &fBuiltinUniformHandles); 120 fXPImpl->setData(fProgramDataManager, programInfo.pipeline().getXferProcessor()); 121} 122 123void GrGLProgram::bindTextures(const GrGeometryProcessor& geomProc, 124 const GrSurfaceProxy* const geomProcTextures[], 125 const GrPipeline& pipeline) { 126 // Bind textures from the geometry processor. 127 for (int i = 0; i < geomProc.numTextureSamplers(); ++i) { 128 SkASSERT(geomProcTextures[i]->asTextureProxy()); 129 auto* overrideTexture = static_cast<GrGLTexture*>(geomProcTextures[i]->peekTexture()); 130 fGpu->bindTexture(i, geomProc.textureSampler(i).samplerState(), 131 geomProc.textureSampler(i).swizzle(), overrideTexture); 132 } 133 int nextTexSamplerIdx = geomProc.numTextureSamplers(); 134 // Bind texture from the destination proxy view. 135 GrTexture* dstTexture = pipeline.peekDstTexture(); 136 if (dstTexture) { 137 fGpu->bindTexture(nextTexSamplerIdx++, GrSamplerState::Filter::kNearest, 138 pipeline.dstProxyView().swizzle(), static_cast<GrGLTexture*>(dstTexture)); 139 } 140 // Bind textures from all of the fragment processors. 141 pipeline.visitTextureEffects([&](const GrTextureEffect& te) { 142 GrSamplerState samplerState = te.samplerState(); 143 GrSwizzle swizzle = te.view().swizzle(); 144 auto* texture = static_cast<GrGLTexture*>(te.texture()); 145 fGpu->bindTexture(nextTexSamplerIdx++, samplerState, swizzle, texture); 146 }); 147 148 SkASSERT(nextTexSamplerIdx == fNumTextureSamplers); 149} 150 151void GrGLProgram::setRenderTargetState(const GrRenderTarget* rt, 152 GrSurfaceOrigin origin, 153 const GrGeometryProcessor& geomProc) { 154 // Set RT adjustment and RT flip 155 SkISize dimensions = rt->dimensions(); 156 if (fRenderTargetState.fRenderTargetOrigin != origin || 157 fRenderTargetState.fRenderTargetSize != dimensions) { 158 fRenderTargetState.fRenderTargetSize = dimensions; 159 fRenderTargetState.fRenderTargetOrigin = origin; 160 161 // The client will mark a swap buffer as kBottomLeft when making a SkSurface because 162 // GL's framebuffer space has (0, 0) at the bottom left. In NDC (-1, -1) is also the 163 // bottom left. However, Skia's device coords has (0, 0) at the top left, so a flip is 164 // required when the origin is kBottomLeft. 165 bool flip = (origin == kBottomLeft_GrSurfaceOrigin); 166 std::array<float, 4> v = SkSL::Compiler::GetRTAdjustVector(dimensions, flip); 167 fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, v.data()); 168 if (fBuiltinUniformHandles.fRTFlipUni.isValid()) { 169 std::array<float, 2> d = SkSL::Compiler::GetRTFlipVector(dimensions.height(), flip); 170 fProgramDataManager.set2fv(fBuiltinUniformHandles.fRTFlipUni, 1, d.data()); 171 } 172 } 173} 174