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