Move shader compiling to ProgramBuilder and various ShaderBuilder cleanups.
An additional positive of this CL is that GrGLShaderBuilder is now GL independent besides GrGLProgramBuilder BUG=skia: Review URL: https://codereview.chromium.org/1431433003
This commit is contained in:
parent
9dbec09251
commit
574a4c153d
@ -11,6 +11,7 @@
|
||||
#include "GrFragmentProcessor.h"
|
||||
#include "GrCoordTransform.h"
|
||||
#include "effects/GrXfermodeFragmentProcessor.h"
|
||||
#include "gl/GrGLFragmentProcessor.h"
|
||||
#include "gl/builders/GrGLProgramBuilder.h"
|
||||
#include "glsl/GrGLSLProgramDataManager.h"
|
||||
#include "Resources.h"
|
||||
|
@ -130,6 +130,7 @@ private:
|
||||
#include "GrCoordTransform.h"
|
||||
#include "GrFragmentProcessor.h"
|
||||
#include "GrTextureAccess.h"
|
||||
#include "gl/GrGLFragmentProcessor.h"
|
||||
#include "gl/builders/GrGLProgramBuilder.h"
|
||||
#include "glsl/GrGLSLProgramDataManager.h"
|
||||
#include "SkGr.h"
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "GrFragmentProcessor.h"
|
||||
#include "effects/GrConstColorProcessor.h"
|
||||
#include "gl/GrGLFragmentProcessor.h"
|
||||
#include "gl/GrGLSLBlend.h"
|
||||
#include "gl/builders/GrGLProgramBuilder.h"
|
||||
#include "SkGrPriv.h"
|
||||
|
@ -591,6 +591,10 @@ void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
|
||||
|
||||
glslCaps->fVersionDeclString = get_glsl_version_decl_string(standard, glslCaps->fGLSLGeneration,
|
||||
fIsCoreProfile);
|
||||
|
||||
if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == glslCaps->fGLSLGeneration) {
|
||||
glslCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
|
||||
}
|
||||
}
|
||||
|
||||
bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
|
||||
|
@ -2396,6 +2396,22 @@ static inline GrGLenum tile_to_gl_wrap(SkShader::TileMode tm) {
|
||||
return gWrapModes[tm];
|
||||
}
|
||||
|
||||
const GrGLenum* GrGLGpu::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) {
|
||||
if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
|
||||
if (caps.textureRedSupport()) {
|
||||
static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED };
|
||||
return gRedSmear;
|
||||
} else {
|
||||
static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
|
||||
GR_GL_ALPHA, GR_GL_ALPHA };
|
||||
return gAlphaSmear;
|
||||
}
|
||||
} else {
|
||||
static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA };
|
||||
return gStraight;
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture) {
|
||||
SkASSERT(texture);
|
||||
|
||||
@ -2462,7 +2478,7 @@ void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
|
||||
newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX());
|
||||
newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY());
|
||||
memcpy(newTexParams.fSwizzleRGBA,
|
||||
GrGLShaderBuilder::GetTexParamSwizzle(texture->config(), this->glCaps()),
|
||||
GetTexParamSwizzle(texture->config(), this->glCaps()),
|
||||
sizeof(newTexParams.fSwizzleRGBA));
|
||||
if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) {
|
||||
this->setTextureUnit(unitIdx);
|
||||
|
@ -128,6 +128,11 @@ public:
|
||||
bool isTestingOnlyBackendTexture(GrBackendObject id) const override;
|
||||
void deleteTestingOnlyBackendTexture(GrBackendObject id) const override;
|
||||
|
||||
/** If texture swizzling is available using tex parameters then it is preferred over mangling
|
||||
the generated shader code. This potentially allows greater reuse of cached shaders. */
|
||||
static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
|
||||
|
||||
|
||||
private:
|
||||
GrGLGpu(GrGLContext* ctx, GrContext* context);
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "GrPathProcessor.h"
|
||||
#include "GrPipeline.h"
|
||||
#include "GrXferProcessor.h"
|
||||
#include "gl/GrGLFragmentProcessor.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
|
||||
|
@ -159,8 +159,7 @@ bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc,
|
||||
|
||||
if (pipeline.readsFragPosition()) {
|
||||
header->fFragPosKey =
|
||||
GrGLFragmentShaderBuilder::KeyForFragmentPosition(pipeline.getRenderTarget(),
|
||||
gpu->glCaps());
|
||||
GrGLFragmentShaderBuilder::KeyForFragmentPosition(pipeline.getRenderTarget());
|
||||
} else {
|
||||
header->fFragPosKey = 0;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "GrGLFragmentShaderBuilder.h"
|
||||
#include "GrRenderTarget.h"
|
||||
#include "GrGLProgramBuilder.h"
|
||||
#include "gl/GrGLGpu.h"
|
||||
#include "glsl/GrGLSL.h"
|
||||
@ -59,26 +60,8 @@ static const char* specific_layout_qualifier_name(GrBlendEquation equation) {
|
||||
kGrBlendEquationCnt - kFirstAdvancedGrBlendEquation);
|
||||
}
|
||||
|
||||
GrGLFragmentShaderBuilder::DstReadKey
|
||||
GrGLFragmentShaderBuilder::KeyForDstRead(const GrTexture* dstTexture, const GrGLCaps& caps) {
|
||||
uint32_t key = kYesDstRead_DstReadKeyBit;
|
||||
if (caps.glslCaps()->fbFetchSupport()) {
|
||||
return key;
|
||||
}
|
||||
SkASSERT(dstTexture);
|
||||
if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstTexture->config())) {
|
||||
// The fact that the config is alpha-only must be considered when generating code.
|
||||
key |= kUseAlphaConfig_DstReadKeyBit;
|
||||
}
|
||||
if (kTopLeft_GrSurfaceOrigin == dstTexture->origin()) {
|
||||
key |= kTopLeftOrigin_DstReadKeyBit;
|
||||
}
|
||||
SkASSERT(static_cast<DstReadKey>(key) == key);
|
||||
return static_cast<DstReadKey>(key);
|
||||
}
|
||||
|
||||
GrGLFragmentShaderBuilder::FragPosKey
|
||||
GrGLFragmentShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&) {
|
||||
GrGLFragmentShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst) {
|
||||
if (kTopLeft_GrSurfaceOrigin == dst->origin()) {
|
||||
return kTopLeftFragPosRead_FragPosKey;
|
||||
} else {
|
||||
@ -101,14 +84,12 @@ GrGLFragmentShaderBuilder::GrGLFragmentShaderBuilder(GrGLProgramBuilder* program
|
||||
bool GrGLFragmentShaderBuilder::enableFeature(GLSLFeature feature) {
|
||||
switch (feature) {
|
||||
case kStandardDerivatives_GLSLFeature: {
|
||||
GrGLGpu* gpu = fProgramBuilder->gpu();
|
||||
if (!gpu->glCaps().shaderCaps()->shaderDerivativeSupport()) {
|
||||
if (!fProgramBuilder->glslCaps()->shaderDerivativeSupport()) {
|
||||
return false;
|
||||
}
|
||||
if (kGLES_GrGLStandard == gpu->glStandard() &&
|
||||
k110_GrGLSLGeneration == gpu->glslGeneration()) {
|
||||
this->addFeature(1 << kStandardDerivatives_GLSLFeature,
|
||||
"GL_OES_standard_derivatives");
|
||||
const char* extension = fProgramBuilder->glslCaps()->shaderDerivativeExtensionString();
|
||||
if (extension) {
|
||||
this->addFeature(1 << kStandardDerivatives_GLSLFeature, extension);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -248,7 +229,7 @@ void GrGLFragmentShaderBuilder::enableSecondaryOutput() {
|
||||
// and vice versa, since it is not allowed to use a built-in gl_FragColor and a custom
|
||||
// output. The condition also co-incides with the condition in whici GLES SL 2.0
|
||||
// requires the built-in gl_SecondaryFragColorEXT, where as 3.0 requires a custom output.
|
||||
const GrGLSLCaps& caps = *fProgramBuilder->gpu()->glCaps().glslCaps();
|
||||
const GrGLSLCaps& caps = *fProgramBuilder->glslCaps();
|
||||
if (caps.mustDeclareFragmentShaderOutput()) {
|
||||
fOutputs.push_back().set(kVec4f_GrSLType, GrGLSLShaderVar::kOut_TypeModifier,
|
||||
declared_secondary_color_output_name());
|
||||
@ -265,20 +246,10 @@ const char* GrGLFragmentShaderBuilder::getSecondaryColorOutputName() const {
|
||||
: "gl_SecondaryFragColorEXT";
|
||||
}
|
||||
|
||||
bool GrGLFragmentShaderBuilder::compileAndAttachShaders(GrGLuint programId,
|
||||
SkTDArray<GrGLuint>* shaderIds) {
|
||||
this->versionDecl() = fProgramBuilder->glslCaps()->versionDeclString();
|
||||
void GrGLFragmentShaderBuilder::onFinalize() {
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision,
|
||||
*fProgramBuilder->glslCaps(),
|
||||
&this->precisionQualifier());
|
||||
this->compileAndAppendLayoutQualifiers();
|
||||
fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kFragment_Visibility,
|
||||
&this->uniforms());
|
||||
this->appendDecls(fInputs, &this->inputs());
|
||||
// We shouldn't have declared outputs on 1.10
|
||||
SkASSERT(k110_GrGLSLGeneration != fProgramBuilder->gpu()->glslGeneration() || fOutputs.empty());
|
||||
this->appendDecls(fOutputs, &this->outputs());
|
||||
return this->finalize(programId, GR_GL_FRAGMENT_SHADER, shaderIds);
|
||||
}
|
||||
|
||||
void GrGLFragmentShaderBuilder::bindFragmentShaderLocations(GrGLuint programID) {
|
||||
|
@ -10,8 +10,10 @@
|
||||
|
||||
#include "GrGLShaderBuilder.h"
|
||||
|
||||
#include "gl/GrGLTypes.h"
|
||||
#include "glsl/GrGLSLProcessorTypes.h"
|
||||
|
||||
class GrRenderTarget;
|
||||
class GrGLVarying;
|
||||
|
||||
/*
|
||||
@ -111,18 +113,12 @@ private:
|
||||
// TODO rename to Fragment Builder
|
||||
class GrGLFragmentShaderBuilder : public GrGLXPFragmentBuilder {
|
||||
public:
|
||||
typedef uint8_t DstReadKey;
|
||||
typedef uint8_t FragPosKey;
|
||||
|
||||
/** Returns a key for adding code to read the dst texture color in service of effects that
|
||||
require reading the dst. It must not return 0 because 0 indicates that there is no dst
|
||||
texture at all (in which case this function should not be called). */
|
||||
static DstReadKey KeyForDstRead(const GrTexture* dsttexture, const GrGLCaps&);
|
||||
|
||||
/** Returns a key for reading the fragment location. This should only be called if there is an
|
||||
effect that will requires the fragment position. If the fragment position is not required,
|
||||
the key is 0. */
|
||||
static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
|
||||
static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst);
|
||||
|
||||
GrGLFragmentShaderBuilder(GrGLProgramBuilder* program, uint8_t fragPosKey);
|
||||
|
||||
@ -141,7 +137,6 @@ private:
|
||||
void enableSecondaryOutput();
|
||||
const char* getPrimaryColorOutputName() const;
|
||||
const char* getSecondaryColorOutputName() const;
|
||||
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds);
|
||||
void bindFragmentShaderLocations(GrGLuint programID);
|
||||
|
||||
// As GLProcessors emit code, there are some conditions we need to verify. We use the below
|
||||
@ -158,6 +153,8 @@ private:
|
||||
*/
|
||||
void addVarying(GrGLVarying*, GrSLPrecision);
|
||||
|
||||
void onFinalize() override;
|
||||
|
||||
/**
|
||||
* Features that should only be enabled by GrGLFragmentShaderBuilder itself.
|
||||
*/
|
||||
@ -168,14 +165,6 @@ private:
|
||||
kLastGLSLPrivateFeature = kBlendFuncExtended_GLSLPrivateFeature
|
||||
};
|
||||
|
||||
// Interpretation of DstReadKey when generating code
|
||||
enum {
|
||||
kNoDstRead_DstReadKey = 0,
|
||||
kYesDstRead_DstReadKeyBit = 0x1, // Set if we do a dst-copy-read.
|
||||
kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
|
||||
kTopLeftOrigin_DstReadKeyBit = 0x4, // Set if dst-copy origin is top-left.
|
||||
};
|
||||
|
||||
// Interpretation of FragPosKey when generating code
|
||||
enum {
|
||||
kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed.
|
||||
|
@ -37,8 +37,3 @@ void GrGLGeometryBuilder::addVarying(const char* name, GrSLPrecision precision,
|
||||
}
|
||||
}
|
||||
|
||||
bool GrGLGeometryBuilder::compileAndAttachShaders(GrGLuint programId,
|
||||
SkTDArray<GrGLuint>* shaderIds) {
|
||||
SkFAIL("Geometry shaders are not currently supported");
|
||||
return false;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ private:
|
||||
*/
|
||||
void addVarying(const char* name, GrSLPrecision precision, GrGLVarying*);
|
||||
|
||||
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds);
|
||||
void onFinalize() override {}
|
||||
|
||||
friend class GrGLProgramBuilder;
|
||||
|
||||
|
@ -13,11 +13,13 @@
|
||||
#include "GrTexture.h"
|
||||
#include "SkRTConf.h"
|
||||
#include "SkTraceEvent.h"
|
||||
#include "gl/GrGLFragmentProcessor.h"
|
||||
#include "gl/GrGLGeometryProcessor.h"
|
||||
#include "gl/GrGLGpu.h"
|
||||
#include "gl/GrGLProgram.h"
|
||||
#include "gl/GrGLSLPrettyPrint.h"
|
||||
#include "gl/GrGLXferProcessor.h"
|
||||
#include "gl/builders/GrGLShaderStringBuilder.h"
|
||||
#include "glsl/GrGLSLCaps.h"
|
||||
#include "glsl/GrGLSLProgramDataManager.h"
|
||||
#include "glsl/GrGLSLTextureSampler.h"
|
||||
@ -380,6 +382,28 @@ void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
|
||||
}
|
||||
}
|
||||
|
||||
bool GrGLProgramBuilder::compileAndAttachShaders(GrGLShaderBuilder& shader,
|
||||
GrGLuint programId,
|
||||
GrGLenum type,
|
||||
SkTDArray<GrGLuint>* shaderIds) {
|
||||
GrGLGpu* gpu = this->gpu();
|
||||
GrGLuint shaderId = GrGLCompileAndAttachShader(gpu->glContext(),
|
||||
programId,
|
||||
type,
|
||||
shader.fCompilerStrings.begin(),
|
||||
shader.fCompilerStringLengths.begin(),
|
||||
shader.fCompilerStrings.count(),
|
||||
gpu->stats());
|
||||
|
||||
if (!shaderId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*shaderIds->append() = shaderId;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GrGLProgram* GrGLProgramBuilder::finalize() {
|
||||
// verify we can get a program id
|
||||
GrGLuint programID;
|
||||
@ -390,8 +414,8 @@ GrGLProgram* GrGLProgramBuilder::finalize() {
|
||||
|
||||
// compile shaders and bind attributes / uniforms
|
||||
SkTDArray<GrGLuint> shadersToDelete;
|
||||
|
||||
if (!fVS.compileAndAttachShaders(programID, &shadersToDelete)) {
|
||||
fVS.finalize(kVertex_Visibility);
|
||||
if (!this->compileAndAttachShaders(fVS, programID, GR_GL_VERTEX_SHADER, &shadersToDelete)) {
|
||||
this->cleanupProgram(programID, shadersToDelete);
|
||||
return nullptr;
|
||||
}
|
||||
@ -402,7 +426,8 @@ GrGLProgram* GrGLProgramBuilder::finalize() {
|
||||
fVS.bindVertexAttributes(programID);
|
||||
}
|
||||
|
||||
if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) {
|
||||
fFS.finalize(kFragment_Visibility);
|
||||
if (!this->compileAndAttachShaders(fFS, programID, GR_GL_FRAGMENT_SHADER, &shadersToDelete)) {
|
||||
this->cleanupProgram(programID, shadersToDelete);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "GrGLFragmentShaderBuilder.h"
|
||||
#include "GrGLGeometryShaderBuilder.h"
|
||||
#include "GrGLVertexShaderBuilder.h"
|
||||
#include "gl/GrGLProgramDataManager.h"
|
||||
#include "glsl/GrGLSLProgramDataManager.h"
|
||||
#include "glsl/GrGLSLTextureSampler.h"
|
||||
#include "../GrGLPrimitiveProcessor.h"
|
||||
@ -18,6 +19,7 @@
|
||||
#include "../../GrPipeline.h"
|
||||
|
||||
class GrFragmentProcessor;
|
||||
class GrGLContextInfo;
|
||||
class GrGLSLCaps;
|
||||
|
||||
// Enough precision to represent 1 / 2048 accurately in printf
|
||||
@ -44,7 +46,7 @@ public:
|
||||
virtual ~GrGLUniformBuilder() {}
|
||||
|
||||
typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
|
||||
typedef GrGLProgramDataManager::SeparableVaryingHandle SeparableVaryingHandle;
|
||||
typedef GrGLSLProgramDataManager::SeparableVaryingHandle SeparableVaryingHandle;
|
||||
|
||||
/** Add a uniform variable to the current program, that has visibility in one or more shaders.
|
||||
visibility is a bitfield of ShaderVisibility values indicating from which shaders the
|
||||
@ -334,6 +336,10 @@ protected:
|
||||
GrGLSLTextureSampler::TextureSamplerArray* outSamplers,
|
||||
GrGLInstalledProc<Proc>*);
|
||||
|
||||
bool compileAndAttachShaders(GrGLShaderBuilder& shader,
|
||||
GrGLuint programId,
|
||||
GrGLenum type,
|
||||
SkTDArray<GrGLuint>* shaderIds);
|
||||
GrGLProgram* finalize();
|
||||
virtual void bindProgramResourceLocations(GrGLuint programID);
|
||||
bool checkLinkStatus(GrGLuint programID);
|
||||
|
@ -6,11 +6,8 @@
|
||||
*/
|
||||
|
||||
#include "GrGLShaderBuilder.h"
|
||||
#include "GrGLProgramBuilder.h"
|
||||
#include "GrGLShaderStringBuilder.h"
|
||||
#include "gl/GrGLCaps.h"
|
||||
#include "gl/GrGLContext.h"
|
||||
#include "gl/GrGLGpu.h"
|
||||
#include "gl/builders/GrGLProgramBuilder.h"
|
||||
#include "glsl/GrGLSLCaps.h"
|
||||
#include "glsl/GrGLSLShaderVar.h"
|
||||
#include "glsl/GrGLSLTextureSampler.h"
|
||||
@ -123,23 +120,6 @@ void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation,
|
||||
this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str());
|
||||
}
|
||||
|
||||
|
||||
const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) {
|
||||
if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
|
||||
if (caps.textureRedSupport()) {
|
||||
static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED };
|
||||
return gRedSmear;
|
||||
} else {
|
||||
static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
|
||||
GR_GL_ALPHA, GR_GL_ALPHA };
|
||||
return gAlphaSmear;
|
||||
}
|
||||
} else {
|
||||
static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA };
|
||||
return gStraight;
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) {
|
||||
if (!(featureBit & fFeaturesAddedMask)) {
|
||||
this->extensions().appendf("#extension %s: require\n", extensionName);
|
||||
@ -168,8 +148,8 @@ void GrGLShaderBuilder::appendTextureLookup(const char* samplerName,
|
||||
}
|
||||
|
||||
void GrGLShaderBuilder::addLayoutQualifier(const char* param, InterfaceQualifier interface) {
|
||||
SkASSERT(fProgramBuilder->gpu()->glslGeneration() >= k330_GrGLSLGeneration ||
|
||||
fProgramBuilder->gpu()->glCaps().glslCaps()->mustEnableAdvBlendEqs());
|
||||
SkASSERT(fProgramBuilder->glslCaps()->generation() >= k330_GrGLSLGeneration ||
|
||||
fProgramBuilder->glslCaps()->mustEnableAdvBlendEqs());
|
||||
fLayoutParams[interface].push_back() = param;
|
||||
}
|
||||
|
||||
@ -194,9 +174,17 @@ void GrGLShaderBuilder::compileAndAppendLayoutQualifiers() {
|
||||
GR_STATIC_ASSERT(SK_ARRAY_COUNT(interfaceQualifierNames) == kLastInterfaceQualifier + 1);
|
||||
}
|
||||
|
||||
bool
|
||||
GrGLShaderBuilder::finalize(GrGLuint programId, GrGLenum type, SkTDArray<GrGLuint>* shaderIds) {
|
||||
void GrGLShaderBuilder::finalize(uint32_t visibility) {
|
||||
SkASSERT(!fFinalized);
|
||||
this->versionDecl() = fProgramBuilder->glslCaps()->versionDeclString();
|
||||
this->compileAndAppendLayoutQualifiers();
|
||||
fProgramBuilder->appendUniformDecls((GrGLProgramBuilder::ShaderVisibility) visibility,
|
||||
&this->uniforms());
|
||||
this->appendDecls(fInputs, &this->inputs());
|
||||
SkASSERT(k110_GrGLSLGeneration != fProgramBuilder->glslCaps()->generation() ||
|
||||
fOutputs.empty());
|
||||
this->appendDecls(fOutputs, &this->outputs());
|
||||
this->onFinalize();
|
||||
// append the 'footer' to code
|
||||
this->code().append("}");
|
||||
|
||||
@ -205,22 +193,6 @@ GrGLShaderBuilder::finalize(GrGLuint programId, GrGLenum type, SkTDArray<GrGLuin
|
||||
fCompilerStringLengths[i] = (int)fShaderStrings[i].size();
|
||||
}
|
||||
|
||||
GrGLGpu* gpu = fProgramBuilder->gpu();
|
||||
GrGLuint shaderId = GrGLCompileAndAttachShader(gpu->glContext(),
|
||||
programId,
|
||||
type,
|
||||
fCompilerStrings.begin(),
|
||||
fCompilerStringLengths.begin(),
|
||||
fCompilerStrings.count(),
|
||||
gpu->stats());
|
||||
|
||||
fFinalized = true;
|
||||
|
||||
if (!shaderId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*shaderIds->append() = shaderId;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -8,16 +8,12 @@
|
||||
#ifndef GrGLShaderBuilder_DEFINED
|
||||
#define GrGLShaderBuilder_DEFINED
|
||||
|
||||
#include "SkTArray.h"
|
||||
#include "gl/GrGLFragmentProcessor.h"
|
||||
#include "gl/GrGLProgramDesc.h"
|
||||
#include "gl/GrGLProgramDataManager.h"
|
||||
#include "gl/GrGLTypes.h"
|
||||
#include "GrAllocator.h"
|
||||
#include "glsl/GrGLSLShaderVar.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
class GrGLCaps;
|
||||
class GrGLContextInfo;
|
||||
class GrGLProgramBuilder;
|
||||
class GrGLSLTextureSampler;
|
||||
|
||||
@ -27,6 +23,7 @@ class GrGLSLTextureSampler;
|
||||
class GrGLShaderBuilder {
|
||||
public:
|
||||
GrGLShaderBuilder(GrGLProgramBuilder* program);
|
||||
virtual ~GrGLShaderBuilder() {}
|
||||
|
||||
void addInput(const GrGLSLShaderVar& input) { fInputs.push_back(input); }
|
||||
void addOutput(const GrGLSLShaderVar& output) { fOutputs.push_back(output); }
|
||||
@ -65,10 +62,6 @@ public:
|
||||
const char* coordName,
|
||||
GrSLType coordType = kVec2f_GrSLType);
|
||||
|
||||
/** If texture swizzling is available using tex parameters then it is preferred over mangling
|
||||
the generated shader code. This potentially allows greater reuse of cached shaders. */
|
||||
static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
|
||||
|
||||
/**
|
||||
* Called by GrGLProcessors to add code to one of the shaders.
|
||||
*/
|
||||
@ -101,6 +94,11 @@ public:
|
||||
const char* body,
|
||||
SkString* outName);
|
||||
|
||||
/*
|
||||
* Combines the various parts of the shader to create a single finalized shader string.
|
||||
*/
|
||||
void finalize(uint32_t visibility);
|
||||
|
||||
/*
|
||||
* Get parent builder for adding uniforms
|
||||
*/
|
||||
@ -173,7 +171,8 @@ protected:
|
||||
SkString& functions() { return fShaderStrings[kFunctions]; }
|
||||
SkString& main() { return fShaderStrings[kMain]; }
|
||||
SkString& code() { return fShaderStrings[fCodeIndex]; }
|
||||
bool finalize(GrGLuint programId, GrGLenum type, SkTDArray<GrGLuint>* shaderIds);
|
||||
|
||||
virtual void onFinalize() = 0;
|
||||
|
||||
enum {
|
||||
kVersionDecl,
|
||||
|
@ -87,16 +87,6 @@ void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool
|
||||
GrGLVertexBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) {
|
||||
this->versionDecl() = fProgramBuilder->glslCaps()->versionDeclString();
|
||||
this->compileAndAppendLayoutQualifiers();
|
||||
fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kVertex_Visibility, &this->uniforms());
|
||||
this->appendDecls(fInputs, &this->inputs());
|
||||
this->appendDecls(fOutputs, &this->outputs());
|
||||
return this->finalize(programId, GR_GL_VERTEX_SHADER, shaderIds);
|
||||
}
|
||||
|
||||
bool GrGLVertexBuilder::addAttribute(const GrShaderVar& var) {
|
||||
SkASSERT(GrShaderVar::kAttribute_TypeModifier == var.getTypeModifier());
|
||||
for (int i = 0; i < fInputs.count(); ++i) {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define GrGLVertexShader_DEFINED
|
||||
|
||||
#include "GrGLShaderBuilder.h"
|
||||
#include "gl/GrGLTypes.h"
|
||||
#include "GrGeometryProcessor.h"
|
||||
|
||||
class GrGLVarying;
|
||||
@ -38,11 +39,12 @@ private:
|
||||
* private helpers for compilation by GrGLProgramBuilder
|
||||
*/
|
||||
void bindVertexAttributes(GrGLuint programID);
|
||||
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds);
|
||||
|
||||
// an internal call which checks for uniquness of a var before adding it to the list of inputs
|
||||
bool addAttribute(const GrShaderVar& var);
|
||||
|
||||
void onFinalize() override {}
|
||||
|
||||
const char* fRtAdjustName;
|
||||
|
||||
friend class GrGLProgramBuilder;
|
||||
|
@ -21,6 +21,7 @@ GrGLSLCaps::GrGLSLCaps(const GrContextOptions& options) {
|
||||
fCanUseAnyFunctionInShader = true;
|
||||
fForceHighPrecisionNDSTransform = false;
|
||||
fVersionDeclString = nullptr;
|
||||
fShaderDerivativeExtensionString = nullptr;
|
||||
fFBFetchColorName = nullptr;
|
||||
fFBFetchExtensionString = nullptr;
|
||||
fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
|
||||
|
@ -74,6 +74,14 @@ public:
|
||||
|
||||
bool forceHighPrecisionNDSTransform() const { return fForceHighPrecisionNDSTransform; }
|
||||
|
||||
// Returns the string of an extension that must be enabled in the shader to support
|
||||
// derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
|
||||
// this function, the caller should check that shaderDerivativeSupport exists.
|
||||
const char* shaderDerivativeExtensionString() const {
|
||||
SkASSERT(this->shaderDerivativeSupport());
|
||||
return fShaderDerivativeExtensionString;
|
||||
}
|
||||
|
||||
GrGLSLGeneration generation() const { return fGLSLGeneration; }
|
||||
|
||||
/**
|
||||
@ -94,6 +102,8 @@ private:
|
||||
|
||||
const char* fVersionDeclString;
|
||||
|
||||
const char* fShaderDerivativeExtensionString;
|
||||
|
||||
const char* fFBFetchColorName;
|
||||
const char* fFBFetchExtensionString;
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "effects/GrPorterDuffXferProcessor.h"
|
||||
#include "effects/GrXfermodeFragmentProcessor.h"
|
||||
|
||||
#include "gl/GrGLFragmentProcessor.h"
|
||||
#include "gl/GrGLGpu.h"
|
||||
#include "gl/GrGLPathRendering.h"
|
||||
#include "gl/builders/GrGLProgramBuilder.h"
|
||||
|
Loading…
Reference in New Issue
Block a user