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:
egdaniel 2015-11-02 06:22:44 -08:00 committed by Commit bot
parent 9dbec09251
commit 574a4c153d
21 changed files with 120 additions and 131 deletions

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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) {

View File

@ -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.

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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,

View File

@ -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) {

View File

@ -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;

View File

@ -21,6 +21,7 @@ GrGLSLCaps::GrGLSLCaps(const GrContextOptions& options) {
fCanUseAnyFunctionInShader = true;
fForceHighPrecisionNDSTransform = false;
fVersionDeclString = nullptr;
fShaderDerivativeExtensionString = nullptr;
fFBFetchColorName = nullptr;
fFBFetchExtensionString = nullptr;
fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;

View File

@ -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;

View File

@ -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"