blob: 7491b391d035736d070f75f64fc7faf5ff4726e3 [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/GrPathProcessor.h"
9#include "src/gpu/GrPipeline.h"
10#include "src/gpu/GrProcessor.h"
Robert Phillips901aff02019-10-08 12:32:56 -040011#include "src/gpu/GrProgramInfo.h"
Michael Ludwig45191342020-03-24 12:29:39 -040012#include "src/gpu/GrTAllocator.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#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
Robert Phillipsdf546db2020-05-29 09:42:54 -040028sk_sp<GrGLProgram> GrGLProgram::Make(
29 GrGLGpu* gpu,
30 const GrGLSLBuiltinUniformHandles& builtinUniforms,
31 GrGLuint programID,
32 const UniformInfoArray& uniforms,
33 const UniformInfoArray& textureSamplers,
34 const VaryingInfoArray& pathProcVaryings,
35 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
36 std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
37 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fps,
38 int fragmentProcessorCnt,
39 std::unique_ptr<Attribute[]> attributes,
40 int vertexAttributeCnt,
41 int instanceAttributeCnt,
42 int vertexStride,
43 int instanceStride) {
44 sk_sp<GrGLProgram> program(new GrGLProgram(gpu,
45 builtinUniforms,
46 programID,
47 uniforms,
48 textureSamplers,
49 pathProcVaryings,
50 std::move(geometryProcessor),
51 std::move(xferProcessor),
52 std::move(fps),
53 fragmentProcessorCnt,
54 std::move(attributes),
55 vertexAttributeCnt,
56 instanceAttributeCnt,
57 vertexStride,
58 instanceStride));
59 // Assign texture units to sampler uniforms one time up front.
60 gpu->flushProgram(program);
61 program->fProgramDataManager.setSamplerUniforms(textureSamplers, 0);
62 return program;
63}
64
Brian Salomon1471df92018-06-08 10:49:00 -040065GrGLProgram::GrGLProgram(
66 GrGLGpu* gpu,
67 const GrGLSLBuiltinUniformHandles& builtinUniforms,
Brian Salomon4d3f5172018-06-07 14:42:52 -040068 GrGLuint programID,
69 const UniformInfoArray& uniforms,
70 const UniformInfoArray& textureSamplers,
Brian Salomon4d3f5172018-06-07 14:42:52 -040071 const VaryingInfoArray& pathProcVaryings,
72 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
73 std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
Robert Phillipsdf546db2020-05-29 09:42:54 -040074 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fps,
Brian Salomon802cb312018-06-08 18:05:20 -040075 int fragmentProcessorCnt,
76 std::unique_ptr<Attribute[]> attributes,
Brian Salomon92be2f72018-06-19 14:33:47 -040077 int vertexAttributeCnt,
78 int instanceAttributeCnt,
Brian Salomon802cb312018-06-08 18:05:20 -040079 int vertexStride,
80 int instanceStride)
Brian Salomon4d3f5172018-06-07 14:42:52 -040081 : fBuiltinUniformHandles(builtinUniforms)
82 , fProgramID(programID)
Brian Salomon802cb312018-06-08 18:05:20 -040083 , fPrimitiveProcessor(std::move(geometryProcessor))
Brian Salomon4d3f5172018-06-07 14:42:52 -040084 , fXferProcessor(std::move(xferProcessor))
Robert Phillipsdf546db2020-05-29 09:42:54 -040085 , fFragmentProcessors(std::move(fps))
Brian Salomon4d3f5172018-06-07 14:42:52 -040086 , fFragmentProcessorCnt(fragmentProcessorCnt)
Brian Salomon802cb312018-06-08 18:05:20 -040087 , fAttributes(std::move(attributes))
Brian Salomon92be2f72018-06-19 14:33:47 -040088 , fVertexAttributeCnt(vertexAttributeCnt)
89 , fInstanceAttributeCnt(instanceAttributeCnt)
Brian Salomon802cb312018-06-08 18:05:20 -040090 , fVertexStride(vertexStride)
91 , fInstanceStride(instanceStride)
Brian Salomon4d3f5172018-06-07 14:42:52 -040092 , fGpu(gpu)
93 , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings)
Brian Salomon662ea4b2018-07-12 14:53:49 -040094 , fNumTextureSamplers(textureSamplers.count()) {
junov@google.comf93e7172011-03-31 21:26:24 +000095}
96
97GrGLProgram::~GrGLProgram() {
kkinnunendddc18a2014-08-03 23:19:46 -070098 if (fProgramID) {
99 GL_CALL(DeleteProgram(fProgramID));
bsalomon@google.comecb60aa2012-07-18 13:20:29 +0000100 }
junov@google.comf93e7172011-03-31 21:26:24 +0000101}
102
bsalomon@google.comecb60aa2012-07-18 13:20:29 +0000103void GrGLProgram::abandon() {
kkinnunendddc18a2014-08-03 23:19:46 -0700104 fProgramID = 0;
bsalomon@google.comecb60aa2012-07-18 13:20:29 +0000105}
106
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000107///////////////////////////////////////////////////////////////////////////////
junov@google.comf93e7172011-03-31 21:26:24 +0000108
Chris Dalton3ffa7af2020-02-20 16:31:47 -0700109void GrGLProgram::updateUniforms(const GrRenderTarget* renderTarget,
110 const GrProgramInfo& programInfo) {
Robert Phillips901aff02019-10-08 12:32:56 -0400111 this->setRenderTargetState(renderTarget, programInfo.origin(), programInfo.primProc());
bsalomon@google.com91207482013-02-12 21:45:24 +0000112
Chris Dalton3ffa7af2020-02-20 16:31:47 -0700113 // we set the uniforms for installed processors in a generic way, but subclasses of GLProgram
114 // determine how to set coord transforms
Greg Danielbc5d4d72017-05-05 10:28:42 -0400115
116 // We must bind to texture units in the same order in which we set the uniforms in
Brian Salomon662ea4b2018-07-12 14:53:49 -0400117 // GrGLProgramDataManager. That is, we bind textures for processors in this order:
118 // primProc, fragProcs, XP.
Brian Salomonc241b582019-11-27 08:57:17 -0500119 GrFragmentProcessor::PipelineCoordTransformRange range(programInfo.pipeline());
120 fPrimitiveProcessor->setData(fProgramDataManager, programInfo.primProc(), range);
cdalton42717652015-06-18 11:54:30 -0700121
Chris Dalton3ffa7af2020-02-20 16:31:47 -0700122 GrFragmentProcessor::CIter fpIter(programInfo.pipeline());
123 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
124 for (; fpIter && glslIter; ++fpIter, ++glslIter) {
125 glslIter->setData(fProgramDataManager, *fpIter);
126 }
127 SkASSERT(!fpIter && !glslIter);
joshualitt9b989322014-12-15 14:16:27 -0800128
Robert Phillips901aff02019-10-08 12:32:56 -0400129 const GrXferProcessor& xp = programInfo.pipeline().getXferProcessor();
Brian Salomon18dfa982017-04-03 16:57:43 -0400130 SkIPoint offset;
Robert Phillips901aff02019-10-08 12:32:56 -0400131 GrTexture* dstTexture = programInfo.pipeline().peekDstTexture(&offset);
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400132
Brian Salomon18dfa982017-04-03 16:57:43 -0400133 fXferProcessor->setData(fProgramDataManager, xp, dstTexture, offset);
joshualitt47bb3822014-10-07 16:43:25 -0700134}
135
Chris Daltondb20afc2020-03-05 12:13:53 -0700136void GrGLProgram::bindTextures(const GrPrimitiveProcessor& primProc,
137 const GrSurfaceProxy* const primProcTextures[],
138 const GrPipeline& pipeline) {
Brian Salomonf7232642018-09-19 08:58:08 -0400139 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
Chris Dalton2e7ed262020-02-21 15:17:59 -0700140 SkASSERT(primProcTextures[i]->asTextureProxy());
141 auto* overrideTexture = static_cast<GrGLTexture*>(primProcTextures[i]->peekTexture());
Greg Daniel2c3398d2019-06-19 11:58:01 -0400142 fGpu->bindTexture(i, primProc.textureSampler(i).samplerState(),
Chris Dalton3ffa7af2020-02-20 16:31:47 -0700143 primProc.textureSampler(i).swizzle(), overrideTexture);
Brian Salomonf7232642018-09-19 08:58:08 -0400144 }
Chris Dalton3ffa7af2020-02-20 16:31:47 -0700145 int nextTexSamplerIdx = primProc.numTextureSamplers();
Brian Salomonf7232642018-09-19 08:58:08 -0400146
Brian Salomon7eabfe82019-12-02 14:20:20 -0500147 GrFragmentProcessor::CIter fpIter(pipeline);
Chris Dalton3ffa7af2020-02-20 16:31:47 -0700148 for (; fpIter; ++fpIter) {
Brian Salomonc241b582019-11-27 08:57:17 -0500149 for (int i = 0; i < fpIter->numTextureSamplers(); ++i) {
150 const GrFragmentProcessor::TextureSampler& sampler = fpIter->textureSampler(i);
Chris Dalton3ffa7af2020-02-20 16:31:47 -0700151 fGpu->bindTexture(nextTexSamplerIdx++, sampler.samplerState(), sampler.view().swizzle(),
Brian Salomone782f842018-07-31 13:53:11 -0400152 static_cast<GrGLTexture*>(sampler.peekTexture()));
153 }
joshualitta5305a12014-10-10 17:47:00 -0700154 }
Chris Dalton3ffa7af2020-02-20 16:31:47 -0700155
156 SkIPoint offset;
157 GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
158 if (dstTexture) {
159 fGpu->bindTexture(nextTexSamplerIdx++, GrSamplerState::Filter::kNearest,
160 pipeline.dstProxyView().swizzle(), static_cast<GrGLTexture*>(dstTexture));
161 }
162 SkASSERT(nextTexSamplerIdx == fNumTextureSamplers);
joshualitta5305a12014-10-10 17:47:00 -0700163}
bsalomona624bf32016-09-20 09:12:47 -0700164
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500165void GrGLProgram::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin,
166 const GrPrimitiveProcessor& primProc) {
Ethan Nicholascd700e92018-08-24 16:43:57 -0400167 // Load the RT size uniforms if they are needed
168 if (fBuiltinUniformHandles.fRTWidthUni.isValid() &&
169 fRenderTargetState.fRenderTargetSize.fWidth != rt->width()) {
170 fProgramDataManager.set1f(fBuiltinUniformHandles.fRTWidthUni, SkIntToScalar(rt->width()));
171 }
Greg Daniele6ab9982018-08-22 13:56:32 +0000172 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
173 fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
174 fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
joshualitt47bb3822014-10-07 16:43:25 -0700175 }
176
joshualittd8dd47b2015-09-11 11:45:01 -0700177 // set RT adjustment
Brian Salomon9f2b86c2019-10-22 10:37:46 -0400178 SkISize dimensions = rt->dimensions();
joshualittd8dd47b2015-09-11 11:45:01 -0700179 if (!primProc.isPathRendering()) {
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500180 if (fRenderTargetState.fRenderTargetOrigin != origin ||
Brian Salomon9f2b86c2019-10-22 10:37:46 -0400181 fRenderTargetState.fRenderTargetSize != dimensions) {
182 fRenderTargetState.fRenderTargetSize = dimensions;
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500183 fRenderTargetState.fRenderTargetOrigin = origin;
commit-bot@chromium.org47c66dd2014-05-29 01:12:10 +0000184
egdaniel018fb622015-10-28 07:26:40 -0700185 float rtAdjustmentVec[4];
joshualittd8dd47b2015-09-11 11:45:01 -0700186 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
187 fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
188 }
189 } else {
190 SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport());
191 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
Brian Salomon9f2b86c2019-10-22 10:37:46 -0400192 fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(), dimensions, origin);
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000193 }
194}