Line data Source code
1 : /*
2 : * 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.
6 : */
7 :
8 : #include "GrGLProgram.h"
9 :
10 : #include "GrAllocator.h"
11 : #include "GrProcessor.h"
12 : #include "GrCoordTransform.h"
13 : #include "GrGLGpu.h"
14 : #include "GrGLBuffer.h"
15 : #include "GrGLPathRendering.h"
16 : #include "GrPathProcessor.h"
17 : #include "GrPipeline.h"
18 : #include "GrXferProcessor.h"
19 : #include "glsl/GrGLSLFragmentProcessor.h"
20 : #include "glsl/GrGLSLGeometryProcessor.h"
21 : #include "glsl/GrGLSLXferProcessor.h"
22 :
23 : #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)
25 :
26 : ///////////////////////////////////////////////////////////////////////////////////////////////////
27 :
28 0 : GrGLProgram::GrGLProgram(GrGLGpu* gpu,
29 : const GrProgramDesc& desc,
30 : const BuiltinUniformHandles& builtinUniforms,
31 : GrGLuint programID,
32 : const UniformInfoArray& uniforms,
33 : const UniformInfoArray& samplers,
34 : const UniformInfoArray& imageStorages,
35 : const VaryingInfoArray& pathProcVaryings,
36 : GrGLSLPrimitiveProcessor* geometryProcessor,
37 : GrGLSLXferProcessor* xferProcessor,
38 0 : const GrGLSLFragProcs& fragmentProcessors)
39 : : fBuiltinUniformHandles(builtinUniforms)
40 : , fProgramID(programID)
41 : , fGeometryProcessor(geometryProcessor)
42 : , fXferProcessor(xferProcessor)
43 : , fFragmentProcessors(fragmentProcessors)
44 : , fDesc(desc)
45 : , fGpu(gpu)
46 0 : , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings) {
47 : // Assign texture units to sampler uniforms one time up front.
48 0 : GL_CALL(UseProgram(fProgramID));
49 0 : fProgramDataManager.setSamplers(samplers);
50 0 : fProgramDataManager.setImageStorages(imageStorages);
51 0 : }
52 :
53 0 : GrGLProgram::~GrGLProgram() {
54 0 : if (fProgramID) {
55 0 : GL_CALL(DeleteProgram(fProgramID));
56 : }
57 0 : for (int i = 0; i < fFragmentProcessors.count(); ++i) {
58 0 : delete fFragmentProcessors[i];
59 : }
60 0 : }
61 :
62 0 : void GrGLProgram::abandon() {
63 0 : fProgramID = 0;
64 0 : }
65 :
66 : ///////////////////////////////////////////////////////////////////////////////
67 :
68 0 : void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline) {
69 0 : this->setRenderTargetState(primProc, pipeline.getRenderTarget());
70 :
71 : // we set the textures, and uniforms for installed processors in a generic way, but subclasses
72 : // of GLProgram determine how to set coord transforms
73 0 : int nextSamplerIdx = 0;
74 0 : fGeometryProcessor->setData(fProgramDataManager, primProc,
75 0 : GrFragmentProcessor::CoordTransformIter(pipeline));
76 0 : this->bindTextures(primProc, pipeline.getAllowSRGBInputs(), &nextSamplerIdx);
77 :
78 0 : this->setFragmentData(primProc, pipeline, &nextSamplerIdx);
79 :
80 0 : const GrXferProcessor& xp = pipeline.getXferProcessor();
81 : SkIPoint offset;
82 0 : GrTexture* dstTexture = pipeline.dstTexture(&offset);
83 0 : fXferProcessor->setData(fProgramDataManager, xp, dstTexture, offset);
84 0 : if (dstTexture) {
85 0 : fGpu->bindTexture(nextSamplerIdx++, GrSamplerParams::ClampNoFilter(), true,
86 0 : static_cast<GrGLTexture*>(dstTexture));
87 : }
88 0 : }
89 :
90 0 : void GrGLProgram::generateMipmaps(const GrPrimitiveProcessor& primProc,
91 : const GrPipeline& pipeline) {
92 0 : this->generateMipmaps(primProc, pipeline.getAllowSRGBInputs());
93 :
94 0 : GrFragmentProcessor::Iter iter(pipeline);
95 0 : while (const GrFragmentProcessor* fp = iter.next()) {
96 0 : this->generateMipmaps(*fp, pipeline.getAllowSRGBInputs());
97 0 : }
98 0 : }
99 :
100 0 : void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc,
101 : const GrPipeline& pipeline,
102 : int* nextSamplerIdx) {
103 0 : GrFragmentProcessor::Iter iter(pipeline);
104 : GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.begin(),
105 0 : fFragmentProcessors.count());
106 0 : const GrFragmentProcessor* fp = iter.next();
107 0 : GrGLSLFragmentProcessor* glslFP = glslIter.next();
108 0 : while (fp && glslFP) {
109 0 : glslFP->setData(fProgramDataManager, *fp);
110 0 : this->bindTextures(*fp, pipeline.getAllowSRGBInputs(), nextSamplerIdx);
111 0 : fp = iter.next();
112 0 : glslFP = glslIter.next();
113 : }
114 0 : SkASSERT(!fp && !glslFP);
115 0 : }
116 :
117 :
118 0 : void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
119 : const GrRenderTarget* rt) {
120 : // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
121 0 : if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
122 0 : fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
123 0 : fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
124 : }
125 :
126 : // set RT adjustment
127 : SkISize size;
128 0 : size.set(rt->width(), rt->height());
129 0 : if (!primProc.isPathRendering()) {
130 0 : if (fRenderTargetState.fRenderTargetOrigin != rt->origin() ||
131 0 : fRenderTargetState.fRenderTargetSize != size) {
132 0 : fRenderTargetState.fRenderTargetSize = size;
133 0 : fRenderTargetState.fRenderTargetOrigin = rt->origin();
134 :
135 : float rtAdjustmentVec[4];
136 0 : fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
137 0 : fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
138 : }
139 : } else {
140 0 : SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport());
141 0 : const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
142 0 : fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(),
143 0 : size, rt->origin());
144 : }
145 0 : }
146 :
147 0 : void GrGLProgram::bindTextures(const GrResourceIOProcessor& processor,
148 : bool allowSRGBInputs,
149 : int* nextSamplerIdx) {
150 0 : for (int i = 0; i < processor.numTextureSamplers(); ++i) {
151 0 : const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i);
152 0 : fGpu->bindTexture((*nextSamplerIdx)++, sampler.params(),
153 0 : allowSRGBInputs, static_cast<GrGLTexture*>(sampler.texture()));
154 : }
155 0 : for (int i = 0; i < processor.numBuffers(); ++i) {
156 0 : const GrResourceIOProcessor::BufferAccess& access = processor.bufferAccess(i);
157 0 : fGpu->bindTexelBuffer((*nextSamplerIdx)++, access.texelConfig(),
158 0 : static_cast<GrGLBuffer*>(access.buffer()));
159 : }
160 0 : for (int i = 0; i < processor.numImageStorages(); ++i) {
161 0 : const GrResourceIOProcessor::ImageStorageAccess& access = processor.imageStorageAccess(i);
162 0 : fGpu->bindImageStorage((*nextSamplerIdx)++, access.ioType(),
163 0 : static_cast<GrGLTexture *>(access.texture()));
164 : }
165 0 : }
166 :
167 0 : void GrGLProgram::generateMipmaps(const GrResourceIOProcessor& processor, bool allowSRGBInputs) {
168 0 : for (int i = 0; i < processor.numTextureSamplers(); ++i) {
169 0 : const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i);
170 0 : fGpu->generateMipmaps(sampler.params(), allowSRGBInputs,
171 0 : static_cast<GrGLTexture*>(sampler.texture()));
172 : }
173 0 : }
|