• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GrGLPathRendering.h"
15 #include "GrPathProcessor.h"
16 #include "GrPipeline.h"
17 #include "GrXferProcessor.h"
18 #include "glsl/GrGLSLFragmentProcessor.h"
19 #include "glsl/GrGLSLGeometryProcessor.h"
20 #include "glsl/GrGLSLXferProcessor.h"
21 #include "SkXfermode.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 
GrGLProgram(GrGLGpu * gpu,const GrProgramDesc & desc,const BuiltinUniformHandles & builtinUniforms,GrGLuint programID,const UniformInfoArray & uniforms,const VaryingInfoArray & pathProcVaryings,GrGLSLPrimitiveProcessor * geometryProcessor,GrGLSLXferProcessor * xferProcessor,const GrGLSLFragProcs & fragmentProcessors,SkTArray<UniformHandle> * passSamplerUniforms)28 GrGLProgram::GrGLProgram(GrGLGpu* gpu,
29                          const GrProgramDesc& desc,
30                          const BuiltinUniformHandles& builtinUniforms,
31                          GrGLuint programID,
32                          const UniformInfoArray& uniforms,
33                          const VaryingInfoArray& pathProcVaryings,
34                          GrGLSLPrimitiveProcessor* geometryProcessor,
35                          GrGLSLXferProcessor* xferProcessor,
36                          const GrGLSLFragProcs& fragmentProcessors,
37                          SkTArray<UniformHandle>* passSamplerUniforms)
38     : fBuiltinUniformHandles(builtinUniforms)
39     , fProgramID(programID)
40     , fGeometryProcessor(geometryProcessor)
41     , fXferProcessor(xferProcessor)
42     , fFragmentProcessors(fragmentProcessors)
43     , fDesc(desc)
44     , fGpu(gpu)
45     , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings) {
46     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     }
52 }
53 
~GrGLProgram()54 GrGLProgram::~GrGLProgram() {
55     if (fProgramID) {
56         GL_CALL(DeleteProgram(fProgramID));
57     }
58     for (int i = 0; i < fFragmentProcessors.count(); ++i) {
59         delete fFragmentProcessors[i];
60     }
61 }
62 
abandon()63 void GrGLProgram::abandon() {
64     fProgramID = 0;
65 }
66 
67 ///////////////////////////////////////////////////////////////////////////////
68 
append_texture_bindings(const GrProcessor & processor,SkTArray<const GrTextureAccess * > * textureBindings)69 static void append_texture_bindings(const GrProcessor& processor,
70                                     SkTArray<const GrTextureAccess*>* textureBindings) {
71     if (int numTextures = processor.numTextures()) {
72         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 
setData(const GrPrimitiveProcessor & primProc,const GrPipeline & pipeline,SkTArray<const GrTextureAccess * > * textureBindings)80 void GrGLProgram::setData(const GrPrimitiveProcessor& primProc,
81                           const GrPipeline& pipeline,
82                           SkTArray<const GrTextureAccess*>* textureBindings) {
83     this->setRenderTargetState(primProc, pipeline);
84 
85     // we set the textures, and uniforms for installed processors in a generic way, but subclasses
86     // of GLProgram determine how to set coord transforms
87     fGeometryProcessor->setData(fProgramDataManager, primProc);
88     append_texture_bindings(primProc, textureBindings);
89 
90     this->setFragmentData(primProc, pipeline, textureBindings);
91 
92     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     }
98 }
99 
setFragmentData(const GrPrimitiveProcessor & primProc,const GrPipeline & pipeline,SkTArray<const GrTextureAccess * > * textureBindings)100 void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc,
101                                   const GrPipeline& pipeline,
102                                   SkTArray<const GrTextureAccess*>* textureBindings) {
103     int numProcessors = fFragmentProcessors.count();
104     for (int i = 0; i < numProcessors; ++i) {
105         const GrFragmentProcessor& processor = pipeline.getFragmentProcessor(i);
106         fFragmentProcessors[i]->setData(fProgramDataManager, processor);
107         this->setTransformData(primProc, processor, i);
108         append_texture_bindings(processor, textureBindings);
109     }
110 }
setTransformData(const GrPrimitiveProcessor & primProc,const GrFragmentProcessor & processor,int index)111 void GrGLProgram::setTransformData(const GrPrimitiveProcessor& primProc,
112                                    const GrFragmentProcessor& processor,
113                                    int index) {
114     fGeometryProcessor->setTransformData(primProc, fProgramDataManager, index,
115                                          processor.coordTransforms());
116 }
117 
setRenderTargetState(const GrPrimitiveProcessor & primProc,const GrPipeline & pipeline)118 void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
119                                        const GrPipeline& pipeline) {
120     // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
121     if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
122         fRenderTargetState.fRenderTargetSize.fHeight != pipeline.getRenderTarget()->height()) {
123         fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni,
124                                    SkIntToScalar(pipeline.getRenderTarget()->height()));
125     }
126 
127     // set RT adjustment
128     const GrRenderTarget* rt = pipeline.getRenderTarget();
129     SkISize size;
130     size.set(rt->width(), rt->height());
131     if (!primProc.isPathRendering()) {
132         if (fRenderTargetState.fRenderTargetOrigin != rt->origin() ||
133             fRenderTargetState.fRenderTargetSize != size) {
134             fRenderTargetState.fRenderTargetSize = size;
135             fRenderTargetState.fRenderTargetOrigin = rt->origin();
136 
137             float rtAdjustmentVec[4];
138             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());
146     }
147 }
148