blob: 8ef188bf2b074c2471805fc632abe8980ac307cb [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"
kkinnunenec56e452014-08-25 22:21:16 -070014#include "GrGLPathRendering.h"
kkinnunencabe20c2015-06-01 01:37:26 -070015#include "GrPathProcessor.h"
egdaniel8dd688b2015-01-22 10:16:09 -080016#include "GrPipeline.h"
egdanielc2304142014-12-11 13:15:13 -080017#include "GrXferProcessor.h"
egdaniel64c47282015-11-13 06:54:19 -080018#include "glsl/GrGLSLFragmentProcessor.h"
egdaniele659a582015-11-13 09:55:43 -080019#include "glsl/GrGLSLGeometryProcessor.h"
egdanielfa4cc8b2015-11-13 08:34:52 -080020#include "glsl/GrGLSLXferProcessor.h"
Scroggo97c88c22011-05-11 14:05:25 +000021#include "SkXfermode.h"
22
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,
egdaniel0eafe792015-11-20 14:01:22 -080033 const VaryingInfoArray& pathProcVaryings,
egdanielfa896322016-01-13 12:19:30 -080034 GrGLSLPrimitiveProcessor* geometryProcessor,
35 GrGLSLXferProcessor* xferProcessor,
36 const GrGLSLFragProcs& fragmentProcessors,
cdalton42717652015-06-18 11:54:30 -070037 SkTArray<UniformHandle>* passSamplerUniforms)
egdanielcdf79db2015-10-19 07:23:02 -070038 : fBuiltinUniformHandles(builtinUniforms)
joshualitt47bb3822014-10-07 16:43:25 -070039 , fProgramID(programID)
joshualitta5305a12014-10-10 17:47:00 -070040 , fGeometryProcessor(geometryProcessor)
egdanielc2304142014-12-11 13:15:13 -080041 , fXferProcessor(xferProcessor)
egdanielfa896322016-01-13 12:19:30 -080042 , fFragmentProcessors(fragmentProcessors)
commit-bot@chromium.org6eac42e2014-05-29 21:29:51 +000043 , fDesc(desc)
44 , fGpu(gpu)
egdaniel0eafe792015-11-20 14:01:22 -080045 , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings) {
cdalton42717652015-06-18 11:54:30 -070046 fSamplerUniforms.swap(passSamplerUniforms);
47 // Assign texture units to sampler uniforms one time up front.
48 GL_CALL(UseProgram(fProgramID));
49 for (int i = 0; i < fSamplerUniforms.count(); i++) {
50 fProgramDataManager.setSampler(fSamplerUniforms[i], i);
51 }
junov@google.comf93e7172011-03-31 21:26:24 +000052}
53
54GrGLProgram::~GrGLProgram() {
kkinnunendddc18a2014-08-03 23:19:46 -070055 if (fProgramID) {
56 GL_CALL(DeleteProgram(fProgramID));
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000057 }
egdanielfa896322016-01-13 12:19:30 -080058 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
59 delete fFragmentProcessors[i];
60 }
junov@google.comf93e7172011-03-31 21:26:24 +000061}
62
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000063void GrGLProgram::abandon() {
kkinnunendddc18a2014-08-03 23:19:46 -070064 fProgramID = 0;
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000065}
66
bsalomon@google.comeb715c82012-07-11 15:03:31 +000067///////////////////////////////////////////////////////////////////////////////
junov@google.comf93e7172011-03-31 21:26:24 +000068
egdanielfa896322016-01-13 12:19:30 -080069static void append_texture_bindings(const GrProcessor& processor,
cdalton42717652015-06-18 11:54:30 -070070 SkTArray<const GrTextureAccess*>* textureBindings) {
71 if (int numTextures = processor.numTextures()) {
cdalton42717652015-06-18 11:54:30 -070072 const GrTextureAccess** bindings = textureBindings->push_back_n(numTextures);
73 int i = 0;
74 do {
75 bindings[i] = &processor.textureAccess(i);
76 } while (++i < numTextures);
77 }
78}
79
80void GrGLProgram::setData(const GrPrimitiveProcessor& primProc,
81 const GrPipeline& pipeline,
cdalton42717652015-06-18 11:54:30 -070082 SkTArray<const GrTextureAccess*>* textureBindings) {
egdaniel8dd688b2015-01-22 10:16:09 -080083 this->setRenderTargetState(primProc, pipeline);
bsalomon@google.com91207482013-02-12 21:45:24 +000084
joshualitt47bb3822014-10-07 16:43:25 -070085 // we set the textures, and uniforms for installed processors in a generic way, but subclasses
86 // of GLProgram determine how to set coord transforms
egdanielfa896322016-01-13 12:19:30 -080087 fGeometryProcessor->setData(fProgramDataManager, primProc);
88 append_texture_bindings(primProc, textureBindings);
cdalton42717652015-06-18 11:54:30 -070089
90 this->setFragmentData(primProc, pipeline, textureBindings);
joshualitt9b989322014-12-15 14:16:27 -080091
ethannicholas22793252016-01-30 09:59:10 -080092 if (primProc.getPixelLocalStorageState() !=
93 GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState) {
94 const GrXferProcessor& xp = pipeline.getXferProcessor();
95 fXferProcessor->setData(fProgramDataManager, xp);
96 append_texture_bindings(xp, textureBindings);
97 }
joshualitt47bb3822014-10-07 16:43:25 -070098}
99
joshualitt873ad0e2015-01-20 09:08:51 -0800100void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc,
cdalton42717652015-06-18 11:54:30 -0700101 const GrPipeline& pipeline,
102 SkTArray<const GrTextureAccess*>* textureBindings) {
egdanielfa896322016-01-13 12:19:30 -0800103 int numProcessors = fFragmentProcessors.count();
bsalomonac856c92015-08-27 06:30:17 -0700104 for (int i = 0; i < numProcessors; ++i) {
105 const GrFragmentProcessor& processor = pipeline.getFragmentProcessor(i);
egdanielfa896322016-01-13 12:19:30 -0800106 fFragmentProcessors[i]->setData(fProgramDataManager, processor);
107 this->setTransformData(primProc, processor, i);
108 append_texture_bindings(processor, textureBindings);
joshualitta5305a12014-10-10 17:47:00 -0700109 }
110}
joshualitt873ad0e2015-01-20 09:08:51 -0800111void GrGLProgram::setTransformData(const GrPrimitiveProcessor& primProc,
bsalomonac856c92015-08-27 06:30:17 -0700112 const GrFragmentProcessor& processor,
egdanielfa896322016-01-13 12:19:30 -0800113 int index) {
114 fGeometryProcessor->setTransformData(primProc, fProgramDataManager, index,
115 processor.coordTransforms());
skia.committer@gmail.com8ae714b2013-01-05 02:02:05 +0000116}
bsalomon@google.com91207482013-02-12 21:45:24 +0000117
joshualitt873ad0e2015-01-20 09:08:51 -0800118void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
egdaniel8dd688b2015-01-22 10:16:09 -0800119 const GrPipeline& pipeline) {
joshualitt47bb3822014-10-07 16:43:25 -0700120 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
121 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
egdaniel8dd688b2015-01-22 10:16:09 -0800122 fRenderTargetState.fRenderTargetSize.fHeight != pipeline.getRenderTarget()->height()) {
joshualitt47bb3822014-10-07 16:43:25 -0700123 fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni,
egdaniel8dd688b2015-01-22 10:16:09 -0800124 SkIntToScalar(pipeline.getRenderTarget()->height()));
joshualitt47bb3822014-10-07 16:43:25 -0700125 }
126
joshualittd8dd47b2015-09-11 11:45:01 -0700127 // set RT adjustment
egdaniel8dd688b2015-01-22 10:16:09 -0800128 const GrRenderTarget* rt = pipeline.getRenderTarget();
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000129 SkISize size;
130 size.set(rt->width(), rt->height());
joshualittd8dd47b2015-09-11 11:45:01 -0700131 if (!primProc.isPathRendering()) {
132 if (fRenderTargetState.fRenderTargetOrigin != rt->origin() ||
133 fRenderTargetState.fRenderTargetSize != size) {
134 fRenderTargetState.fRenderTargetSize = size;
135 fRenderTargetState.fRenderTargetOrigin = rt->origin();
commit-bot@chromium.org47c66dd2014-05-29 01:12:10 +0000136
egdaniel018fb622015-10-28 07:26:40 -0700137 float rtAdjustmentVec[4];
joshualittd8dd47b2015-09-11 11:45:01 -0700138 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
139 fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
140 }
141 } else {
142 SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport());
143 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
144 fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(),
145 size, rt->origin());
bsalomon@google.com6a51dcb2013-02-13 16:03:51 +0000146 }
147}