* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrGLSLProgramBuilder_DEFINED
#define GrGLSLProgramBuilder_DEFINED
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrProgramDesc.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrRenderTargetPriv.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLPrimitiveProcessor.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
#include "src/gpu/glsl/GrGLSLXferProcessor.h"
class GrShaderVar;
class GrGLSLVaryingHandler;
class SkString;
class GrShaderCaps;
class GrGLSLProgramBuilder {
public:
using UniformHandle = GrGLSLUniformHandler::UniformHandle;
using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
virtual ~GrGLSLProgramBuilder() {}
virtual const GrCaps* caps() const = 0;
const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; }
const GrTextureProxy* const* primProcProxies() const { return fPrimProcProxies; }
const GrRenderTarget* renderTarget() const { return fRenderTarget; }
GrPixelConfig config() const { return fRenderTarget->config(); }
int effectiveSampleCnt() const {
SkASSERT(GrProcessor::CustomFeatures::kSampleLocations & header().processorFeatures());
return fRenderTarget->renderTargetPriv().getSampleLocations().count();
}
GrSurfaceOrigin origin() const { return fOrigin; }
const GrPipeline& pipeline() const { return fPipeline; }
GrProgramDesc* desc() { return fDesc; }
const GrProgramDesc::KeyHeader& header() const { return fDesc->header(); }
void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
const char* samplerVariable(SamplerHandle handle) const {
return this->uniformHandler()->samplerVariable(handle);
}
GrSwizzle samplerSwizzle(SamplerHandle handle) const {
if (this->caps()->shaderCaps()->textureSwizzleAppliedInShader()) {
return this->uniformHandler()->samplerSwizzle(handle);
}
return GrSwizzle::RGBA();
}
void addRTWidthUniform(const char* name);
void addRTHeightUniform(const char* name);
void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true);
virtual GrGLSLUniformHandler* uniformHandler() = 0;
virtual const GrGLSLUniformHandler* uniformHandler() const = 0;
virtual GrGLSLVaryingHandler* varyingHandler() = 0;
virtual void finalizeFragmentOutputColor(GrShaderVar& outputColor) {}
virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {}
static const int kVarsPerBlock;
GrGLSLVertexBuilder fVS;
GrGLSLGeometryBuilder fGS;
GrGLSLFragmentShaderBuilder fFS;
int fStageIndex;
const GrRenderTarget* fRenderTarget;
const GrSurfaceOrigin fOrigin;
const GrPipeline& fPipeline;
const GrPrimitiveProcessor& fPrimProc;
const GrTextureProxy* const* fPrimProcProxies;
GrProgramDesc* fDesc;
GrGLSLBuiltinUniformHandles fUniformHandles;
std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
int fFragmentProcessorCnt;
protected:
explicit GrGLSLProgramBuilder(GrRenderTarget* renderTarget, GrSurfaceOrigin origin,
const GrPrimitiveProcessor&,
const GrTextureProxy* const primProcProxies[],
const GrPipeline&,
GrProgramDesc*);
void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
bool emitAndInstallProcs();
void finalizeShaders();
bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); }
private:
void reset() {
this->addStage();
SkDEBUGCODE(fFS.debugOnly_resetPerStageVerification();)
}
void addStage() { fStageIndex++; }
class AutoStageAdvance {
public:
AutoStageAdvance(GrGLSLProgramBuilder* pb)
: fPB(pb) {
fPB->reset();
fPB->fFS.nextStage();
}
~AutoStageAdvance() {}
private:
GrGLSLProgramBuilder* fPB;
};
void nameExpression(SkString*, const char* baseName);
void emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage);
void emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut);
SkString emitAndInstallFragProc(const GrFragmentProcessor&,
int index,
int transformedCoordVarsIdx,
const SkString& input,
SkString output,
SkTArray<std::unique_ptr<GrGLSLFragmentProcessor>>*);
void emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
SamplerHandle emitSampler(const GrTexture*, const GrSamplerState&, const GrSwizzle&,
const char* name);
bool checkSamplerCounts();
#ifdef SK_DEBUG
void verify(const GrPrimitiveProcessor&);
void verify(const GrFragmentProcessor&);
void verify(const GrXferProcessor&);
#endif
int fNumFragmentSamplers;
SkSTArray<4, GrShaderVar> fTransformedCoordVars;
};
#endif