xref: /third_party/skia/src/gpu/gl/GrGLProgram.cpp (revision cb93a386)
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