123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- /*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "src/gpu/GrAllocator.h"
- #include "src/gpu/GrCoordTransform.h"
- #include "src/gpu/GrPathProcessor.h"
- #include "src/gpu/GrPipeline.h"
- #include "src/gpu/GrProcessor.h"
- #include "src/gpu/GrTexturePriv.h"
- #include "src/gpu/GrXferProcessor.h"
- #include "src/gpu/gl/GrGLBuffer.h"
- #include "src/gpu/gl/GrGLGpu.h"
- #include "src/gpu/gl/GrGLPathRendering.h"
- #include "src/gpu/gl/GrGLProgram.h"
- #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
- #include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
- #include "src/gpu/glsl/GrGLSLXferProcessor.h"
- #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
- #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X)
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- GrGLProgram::GrGLProgram(
- GrGLGpu* gpu,
- const GrGLSLBuiltinUniformHandles& builtinUniforms,
- GrGLuint programID,
- const UniformInfoArray& uniforms,
- const UniformInfoArray& textureSamplers,
- const VaryingInfoArray& pathProcVaryings,
- std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
- std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
- std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
- int fragmentProcessorCnt,
- std::unique_ptr<Attribute[]> attributes,
- int vertexAttributeCnt,
- int instanceAttributeCnt,
- int vertexStride,
- int instanceStride)
- : fBuiltinUniformHandles(builtinUniforms)
- , fProgramID(programID)
- , fPrimitiveProcessor(std::move(geometryProcessor))
- , fXferProcessor(std::move(xferProcessor))
- , fFragmentProcessors(std::move(fragmentProcessors))
- , fFragmentProcessorCnt(fragmentProcessorCnt)
- , fAttributes(std::move(attributes))
- , fVertexAttributeCnt(vertexAttributeCnt)
- , fInstanceAttributeCnt(instanceAttributeCnt)
- , fVertexStride(vertexStride)
- , fInstanceStride(instanceStride)
- , fGpu(gpu)
- , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings)
- , fNumTextureSamplers(textureSamplers.count()) {
- // Assign texture units to sampler uniforms one time up front.
- GL_CALL(UseProgram(fProgramID));
- fProgramDataManager.setSamplerUniforms(textureSamplers, 0);
- }
- GrGLProgram::~GrGLProgram() {
- if (fProgramID) {
- GL_CALL(DeleteProgram(fProgramID));
- }
- }
- void GrGLProgram::abandon() {
- fProgramID = 0;
- }
- ///////////////////////////////////////////////////////////////////////////////
- void GrGLProgram::updateUniformsAndTextureBindings(const GrRenderTarget* renderTarget,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrTextureProxy* const primProcTextures[]) {
- this->setRenderTargetState(renderTarget, origin, primProc);
- // we set the textures, and uniforms for installed processors in a generic way, but subclasses
- // of GLProgram determine how to set coord transforms
- // We must bind to texture units in the same order in which we set the uniforms in
- // GrGLProgramDataManager. That is, we bind textures for processors in this order:
- // primProc, fragProcs, XP.
- fPrimitiveProcessor->setData(fProgramDataManager, primProc,
- GrFragmentProcessor::CoordTransformIter(pipeline));
- if (primProcTextures) {
- this->updatePrimitiveProcessorTextureBindings(primProc, primProcTextures);
- }
- int nextTexSamplerIdx = primProc.numTextureSamplers();
- this->setFragmentData(pipeline, &nextTexSamplerIdx);
- const GrXferProcessor& xp = pipeline.getXferProcessor();
- SkIPoint offset;
- GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
- fXferProcessor->setData(fProgramDataManager, xp, dstTexture, offset);
- if (dstTexture) {
- fGpu->bindTexture(nextTexSamplerIdx++, GrSamplerState::ClampNearest(),
- pipeline.dstTextureProxy()->textureSwizzle(),
- static_cast<GrGLTexture*>(dstTexture));
- }
- SkASSERT(nextTexSamplerIdx == fNumTextureSamplers);
- }
- void GrGLProgram::updatePrimitiveProcessorTextureBindings(const GrPrimitiveProcessor& primProc,
- const GrTextureProxy* const proxies[]) {
- for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
- auto* tex = static_cast<GrGLTexture*>(proxies[i]->peekTexture());
- fGpu->bindTexture(i, primProc.textureSampler(i).samplerState(),
- primProc.textureSampler(i).swizzle(), tex);
- }
- }
- void GrGLProgram::setFragmentData(const GrPipeline& pipeline, int* nextTexSamplerIdx) {
- GrFragmentProcessor::Iter iter(pipeline);
- GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
- const GrFragmentProcessor* fp = iter.next();
- GrGLSLFragmentProcessor* glslFP = glslIter.next();
- while (fp && glslFP) {
- glslFP->setData(fProgramDataManager, *fp);
- for (int i = 0; i < fp->numTextureSamplers(); ++i) {
- const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i);
- fGpu->bindTexture((*nextTexSamplerIdx)++, sampler.samplerState(), sampler.swizzle(),
- static_cast<GrGLTexture*>(sampler.peekTexture()));
- }
- fp = iter.next();
- glslFP = glslIter.next();
- }
- SkASSERT(!fp && !glslFP);
- }
- void GrGLProgram::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc) {
- // Load the RT size uniforms if they are needed
- if (fBuiltinUniformHandles.fRTWidthUni.isValid() &&
- fRenderTargetState.fRenderTargetSize.fWidth != rt->width()) {
- fProgramDataManager.set1f(fBuiltinUniformHandles.fRTWidthUni, SkIntToScalar(rt->width()));
- }
- if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
- fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
- fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
- }
- // set RT adjustment
- SkISize size;
- size.set(rt->width(), rt->height());
- if (!primProc.isPathRendering()) {
- if (fRenderTargetState.fRenderTargetOrigin != origin ||
- fRenderTargetState.fRenderTargetSize != size) {
- fRenderTargetState.fRenderTargetSize = size;
- fRenderTargetState.fRenderTargetOrigin = origin;
- float rtAdjustmentVec[4];
- fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
- fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
- }
- } else {
- SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport());
- const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
- fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(),
- size, origin);
- }
- }
|