blob: e96ffa306b2da8be937d9d1bf732acad4001cefe [file] [log] [blame]
junov@google.comf93e7172011-03-31 21:26:24 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * 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.
junov@google.comf93e7172011-03-31 21:26:24 +00006 */
joshualitt23e280d2014-09-18 12:26:38 -07007
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/GrAllocator.h"
9#include "src/gpu/GrCoordTransform.h"
10#include "src/gpu/GrPathProcessor.h"
11#include "src/gpu/GrPipeline.h"
12#include "src/gpu/GrProcessor.h"
13#include "src/gpu/GrTexturePriv.h"
14#include "src/gpu/GrXferProcessor.h"
15#include "src/gpu/gl/GrGLBuffer.h"
16#include "src/gpu/gl/GrGLGpu.h"
17#include "src/gpu/gl/GrGLPathRendering.h"
18#include "src/gpu/gl/GrGLProgram.h"
19#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
20#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
21#include "src/gpu/glsl/GrGLSLXferProcessor.h"
Scroggo97c88c22011-05-11 14:05:25 +000022
commit-bot@chromium.org9188a152013-09-05 18:28:24 +000023#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
24#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X)
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000025
joshualitt47bb3822014-10-07 16:43:25 -070026///////////////////////////////////////////////////////////////////////////////////////////////////
27
Brian Salomon1471df92018-06-08 10:49:00 -040028GrGLProgram::GrGLProgram(
29 GrGLGpu* gpu,
30 const GrGLSLBuiltinUniformHandles& builtinUniforms,
Brian Salomon4d3f5172018-06-07 14:42:52 -040031 GrGLuint programID,
32 const UniformInfoArray& uniforms,
33 const UniformInfoArray& textureSamplers,
Brian Salomon4d3f5172018-06-07 14:42:52 -040034 const VaryingInfoArray& pathProcVaryings,
35 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
36 std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
37 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
Brian Salomon802cb312018-06-08 18:05:20 -040038 int fragmentProcessorCnt,
39 std::unique_ptr<Attribute[]> attributes,
Brian Salomon92be2f72018-06-19 14:33:47 -040040 int vertexAttributeCnt,
41 int instanceAttributeCnt,
Brian Salomon802cb312018-06-08 18:05:20 -040042 int vertexStride,
43 int instanceStride)
Brian Salomon4d3f5172018-06-07 14:42:52 -040044 : fBuiltinUniformHandles(builtinUniforms)
45 , fProgramID(programID)
Brian Salomon802cb312018-06-08 18:05:20 -040046 , fPrimitiveProcessor(std::move(geometryProcessor))
Brian Salomon4d3f5172018-06-07 14:42:52 -040047 , fXferProcessor(std::move(xferProcessor))
48 , fFragmentProcessors(std::move(fragmentProcessors))
49 , fFragmentProcessorCnt(fragmentProcessorCnt)
Brian Salomon802cb312018-06-08 18:05:20 -040050 , fAttributes(std::move(attributes))
Brian Salomon92be2f72018-06-19 14:33:47 -040051 , fVertexAttributeCnt(vertexAttributeCnt)
52 , fInstanceAttributeCnt(instanceAttributeCnt)
Brian Salomon802cb312018-06-08 18:05:20 -040053 , fVertexStride(vertexStride)
54 , fInstanceStride(instanceStride)
Brian Salomon4d3f5172018-06-07 14:42:52 -040055 , fGpu(gpu)
56 , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings)
Brian Salomon662ea4b2018-07-12 14:53:49 -040057 , fNumTextureSamplers(textureSamplers.count()) {
cdalton42717652015-06-18 11:54:30 -070058 // Assign texture units to sampler uniforms one time up front.
59 GL_CALL(UseProgram(fProgramID));
Greg Danielbc5d4d72017-05-05 10:28:42 -040060 fProgramDataManager.setSamplerUniforms(textureSamplers, 0);
junov@google.comf93e7172011-03-31 21:26:24 +000061}
62
63GrGLProgram::~GrGLProgram() {
kkinnunendddc18a2014-08-03 23:19:46 -070064 if (fProgramID) {
65 GL_CALL(DeleteProgram(fProgramID));
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000066 }
junov@google.comf93e7172011-03-31 21:26:24 +000067}
68
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000069void GrGLProgram::abandon() {
kkinnunendddc18a2014-08-03 23:19:46 -070070 fProgramID = 0;
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000071}
72
bsalomon@google.comeb715c82012-07-11 15:03:31 +000073///////////////////////////////////////////////////////////////////////////////
junov@google.comf93e7172011-03-31 21:26:24 +000074
Robert Phillipsd0fe8752019-01-31 14:13:59 -050075void GrGLProgram::updateUniformsAndTextureBindings(const GrRenderTarget* renderTarget,
76 GrSurfaceOrigin origin,
77 const GrPrimitiveProcessor& primProc,
Brian Salomon7eae3e02018-08-07 14:02:38 +000078 const GrPipeline& pipeline,
79 const GrTextureProxy* const primProcTextures[]) {
Robert Phillipsd0fe8752019-01-31 14:13:59 -050080 this->setRenderTargetState(renderTarget, origin, primProc);
bsalomon@google.com91207482013-02-12 21:45:24 +000081
joshualitt47bb3822014-10-07 16:43:25 -070082 // we set the textures, and uniforms for installed processors in a generic way, but subclasses
83 // of GLProgram determine how to set coord transforms
Greg Danielbc5d4d72017-05-05 10:28:42 -040084
85 // We must bind to texture units in the same order in which we set the uniforms in
Brian Salomon662ea4b2018-07-12 14:53:49 -040086 // GrGLProgramDataManager. That is, we bind textures for processors in this order:
87 // primProc, fragProcs, XP.
Brian Salomon802cb312018-06-08 18:05:20 -040088 fPrimitiveProcessor->setData(fProgramDataManager, primProc,
89 GrFragmentProcessor::CoordTransformIter(pipeline));
Brian Salomonf7232642018-09-19 08:58:08 -040090 if (primProcTextures) {
91 this->updatePrimitiveProcessorTextureBindings(primProc, primProcTextures);
Brian Salomone782f842018-07-31 13:53:11 -040092 }
Brian Salomonf7232642018-09-19 08:58:08 -040093 int nextTexSamplerIdx = primProc.numTextureSamplers();
cdalton42717652015-06-18 11:54:30 -070094
Brian Salomone782f842018-07-31 13:53:11 -040095 this->setFragmentData(pipeline, &nextTexSamplerIdx);
joshualitt9b989322014-12-15 14:16:27 -080096
Brian Salomon42c456f2017-03-06 11:29:48 -050097 const GrXferProcessor& xp = pipeline.getXferProcessor();
Brian Salomon18dfa982017-04-03 16:57:43 -040098 SkIPoint offset;
Robert Phillipsbb581ce2017-05-29 15:05:15 -040099 GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
100
Brian Salomon18dfa982017-04-03 16:57:43 -0400101 fXferProcessor->setData(fProgramDataManager, xp, dstTexture, offset);
102 if (dstTexture) {
Brian Osman2b23c4b2018-06-01 12:25:08 -0400103 fGpu->bindTexture(nextTexSamplerIdx++, GrSamplerState::ClampNearest(),
Greg Daniel2c3398d2019-06-19 11:58:01 -0400104 pipeline.dstTextureProxy()->textureSwizzle(),
Brian Salomon930f9392018-06-20 16:25:26 -0400105 static_cast<GrGLTexture*>(dstTexture));
Brian Salomon18dfa982017-04-03 16:57:43 -0400106 }
Greg Danielbc5d4d72017-05-05 10:28:42 -0400107 SkASSERT(nextTexSamplerIdx == fNumTextureSamplers);
joshualitt47bb3822014-10-07 16:43:25 -0700108}
109
Brian Salomonf7232642018-09-19 08:58:08 -0400110void GrGLProgram::updatePrimitiveProcessorTextureBindings(const GrPrimitiveProcessor& primProc,
111 const GrTextureProxy* const proxies[]) {
112 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
113 auto* tex = static_cast<GrGLTexture*>(proxies[i]->peekTexture());
Greg Daniel2c3398d2019-06-19 11:58:01 -0400114 fGpu->bindTexture(i, primProc.textureSampler(i).samplerState(),
115 primProc.textureSampler(i).swizzle(), tex);
Brian Salomonf7232642018-09-19 08:58:08 -0400116 }
117}
118
Brian Salomone782f842018-07-31 13:53:11 -0400119void GrGLProgram::setFragmentData(const GrPipeline& pipeline, int* nextTexSamplerIdx) {
bsalomonb58a2b42016-09-26 06:55:02 -0700120 GrFragmentProcessor::Iter iter(pipeline);
Brian Salomon4d3f5172018-06-07 14:42:52 -0400121 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
bsalomonb58a2b42016-09-26 06:55:02 -0700122 const GrFragmentProcessor* fp = iter.next();
123 GrGLSLFragmentProcessor* glslFP = glslIter.next();
124 while (fp && glslFP) {
125 glslFP->setData(fProgramDataManager, *fp);
Brian Salomone782f842018-07-31 13:53:11 -0400126 for (int i = 0; i < fp->numTextureSamplers(); ++i) {
127 const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i);
Greg Daniel2c3398d2019-06-19 11:58:01 -0400128 fGpu->bindTexture((*nextTexSamplerIdx)++, sampler.samplerState(), sampler.swizzle(),
Brian Salomone782f842018-07-31 13:53:11 -0400129 static_cast<GrGLTexture*>(sampler.peekTexture()));
130 }
mtklein85552e42016-09-26 08:39:43 -0700131 fp = iter.next();
132 glslFP = glslIter.next();
joshualitta5305a12014-10-10 17:47:00 -0700133 }
bsalomonb58a2b42016-09-26 06:55:02 -0700134 SkASSERT(!fp && !glslFP);
joshualitta5305a12014-10-10 17:47:00 -0700135}
bsalomona624bf32016-09-20 09:12:47 -0700136
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500137void GrGLProgram::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin,
138 const GrPrimitiveProcessor& primProc) {
Ethan Nicholascd700e92018-08-24 16:43:57 -0400139 // Load the RT size uniforms if they are needed
140 if (fBuiltinUniformHandles.fRTWidthUni.isValid() &&
141 fRenderTargetState.fRenderTargetSize.fWidth != rt->width()) {
142 fProgramDataManager.set1f(fBuiltinUniformHandles.fRTWidthUni, SkIntToScalar(rt->width()));
143 }
Greg Daniele6ab9982018-08-22 13:56:32 +0000144 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
145 fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
146 fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
joshualitt47bb3822014-10-07 16:43:25 -0700147 }
148
joshualittd8dd47b2015-09-11 11:45:01 -0700149 // set RT adjustment
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000150 SkISize size;
151 size.set(rt->width(), rt->height());
joshualittd8dd47b2015-09-11 11:45:01 -0700152 if (!primProc.isPathRendering()) {
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500153 if (fRenderTargetState.fRenderTargetOrigin != origin ||
joshualittd8dd47b2015-09-11 11:45:01 -0700154 fRenderTargetState.fRenderTargetSize != size) {
155 fRenderTargetState.fRenderTargetSize = size;
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500156 fRenderTargetState.fRenderTargetOrigin = origin;
commit-bot@chromium.org47c66dd2014-05-29 01:12:10 +0000157
egdaniel018fb622015-10-28 07:26:40 -0700158 float rtAdjustmentVec[4];
joshualittd8dd47b2015-09-11 11:45:01 -0700159 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
160 fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
161 }
162 } else {
163 SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport());
164 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
165 fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(),
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500166 size, origin);
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000167 }
168}