blob: 50cbdc1233ccbd59ab4b49490c08c938de22030b [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
junov@google.comf93e7172011-03-31 21:26:24 +00008#include "GrGLProgram.h"
9
tomhudson@google.comd8f856c2012-05-10 12:13:36 +000010#include "GrAllocator.h"
joshualittb0a8a372014-09-23 09:50:21 -070011#include "GrProcessor.h"
bsalomon@google.com77af6802013-10-02 13:04:56 +000012#include "GrCoordTransform.h"
jvanverth39edf762014-12-22 11:44:19 -080013#include "GrGLGpu.h"
cdalton74b8d322016-04-11 14:47:28 -070014#include "GrGLBuffer.h"
kkinnunenec56e452014-08-25 22:21:16 -070015#include "GrGLPathRendering.h"
kkinnunencabe20c2015-06-01 01:37:26 -070016#include "GrPathProcessor.h"
egdaniel8dd688b2015-01-22 10:16:09 -080017#include "GrPipeline.h"
egdanielc2304142014-12-11 13:15:13 -080018#include "GrXferProcessor.h"
egdaniel64c47282015-11-13 06:54:19 -080019#include "glsl/GrGLSLFragmentProcessor.h"
egdaniele659a582015-11-13 09:55:43 -080020#include "glsl/GrGLSLGeometryProcessor.h"
egdanielfa4cc8b2015-11-13 08:34:52 -080021#include "glsl/GrGLSLXferProcessor.h"
Scroggo97c88c22011-05-11 14:05:25 +000022#include "SkXfermode.h"
23
commit-bot@chromium.org9188a152013-09-05 18:28:24 +000024#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
25#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X)
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000026
joshualitt47bb3822014-10-07 16:43:25 -070027///////////////////////////////////////////////////////////////////////////////////////////////////
28
bsalomon861e1032014-12-16 07:33:49 -080029GrGLProgram::GrGLProgram(GrGLGpu* gpu,
joshualitt79f8fae2014-10-28 17:59:26 -070030 const GrProgramDesc& desc,
joshualitt47bb3822014-10-07 16:43:25 -070031 const BuiltinUniformHandles& builtinUniforms,
32 GrGLuint programID,
33 const UniformInfoArray& uniforms,
egdaniel09aa1fc2016-04-20 07:09:46 -070034 const SkTArray<GrGLSampler>& samplers,
egdaniel0eafe792015-11-20 14:01:22 -080035 const VaryingInfoArray& pathProcVaryings,
egdanielfa896322016-01-13 12:19:30 -080036 GrGLSLPrimitiveProcessor* geometryProcessor,
37 GrGLSLXferProcessor* xferProcessor,
egdaniel09aa1fc2016-04-20 07:09:46 -070038 const GrGLSLFragProcs& fragmentProcessors)
egdanielcdf79db2015-10-19 07:23:02 -070039 : fBuiltinUniformHandles(builtinUniforms)
joshualitt47bb3822014-10-07 16:43:25 -070040 , fProgramID(programID)
joshualitta5305a12014-10-10 17:47:00 -070041 , fGeometryProcessor(geometryProcessor)
egdanielc2304142014-12-11 13:15:13 -080042 , fXferProcessor(xferProcessor)
egdanielfa896322016-01-13 12:19:30 -080043 , fFragmentProcessors(fragmentProcessors)
commit-bot@chromium.org6eac42e2014-05-29 21:29:51 +000044 , fDesc(desc)
45 , fGpu(gpu)
egdaniel0eafe792015-11-20 14:01:22 -080046 , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings) {
cdalton42717652015-06-18 11:54:30 -070047 // Assign texture units to sampler uniforms one time up front.
48 GL_CALL(UseProgram(fProgramID));
egdaniel09aa1fc2016-04-20 07:09:46 -070049 fProgramDataManager.setSamplers(samplers);
junov@google.comf93e7172011-03-31 21:26:24 +000050}
51
52GrGLProgram::~GrGLProgram() {
kkinnunendddc18a2014-08-03 23:19:46 -070053 if (fProgramID) {
54 GL_CALL(DeleteProgram(fProgramID));
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000055 }
egdanielfa896322016-01-13 12:19:30 -080056 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
57 delete fFragmentProcessors[i];
58 }
junov@google.comf93e7172011-03-31 21:26:24 +000059}
60
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000061void GrGLProgram::abandon() {
kkinnunendddc18a2014-08-03 23:19:46 -070062 fProgramID = 0;
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000063}
64
bsalomon@google.comeb715c82012-07-11 15:03:31 +000065///////////////////////////////////////////////////////////////////////////////
junov@google.comf93e7172011-03-31 21:26:24 +000066
cdalton74b8d322016-04-11 14:47:28 -070067void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline) {
egdaniel8dd688b2015-01-22 10:16:09 -080068 this->setRenderTargetState(primProc, pipeline);
bsalomon@google.com91207482013-02-12 21:45:24 +000069
joshualitt47bb3822014-10-07 16:43:25 -070070 // we set the textures, and uniforms for installed processors in a generic way, but subclasses
71 // of GLProgram determine how to set coord transforms
cdalton74b8d322016-04-11 14:47:28 -070072 int nextSamplerIdx = 0;
bsalomona624bf32016-09-20 09:12:47 -070073 fGeometryProcessor->setData(fProgramDataManager, primProc,
74 GrFragmentProcessor::CoordTransformIter(pipeline));
cdalton74b8d322016-04-11 14:47:28 -070075 this->bindTextures(primProc, pipeline.getAllowSRGBInputs(), &nextSamplerIdx);
cdalton42717652015-06-18 11:54:30 -070076
cdalton74b8d322016-04-11 14:47:28 -070077 this->setFragmentData(primProc, pipeline, &nextSamplerIdx);
joshualitt9b989322014-12-15 14:16:27 -080078
halcanary9d524f22016-03-29 09:03:52 -070079 if (primProc.getPixelLocalStorageState() !=
ethannicholas22793252016-01-30 09:59:10 -080080 GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState) {
81 const GrXferProcessor& xp = pipeline.getXferProcessor();
82 fXferProcessor->setData(fProgramDataManager, xp);
cdalton74b8d322016-04-11 14:47:28 -070083 this->bindTextures(xp, pipeline.getAllowSRGBInputs(), &nextSamplerIdx);
ethannicholas22793252016-01-30 09:59:10 -080084 }
joshualitt47bb3822014-10-07 16:43:25 -070085}
86
brianosman33f6b3f2016-06-02 05:49:21 -070087void GrGLProgram::generateMipmaps(const GrPrimitiveProcessor& primProc,
88 const GrPipeline& pipeline) {
89 this->generateMipmaps(primProc, pipeline.getAllowSRGBInputs());
90
bsalomonb58a2b42016-09-26 06:55:02 -070091 GrFragmentProcessor::Iter iter(pipeline);
92 while (const GrFragmentProcessor* fp = iter.next()) {
93 this->generateMipmaps(*fp, pipeline.getAllowSRGBInputs());
brianosman33f6b3f2016-06-02 05:49:21 -070094 }
95
96 if (primProc.getPixelLocalStorageState() !=
97 GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState) {
98 const GrXferProcessor& xp = pipeline.getXferProcessor();
99 this->generateMipmaps(xp, pipeline.getAllowSRGBInputs());
100 }
101}
102
joshualitt873ad0e2015-01-20 09:08:51 -0800103void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc,
cdalton42717652015-06-18 11:54:30 -0700104 const GrPipeline& pipeline,
cdalton74b8d322016-04-11 14:47:28 -0700105 int* nextSamplerIdx) {
bsalomonb58a2b42016-09-26 06:55:02 -0700106 GrFragmentProcessor::Iter iter(pipeline);
107 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.begin(),
108 fFragmentProcessors.count());
109 const GrFragmentProcessor* fp = iter.next();
110 GrGLSLFragmentProcessor* glslFP = glslIter.next();
111 while (fp && glslFP) {
112 glslFP->setData(fProgramDataManager, *fp);
113 this->bindTextures(*fp, pipeline.getAllowSRGBInputs(), nextSamplerIdx);
mtklein85552e42016-09-26 08:39:43 -0700114 fp = iter.next();
115 glslFP = glslIter.next();
joshualitta5305a12014-10-10 17:47:00 -0700116 }
bsalomonb58a2b42016-09-26 06:55:02 -0700117 SkASSERT(!fp && !glslFP);
joshualitta5305a12014-10-10 17:47:00 -0700118}
bsalomona624bf32016-09-20 09:12:47 -0700119
bsalomon@google.com91207482013-02-12 21:45:24 +0000120
joshualitt873ad0e2015-01-20 09:08:51 -0800121void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
egdaniel8dd688b2015-01-22 10:16:09 -0800122 const GrPipeline& pipeline) {
joshualitt47bb3822014-10-07 16:43:25 -0700123 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
124 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
egdaniel8dd688b2015-01-22 10:16:09 -0800125 fRenderTargetState.fRenderTargetSize.fHeight != pipeline.getRenderTarget()->height()) {
joshualitt47bb3822014-10-07 16:43:25 -0700126 fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni,
egdaniel8dd688b2015-01-22 10:16:09 -0800127 SkIntToScalar(pipeline.getRenderTarget()->height()));
joshualitt47bb3822014-10-07 16:43:25 -0700128 }
129
joshualittd8dd47b2015-09-11 11:45:01 -0700130 // set RT adjustment
egdaniel8dd688b2015-01-22 10:16:09 -0800131 const GrRenderTarget* rt = pipeline.getRenderTarget();
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000132 SkISize size;
133 size.set(rt->width(), rt->height());
joshualittd8dd47b2015-09-11 11:45:01 -0700134 if (!primProc.isPathRendering()) {
135 if (fRenderTargetState.fRenderTargetOrigin != rt->origin() ||
136 fRenderTargetState.fRenderTargetSize != size) {
137 fRenderTargetState.fRenderTargetSize = size;
138 fRenderTargetState.fRenderTargetOrigin = rt->origin();
commit-bot@chromium.org47c66dd2014-05-29 01:12:10 +0000139
egdaniel018fb622015-10-28 07:26:40 -0700140 float rtAdjustmentVec[4];
joshualittd8dd47b2015-09-11 11:45:01 -0700141 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
142 fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
143 }
144 } else {
145 SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport());
146 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
147 fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(),
148 size, rt->origin());
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000149 }
150}
cdalton74b8d322016-04-11 14:47:28 -0700151
152void GrGLProgram::bindTextures(const GrProcessor& processor,
153 bool allowSRGBInputs,
154 int* nextSamplerIdx) {
Brian Salomon0bbecb22016-11-17 11:38:22 -0500155 for (int i = 0; i < processor.numTextureSamplers(); ++i) {
156 const GrProcessor::TextureSampler& sampler = processor.textureSampler(i);
Brian Salomondb4183d2016-11-17 12:48:40 -0500157 fGpu->bindTexture((*nextSamplerIdx)++, sampler.params(),
158 allowSRGBInputs, static_cast<GrGLTexture*>(sampler.texture()));
cdalton74b8d322016-04-11 14:47:28 -0700159 }
160 for (int i = 0; i < processor.numBuffers(); ++i) {
161 const GrBufferAccess& access = processor.bufferAccess(i);
csmartdalton1897cfd2016-06-03 08:50:54 -0700162 fGpu->bindTexelBuffer((*nextSamplerIdx)++, access.texelConfig(),
cdalton74b8d322016-04-11 14:47:28 -0700163 static_cast<GrGLBuffer*>(access.buffer()));
164 }
165}
brianosman33f6b3f2016-06-02 05:49:21 -0700166
167void GrGLProgram::generateMipmaps(const GrProcessor& processor,
168 bool allowSRGBInputs) {
Brian Salomon0bbecb22016-11-17 11:38:22 -0500169 for (int i = 0; i < processor.numTextureSamplers(); ++i) {
170 const GrProcessor::TextureSampler& sampler = processor.textureSampler(i);
Brian Salomondb4183d2016-11-17 12:48:40 -0500171 fGpu->generateMipmaps(sampler.params(), allowSRGBInputs,
172 static_cast<GrGLTexture*>(sampler.texture()));
brianosman33f6b3f2016-06-02 05:49:21 -0700173 }
174}