blob: f7e337c7ffd58e12e6650fa88cf0884adf6efe1b [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
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
bsalomon861e1032014-12-16 07:33:49 -080028GrGLProgram::GrGLProgram(GrGLGpu* gpu,
joshualitt79f8fae2014-10-28 17:59:26 -070029 const GrProgramDesc& desc,
joshualitt47bb3822014-10-07 16:43:25 -070030 const BuiltinUniformHandles& builtinUniforms,
31 GrGLuint programID,
32 const UniformInfoArray& uniforms,
Greg Danielbc5d4d72017-05-05 10:28:42 -040033 const UniformInfoArray& textureSamplers,
34 const UniformInfoArray& texelBuffers,
Brian Salomonf9f45122016-11-29 11:59:17 -050035 const UniformInfoArray& imageStorages,
egdaniel0eafe792015-11-20 14:01:22 -080036 const VaryingInfoArray& pathProcVaryings,
Robert Phillips369e8b72017-08-01 16:13:04 -040037 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
38 std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
egdaniel09aa1fc2016-04-20 07:09:46 -070039 const GrGLSLFragProcs& fragmentProcessors)
egdanielcdf79db2015-10-19 07:23:02 -070040 : fBuiltinUniformHandles(builtinUniforms)
joshualitt47bb3822014-10-07 16:43:25 -070041 , fProgramID(programID)
Robert Phillips369e8b72017-08-01 16:13:04 -040042 , fGeometryProcessor(std::move(geometryProcessor))
43 , fXferProcessor(std::move(xferProcessor))
egdanielfa896322016-01-13 12:19:30 -080044 , fFragmentProcessors(fragmentProcessors)
commit-bot@chromium.org6eac42e2014-05-29 21:29:51 +000045 , fDesc(desc)
46 , fGpu(gpu)
Greg Danielbc5d4d72017-05-05 10:28:42 -040047 , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings)
48 , fNumTextureSamplers(textureSamplers.count())
49 , fNumTexelBuffers(texelBuffers.count()) {
cdalton42717652015-06-18 11:54:30 -070050 // Assign texture units to sampler uniforms one time up front.
51 GL_CALL(UseProgram(fProgramID));
Greg Danielbc5d4d72017-05-05 10:28:42 -040052 fProgramDataManager.setSamplerUniforms(textureSamplers, 0);
53 fProgramDataManager.setSamplerUniforms(texelBuffers, fNumTextureSamplers);
Brian Salomonf9f45122016-11-29 11:59:17 -050054 fProgramDataManager.setImageStorages(imageStorages);
junov@google.comf93e7172011-03-31 21:26:24 +000055}
56
57GrGLProgram::~GrGLProgram() {
kkinnunendddc18a2014-08-03 23:19:46 -070058 if (fProgramID) {
59 GL_CALL(DeleteProgram(fProgramID));
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000060 }
egdanielfa896322016-01-13 12:19:30 -080061 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
62 delete fFragmentProcessors[i];
63 }
junov@google.comf93e7172011-03-31 21:26:24 +000064}
65
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000066void GrGLProgram::abandon() {
kkinnunendddc18a2014-08-03 23:19:46 -070067 fProgramID = 0;
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000068}
69
bsalomon@google.comeb715c82012-07-11 15:03:31 +000070///////////////////////////////////////////////////////////////////////////////
junov@google.comf93e7172011-03-31 21:26:24 +000071
cdalton74b8d322016-04-11 14:47:28 -070072void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline) {
Robert Phillipsb0e93a22017-08-29 08:26:54 -040073 this->setRenderTargetState(primProc, pipeline.proxy());
bsalomon@google.com91207482013-02-12 21:45:24 +000074
joshualitt47bb3822014-10-07 16:43:25 -070075 // we set the textures, and uniforms for installed processors in a generic way, but subclasses
76 // of GLProgram determine how to set coord transforms
Greg Danielbc5d4d72017-05-05 10:28:42 -040077
78 // We must bind to texture units in the same order in which we set the uniforms in
79 // GrGLProgramDataManager. That is first all texture samplers and then texel buffers.
80 // ImageStorages are bound to their own image units so they are tracked separately.
81 // Within each group we will bind them in primProc, fragProcs, XP order.
82 int nextTexSamplerIdx = 0;
83 int nextTexelBufferIdx = fNumTextureSamplers;
84 int nextImageStorageIdx = 0;
bsalomona624bf32016-09-20 09:12:47 -070085 fGeometryProcessor->setData(fProgramDataManager, primProc,
86 GrFragmentProcessor::CoordTransformIter(pipeline));
Greg Danielbc5d4d72017-05-05 10:28:42 -040087 this->bindTextures(primProc, pipeline.getAllowSRGBInputs(), &nextTexSamplerIdx,
88 &nextTexelBufferIdx, &nextImageStorageIdx);
cdalton42717652015-06-18 11:54:30 -070089
Greg Danielbc5d4d72017-05-05 10:28:42 -040090 this->setFragmentData(primProc, pipeline, &nextTexSamplerIdx, &nextTexelBufferIdx,
91 &nextImageStorageIdx);
joshualitt9b989322014-12-15 14:16:27 -080092
Brian Salomon42c456f2017-03-06 11:29:48 -050093 const GrXferProcessor& xp = pipeline.getXferProcessor();
Brian Salomon18dfa982017-04-03 16:57:43 -040094 SkIPoint offset;
Robert Phillipsbb581ce2017-05-29 15:05:15 -040095 GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
96
Brian Salomon18dfa982017-04-03 16:57:43 -040097 fXferProcessor->setData(fProgramDataManager, xp, dstTexture, offset);
98 if (dstTexture) {
Greg Danielbc5d4d72017-05-05 10:28:42 -040099 fGpu->bindTexture(nextTexSamplerIdx++, GrSamplerParams::ClampNoFilter(), true,
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400100 static_cast<GrGLTexture*>(dstTexture),
101 pipeline.dstTextureProxy()->origin());
Brian Salomon18dfa982017-04-03 16:57:43 -0400102 }
Greg Danielbc5d4d72017-05-05 10:28:42 -0400103 SkASSERT(nextTexSamplerIdx == fNumTextureSamplers);
104 SkASSERT(nextTexelBufferIdx == fNumTextureSamplers + fNumTexelBuffers);
joshualitt47bb3822014-10-07 16:43:25 -0700105}
106
brianosman33f6b3f2016-06-02 05:49:21 -0700107void GrGLProgram::generateMipmaps(const GrPrimitiveProcessor& primProc,
108 const GrPipeline& pipeline) {
109 this->generateMipmaps(primProc, pipeline.getAllowSRGBInputs());
110
bsalomonb58a2b42016-09-26 06:55:02 -0700111 GrFragmentProcessor::Iter iter(pipeline);
112 while (const GrFragmentProcessor* fp = iter.next()) {
113 this->generateMipmaps(*fp, pipeline.getAllowSRGBInputs());
brianosman33f6b3f2016-06-02 05:49:21 -0700114 }
brianosman33f6b3f2016-06-02 05:49:21 -0700115}
116
joshualitt873ad0e2015-01-20 09:08:51 -0800117void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc,
cdalton42717652015-06-18 11:54:30 -0700118 const GrPipeline& pipeline,
Greg Danielbc5d4d72017-05-05 10:28:42 -0400119 int* nextTexSamplerIdx,
120 int* nextTexelBufferIdx,
121 int* nextImageStorageIdx) {
bsalomonb58a2b42016-09-26 06:55:02 -0700122 GrFragmentProcessor::Iter iter(pipeline);
123 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.begin(),
124 fFragmentProcessors.count());
125 const GrFragmentProcessor* fp = iter.next();
126 GrGLSLFragmentProcessor* glslFP = glslIter.next();
127 while (fp && glslFP) {
128 glslFP->setData(fProgramDataManager, *fp);
Greg Danielbc5d4d72017-05-05 10:28:42 -0400129 this->bindTextures(*fp, pipeline.getAllowSRGBInputs(), nextTexSamplerIdx,
130 nextTexelBufferIdx, nextImageStorageIdx);
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
bsalomon@google.com91207482013-02-12 21:45:24 +0000137
joshualitt873ad0e2015-01-20 09:08:51 -0800138void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400139 const GrRenderTargetProxy* proxy) {
140 GrRenderTarget* rt = proxy->priv().peekRenderTarget();
joshualitt47bb3822014-10-07 16:43:25 -0700141 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
142 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
Robert Phillips02bb6df2017-03-28 17:11:19 -0400143 fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
144 fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
joshualitt47bb3822014-10-07 16:43:25 -0700145 }
146
joshualittd8dd47b2015-09-11 11:45:01 -0700147 // set RT adjustment
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000148 SkISize size;
149 size.set(rt->width(), rt->height());
joshualittd8dd47b2015-09-11 11:45:01 -0700150 if (!primProc.isPathRendering()) {
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400151 if (fRenderTargetState.fRenderTargetOrigin != proxy->origin() ||
joshualittd8dd47b2015-09-11 11:45:01 -0700152 fRenderTargetState.fRenderTargetSize != size) {
153 fRenderTargetState.fRenderTargetSize = size;
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400154 fRenderTargetState.fRenderTargetOrigin = proxy->origin();
commit-bot@chromium.org47c66dd2014-05-29 01:12:10 +0000155
egdaniel018fb622015-10-28 07:26:40 -0700156 float rtAdjustmentVec[4];
joshualittd8dd47b2015-09-11 11:45:01 -0700157 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
158 fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
159 }
160 } else {
161 SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport());
162 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
163 fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(),
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400164 size, proxy->origin());
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000165 }
166}
cdalton74b8d322016-04-11 14:47:28 -0700167
Brian Salomonab015ef2017-04-04 10:15:51 -0400168void GrGLProgram::bindTextures(const GrResourceIOProcessor& processor,
cdalton74b8d322016-04-11 14:47:28 -0700169 bool allowSRGBInputs,
Greg Danielbc5d4d72017-05-05 10:28:42 -0400170 int* nextTexSamplerIdx,
171 int* nextTexelBufferIdx,
172 int* nextImageStorageIdx) {
Brian Salomon0bbecb22016-11-17 11:38:22 -0500173 for (int i = 0; i < processor.numTextureSamplers(); ++i) {
Brian Salomonab015ef2017-04-04 10:15:51 -0400174 const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i);
Greg Danielbc5d4d72017-05-05 10:28:42 -0400175 fGpu->bindTexture((*nextTexSamplerIdx)++, sampler.params(),
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400176 allowSRGBInputs, static_cast<GrGLTexture*>(sampler.peekTexture()),
177 sampler.proxy()->origin());
cdalton74b8d322016-04-11 14:47:28 -0700178 }
179 for (int i = 0; i < processor.numBuffers(); ++i) {
Brian Salomonab015ef2017-04-04 10:15:51 -0400180 const GrResourceIOProcessor::BufferAccess& access = processor.bufferAccess(i);
Greg Danielbc5d4d72017-05-05 10:28:42 -0400181 fGpu->bindTexelBuffer((*nextTexelBufferIdx)++, access.texelConfig(),
cdalton74b8d322016-04-11 14:47:28 -0700182 static_cast<GrGLBuffer*>(access.buffer()));
183 }
Brian Salomonf9f45122016-11-29 11:59:17 -0500184 for (int i = 0; i < processor.numImageStorages(); ++i) {
Brian Salomonab015ef2017-04-04 10:15:51 -0400185 const GrResourceIOProcessor::ImageStorageAccess& access = processor.imageStorageAccess(i);
Greg Danielbc5d4d72017-05-05 10:28:42 -0400186 fGpu->bindImageStorage((*nextImageStorageIdx)++, access.ioType(),
Robert Phillips9bee2e52017-05-29 12:37:20 -0400187 static_cast<GrGLTexture *>(access.peekTexture()));
Brian Salomonf9f45122016-11-29 11:59:17 -0500188 }
cdalton74b8d322016-04-11 14:47:28 -0700189}
brianosman33f6b3f2016-06-02 05:49:21 -0700190
Brian Salomonab015ef2017-04-04 10:15:51 -0400191void GrGLProgram::generateMipmaps(const GrResourceIOProcessor& processor, bool allowSRGBInputs) {
Brian Salomon0bbecb22016-11-17 11:38:22 -0500192 for (int i = 0; i < processor.numTextureSamplers(); ++i) {
Brian Salomonab015ef2017-04-04 10:15:51 -0400193 const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i);
Brian Salomondb4183d2016-11-17 12:48:40 -0500194 fGpu->generateMipmaps(sampler.params(), allowSRGBInputs,
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400195 static_cast<GrGLTexture*>(sampler.peekTexture()),
196 sampler.proxy()->origin());
brianosman33f6b3f2016-06-02 05:49:21 -0700197 }
198}