summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp')
-rw-r--r--chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp364
1 files changed, 240 insertions, 124 deletions
diff --git a/chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp b/chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp
index 961cad798fc..4b2778c5030 100644
--- a/chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -13,7 +13,7 @@
#include "GrGpuGL.h"
#include "GrTexture.h"
#include "SkRTConf.h"
-#include "SkTrace.h"
+#include "SkTraceEvent.h"
#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
@@ -89,45 +89,52 @@ static const char kDstCopyColorName[] = "_dstColor";
///////////////////////////////////////////////////////////////////////////////
-GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
- GrGLUniformManager& uniformManager,
- const GrGLProgramDesc& desc)
- : fGpu(gpu)
- , fUniformManager(uniformManager)
- , fFSFeaturesAddedMask(0)
- , fFSInputs(kVarsPerBlock)
- , fFSOutputs(kMaxFSOutputs)
- , fUniforms(kVarsPerBlock)
- , fSetupFragPosition(false)
- , fHasCustomColorOutput(false)
- , fHasSecondaryOutput(false)
- , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) {
+bool GrGLShaderBuilder::GenProgram(GrGpuGL* gpu,
+ GrGLUniformManager* uman,
+ const GrGLProgramDesc& desc,
+ const GrEffectStage* inColorStages[],
+ const GrEffectStage* inCoverageStages[],
+ GenProgramOutput* output) {
+ SkAutoTDelete<GrGLShaderBuilder> builder;
+ if (desc.getHeader().fHasVertexCode ||!gpu->shouldUseFixedFunctionTexturing()) {
+ builder.reset(SkNEW_ARGS(GrGLFullShaderBuilder, (gpu, uman, desc)));
+ } else {
+ builder.reset(SkNEW_ARGS(GrGLFragmentOnlyShaderBuilder, (gpu, uman, desc)));
+ }
+ if (builder->genProgram(inColorStages, inCoverageStages)) {
+ *output = builder->getOutput();
+ return true;
+ }
+ return false;
+}
- const GrGLProgramDesc::KeyHeader& header = desc.getHeader();
+bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[],
+ const GrEffectStage* coverageStages[]) {
+ const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
- // Emit code to read the dst copy textue if necessary.
+ ///////////////////////////////////////////////////////////////////////////
+ // emit code to read the dst copy texture, if necessary
if (kNoDstRead_DstReadKey != header.fDstReadKey &&
GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) {
bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey);
const char* dstCopyTopLeftName;
const char* dstCopyCoordScaleName;
+ const char* dstCopySamplerName;
uint32_t configMask;
if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) {
configMask = kA_GrColorComponentFlag;
} else {
configMask = kRGBA_GrColorComponentFlags;
}
- fDstCopySamplerUniform = this->addUniform(kFragment_Visibility,
- kSampler2D_GrSLType,
- "DstCopySampler");
- fDstCopyTopLeftUniform = this->addUniform(kFragment_Visibility,
- kVec2f_GrSLType,
- "DstCopyUpperLeft",
- &dstCopyTopLeftName);
- fDstCopyScaleUniform = this->addUniform(kFragment_Visibility,
- kVec2f_GrSLType,
- "DstCopyCoordScale",
- &dstCopyCoordScaleName);
+ fOutput.fUniformHandles.fDstCopySamplerUni =
+ this->addUniform(kFragment_Visibility, kSampler2D_GrSLType, "DstCopySampler",
+ &dstCopySamplerName);
+ fOutput.fUniformHandles.fDstCopyTopLeftUni =
+ this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyUpperLeft",
+ &dstCopyTopLeftName);
+ fOutput.fUniformHandles.fDstCopyScaleUni =
+ this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyCoordScale",
+ &dstCopyCoordScaleName);
const char* fragPos = this->fragmentPosition();
this->fsCodeAppend("\t// Read color from copy of the destination.\n");
this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n",
@@ -138,33 +145,41 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName);
append_texture_lookup(&fFSCode,
fGpu,
- this->getUniformCStr(fDstCopySamplerUniform),
+ dstCopySamplerName,
"_dstTexCoord",
configMask,
"rgba");
this->fsCodeAppend(";\n\n");
}
+ ///////////////////////////////////////////////////////////////////////////
+ // get the initial color and coverage to feed into the first effect in each effect chain
+
+ GrGLSLExpr4 inputColor;
+ GrGLSLExpr4 inputCoverage;
+
if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) {
const char* name;
- fColorUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility,
- kVec4f_GrSLType, "Color", &name);
- fInputColor = GrGLSLExpr4(name);
+ fOutput.fUniformHandles.fColorUni =
+ this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Color",
+ &name);
+ inputColor = GrGLSLExpr4(name);
} else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fColorInput) {
- fInputColor = GrGLSLExpr4(1);
+ inputColor = GrGLSLExpr4(1);
} else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fColorInput) {
- fInputColor = GrGLSLExpr4(0);
+ inputColor = GrGLSLExpr4(0);
}
if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
const char* name;
- fCoverageUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility,
- kVec4f_GrSLType, "Coverage", &name);
- fInputCoverage = GrGLSLExpr4(name);
+ fOutput.fUniformHandles.fCoverageUni =
+ this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Coverage",
+ &name);
+ inputCoverage = GrGLSLExpr4(name);
} else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) {
- fInputCoverage = GrGLSLExpr4(1);
+ inputCoverage = GrGLSLExpr4(1);
} else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fCoverageInput) {
- fInputCoverage = GrGLSLExpr4(0);
+ inputCoverage = GrGLSLExpr4(0);
}
if (k110_GrGLSLGeneration != fGpu->glslGeneration()) {
@@ -173,6 +188,81 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
declared_color_output_name());
fHasCustomColorOutput = true;
}
+
+ this->emitCodeBeforeEffects(&inputColor, &inputCoverage);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // emit the per-effect code for both color and coverage effects
+
+ fOutput.fColorEffects.reset(this->createAndEmitEffects(colorStages,
+ this->desc().getEffectKeys(),
+ this->desc().numColorEffects(),
+ &inputColor));
+
+ fOutput.fCoverageEffects.reset(this->createAndEmitEffects(coverageStages,
+ this->desc().getEffectKeys() + this->desc().numColorEffects(),
+ this->desc().numCoverageEffects(),
+ &inputCoverage));
+
+ this->emitCodeAfterEffects();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // write the secondary color output if necessary
+ if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) {
+ const char* secondaryOutputName = this->enableSecondaryOutput();
+
+ // default coeff to ones for kCoverage_DualSrcOutput
+ GrGLSLExpr4 coeff(1);
+ if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) {
+ // Get (1-A) into coeff
+ coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
+ } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput ==
+ header.fCoverageOutput){
+ // Get (1-RGBA) into coeff
+ coeff = GrGLSLExpr4(1) - inputColor;
+ }
+ // Get coeff * coverage into modulate and then write that to the dual source output.
+ this->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str());
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // combine color and coverage as frag color
+
+ // Get "color * coverage" into fragColor
+ GrGLSLExpr4 fragColor = inputColor * inputCoverage;
+ // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so.
+ if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) {
+ GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
+
+ GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(this->dstColor());
+
+ fragColor = fragColor + dstContribution;
+ }
+ this->fsCodeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str());
+
+ if (!this->finish()) {
+ return false;
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
+ GrGLUniformManager* uniformManager,
+ const GrGLProgramDesc& desc)
+ : fDesc(desc)
+ , fGpu(gpu)
+ , fUniformManager(SkRef(uniformManager))
+ , fFSFeaturesAddedMask(0)
+ , fFSInputs(kVarsPerBlock)
+ , fFSOutputs(kMaxFSOutputs)
+ , fUniforms(kVarsPerBlock)
+ , fSetupFragPosition(false)
+ , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey)
+ , fHasCustomColorOutput(false)
+ , fHasSecondaryOutput(false) {
}
bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) {
@@ -181,13 +271,13 @@ bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) {
if (!fGpu->glCaps().shaderDerivativeSupport()) {
return false;
}
- if (kES_GrGLBinding == fGpu->glBinding()) {
+ if (kGLES_GrGLStandard == fGpu->glStandard()) {
this->addFSFeature(1 << kStandardDerivatives_GLSLFeature,
"GL_OES_standard_derivatives");
}
return true;
default:
- GrCrash("Unexpected GLSLFeature requested.");
+ SkFAIL("Unexpected GLSLFeature requested.");
return false;
}
}
@@ -218,7 +308,7 @@ bool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) {
"GL_NV_shader_framebuffer_fetch");
return true;
default:
- GrCrash("Unexpected GLSLPrivateFeature requested.");
+ SkFAIL("Unexpected GLSLPrivateFeature requested.");
return false;
}
}
@@ -249,7 +339,7 @@ const char* GrGLShaderBuilder::dstColor() {
if (fCodeStage.inStageCode()) {
const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect();
if (!effect->willReadDstColor()) {
- GrDebugCrash("GrGLEffect asked for dst color but its generating GrEffect "
+ SkDEBUGFAIL("GrGLEffect asked for dst color but its generating GrEffect "
"did not request access.");
return "";
}
@@ -262,7 +352,7 @@ const char* GrGLShaderBuilder::dstColor() {
} else if (GrGLCaps::kNV_FBFetchType == fetchType) {
SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSLPrivateFeature));
return kFBFetchColorName;
- } else if (fDstCopySamplerUniform.isValid()) {
+ } else if (fOutput.fUniformHandles.fDstCopySamplerUni.isValid()) {
return kDstCopyColorName;
} else {
return "";
@@ -355,7 +445,7 @@ GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t vi
BuilderUniform& uni = fUniforms.push_back();
UniformHandle h = GrGLUniformManager::UniformHandle::CreateFromUniformIndex(fUniforms.count() - 1);
SkDEBUGCODE(UniformHandle h2 =)
- fUniformManager.appendUniform(type, count);
+ fUniformManager->appendUniform(type, count);
// We expect the uniform manager to initially have no uniforms and that all uniforms are added
// by this function. Therefore, the handles should match.
SkASSERT(h2 == h);
@@ -399,19 +489,16 @@ const char* GrGLShaderBuilder::fragmentPosition() {
if (fCodeStage.inStageCode()) {
const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect();
if (!effect->willReadFragmentPosition()) {
- GrDebugCrash("GrGLEffect asked for frag position but its generating GrEffect "
+ SkDEBUGFAIL("GrGLEffect asked for frag position but its generating GrEffect "
"did not request access.");
return "";
}
}
+ // We only declare "gl_FragCoord" when we're in the case where we want to use layout qualifiers
+ // to reverse y. Otherwise it isn't necessary and whether the "in" qualifier appears in the
+ // declaration varies in earlier GLSL specs. So it is simpler to omit it.
if (fTopLeftFragPosRead) {
- if (!fSetupFragPosition) {
- fFSInputs.push_back().set(kVec4f_GrSLType,
- GrGLShaderVar::kIn_TypeModifier,
- "gl_FragCoord",
- GrGLShaderVar::kDefault_Precision);
- fSetupFragPosition = true;
- }
+ fSetupFragPosition = true;
return "gl_FragCoord";
} else if (fGpu->glCaps().fragCoordConventionsSupport()) {
if (!fSetupFragPosition) {
@@ -430,19 +517,17 @@ const char* GrGLShaderBuilder::fragmentPosition() {
// temporarily change the stage index because we're inserting non-stage code.
CodeStage::AutoStageRestore csar(&fCodeStage, NULL);
- SkASSERT(!fRTHeightUniform.isValid());
+ SkASSERT(!fOutput.fUniformHandles.fRTHeightUni.isValid());
const char* rtHeightName;
- fRTHeightUniform = this->addUniform(kFragment_Visibility,
- kFloat_GrSLType,
- "RTHeight",
- &rtHeightName);
+ fOutput.fUniformHandles.fRTHeightUni =
+ this->addUniform(kFragment_Visibility, kFloat_GrSLType, "RTHeight", &rtHeightName);
this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, gl_FragCoord.zw);\n",
kCoordName, rtHeightName);
fSetupFragPosition = true;
}
- SkASSERT(fRTHeightUniform.isValid());
+ SkASSERT(fOutput.fUniformHandles.fRTHeightUni.isValid());
return kCoordName;
}
}
@@ -471,10 +556,10 @@ void GrGLShaderBuilder::fsEmitFunction(GrSLType returnType,
namespace {
inline void append_default_precision_qualifier(GrGLShaderVar::Precision p,
- GrGLBinding binding,
+ GrGLStandard standard,
SkString* str) {
// Desktop GLSL has added precision qualifiers but they don't do anything.
- if (kES_GrGLBinding == binding) {
+ if (kGLES_GrGLStandard == standard) {
switch (p) {
case GrGLShaderVar::kHigh_Precision:
str->append("precision highp float;\n");
@@ -486,9 +571,9 @@ inline void append_default_precision_qualifier(GrGLShaderVar::Precision p,
str->append("precision lowp float;\n");
break;
case GrGLShaderVar::kDefault_Precision:
- GrCrash("Default precision now allowed.");
+ SkFAIL("Default precision now allowed.");
default:
- GrCrash("Unknown precision value.");
+ SkFAIL("Unknown precision value.");
}
}
}
@@ -572,27 +657,26 @@ const char* GrGLShaderBuilder::enableSecondaryOutput() {
return dual_source_output_name();
}
-
-bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) {
- SK_TRACE_EVENT0("GrGLShaderBuilder::finish");
-
- GrGLuint programId = 0;
- GL_CALL_RET(programId, CreateProgram());
- if (!programId) {
+bool GrGLShaderBuilder::finish() {
+ SkASSERT(0 == fOutput.fProgramID);
+ GL_CALL_RET(fOutput.fProgramID, CreateProgram());
+ if (!fOutput.fProgramID) {
return false;
}
- if (!this->compileAndAttachShaders(programId)) {
- GL_CALL(DeleteProgram(programId));
+ SkTDArray<GrGLuint> shadersToDelete;
+
+ if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) {
+ GL_CALL(DeleteProgram(fOutput.fProgramID));
return false;
}
- this->bindProgramLocations(programId);
- if (fUniformManager.isUsingBindUniform()) {
- fUniformManager.getUniformLocations(programId, fUniforms);
+ this->bindProgramLocations(fOutput.fProgramID);
+ if (fUniformManager->isUsingBindUniform()) {
+ fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms);
}
- GL_CALL(LinkProgram(programId));
+ GL_CALL(LinkProgram(fOutput.fProgramID));
// Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
bool checkLinked = !fGpu->ctxInfo().isChromium();
@@ -601,46 +685,51 @@ bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) {
#endif
if (checkLinked) {
GrGLint linked = GR_GL_INIT_ZERO;
- GL_CALL(GetProgramiv(programId, GR_GL_LINK_STATUS, &linked));
+ GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_LINK_STATUS, &linked));
if (!linked) {
GrGLint infoLen = GR_GL_INIT_ZERO;
- GL_CALL(GetProgramiv(programId, GR_GL_INFO_LOG_LENGTH, &infoLen));
+ GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen));
SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
if (infoLen > 0) {
// retrieve length even though we don't need it to workaround
// bug in chrome cmd buffer param validation.
GrGLsizei length = GR_GL_INIT_ZERO;
- GL_CALL(GetProgramInfoLog(programId,
+ GL_CALL(GetProgramInfoLog(fOutput.fProgramID,
infoLen+1,
&length,
(char*)log.get()));
GrPrintf((char*)log.get());
}
SkDEBUGFAIL("Error linking program");
- GL_CALL(DeleteProgram(programId));
+ GL_CALL(DeleteProgram(fOutput.fProgramID));
+ fOutput.fProgramID = 0;
return false;
}
}
- if (!fUniformManager.isUsingBindUniform()) {
- fUniformManager.getUniformLocations(programId, fUniforms);
+ if (!fUniformManager->isUsingBindUniform()) {
+ fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms);
}
- *outProgramId = programId;
+
+ for (int i = 0; i < shadersToDelete.count(); ++i) {
+ GL_CALL(DeleteShader(shadersToDelete[i]));
+ }
+
return true;
}
-// Compiles a GL shader, attaches it to a program, and releases the shader's reference.
-// (That way there's no need to hang on to the GL shader id and delete it later.)
-static bool attach_shader(const GrGLContext& glCtx,
- GrGLuint programId,
- GrGLenum type,
- const SkString& shaderSrc) {
+// Compiles a GL shader and attaches it to a program. Returns the shader ID if
+// successful, or 0 if not.
+static GrGLuint attach_shader(const GrGLContext& glCtx,
+ GrGLuint programId,
+ GrGLenum type,
+ const SkString& shaderSrc) {
const GrGLInterface* gli = glCtx.interface();
GrGLuint shaderId;
GR_GL_CALL_RET(gli, shaderId, CreateShader(type));
if (0 == shaderId) {
- return false;
+ return 0;
}
const GrGLchar* sourceStr = shaderSrc.c_str();
@@ -649,7 +738,7 @@ static bool attach_shader(const GrGLContext& glCtx,
GR_GL_CALL(gli, CompileShader(shaderId));
// Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds.
- bool checkCompiled = !glCtx.info().isChromium();
+ bool checkCompiled = !glCtx.isChromium();
#ifdef SK_DEBUG
checkCompiled = true;
#endif
@@ -672,7 +761,7 @@ static bool attach_shader(const GrGLContext& glCtx,
}
SkDEBUGFAIL("Shader compilation failed!");
GR_GL_CALL(gli, DeleteShader(shaderId));
- return false;
+ return 0;
}
}
if (c_PrintShaders) {
@@ -680,16 +769,20 @@ static bool attach_shader(const GrGLContext& glCtx,
GrPrintf("\n");
}
+ // Attach the shader, but defer deletion until after we have linked the program.
+ // This works around a bug in the Android emulator's GLES2 wrapper which
+ // will immediately delete the shader object and free its memory even though it's
+ // attached to a program, which then causes glLinkProgram to fail.
GR_GL_CALL(gli, AttachShader(programId, shaderId));
- GR_GL_CALL(gli, DeleteShader(shaderId));
- return true;
+
+ return shaderId;
}
-bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const {
+bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const {
SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
fragShaderSrc.append(fFSExtensions);
append_default_precision_qualifier(kDefaultFragmentPrecision,
- fGpu->glBinding(),
+ fGpu->glStandard(),
&fragShaderSrc);
this->appendUniformDecls(kFragment_Visibility, &fragShaderSrc);
this->appendDecls(fFSInputs, &fragShaderSrc);
@@ -700,10 +793,14 @@ bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const {
fragShaderSrc.append("void main() {\n");
fragShaderSrc.append(fFSCode);
fragShaderSrc.append("}\n");
- if (!attach_shader(fGpu->glContext(), programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc)) {
+
+ GrGLuint fragShaderId = attach_shader(fGpu->glContext(), programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc);
+ if (!fragShaderId) {
return false;
}
+ *shaderIds->append() = fragShaderId;
+
return true;
}
@@ -723,16 +820,19 @@ const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const {
////////////////////////////////////////////////////////////////////////////////
GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu,
- GrGLUniformManager& uniformManager,
+ GrGLUniformManager* uniformManager,
const GrGLProgramDesc& desc)
: INHERITED(gpu, uniformManager, desc)
- , fDesc(desc)
, fVSAttrs(kVarsPerBlock)
, fVSOutputs(kVarsPerBlock)
, fGSInputs(kVarsPerBlock)
, fGSOutputs(kVarsPerBlock) {
+}
+
+void GrGLFullShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) {
+ const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
- const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
+ fOutput.fHasVertexShader = true;
fPositionVar = &fVSAttrs.push_back();
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
@@ -746,11 +846,12 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu,
}
const char* viewMName;
- fViewMatrixUniform = this->addUniform(GrGLShaderBuilder::kVertex_Visibility,
- kMat33f_GrSLType, "ViewM", &viewMName);
+ fOutput.fUniformHandles.fViewMatrixUni =
+ this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kMat33f_GrSLType, "ViewM",
+ &viewMName);
- this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n"
- "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n",
+ // Transform the position into Skia's device coords.
+ this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n",
viewMName, fPositionVar->c_str());
// we output point size in the GS if present
@@ -767,7 +868,7 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu,
const char *vsName, *fsName;
this->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
this->vsCodeAppendf("\t%s = %s;\n", vsName, color_attribute_name());
- this->setInputColor(fsName);
+ *color = fsName;
}
if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
@@ -775,10 +876,22 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu,
const char *vsName, *fsName;
this->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
this->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name());
- this->setInputCoverage(fsName);
+ *coverage = fsName;
}
}
+void GrGLFullShaderBuilder::emitCodeAfterEffects() {
+ const char* rtAdjustName;
+ fOutput.fUniformHandles.fRTAdjustmentUni =
+ this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kVec4f_GrSLType, "rtAdjustment",
+ &rtAdjustName);
+
+ // Transform from Skia's device coords to GL's normalized device coords.
+ this->vsCodeAppendf(
+ "\tgl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);\n",
+ rtAdjustName, rtAdjustName);
+}
+
bool GrGLFullShaderBuilder::addAttribute(GrSLType type, const char* name) {
for (int i = 0; i < fVSAttrs.count(); ++i) {
const GrGLShaderVar& attr = fVSAttrs[i];
@@ -820,7 +933,7 @@ void GrGLFullShaderBuilder::addVarying(GrSLType type,
// input to FS comes either from VS or GS
const SkString* fsName;
#if GR_GL_EXPERIMENTAL_GS
- if (fDesc.getHeader().fExperimentalGS) {
+ if (this->desc().getHeader().fExperimentalGS) {
// if we have a GS take each varying in as an array
// and output as non-array.
fGSInputs.push_back();
@@ -870,7 +983,8 @@ GrGLProgramEffects* GrGLFullShaderBuilder::createAndEmitEffects(
return programEffectsBuilder.finish();
}
-bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const {
+bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId,
+ SkTDArray<GrGLuint>* shaderIds) const {
const GrGLContext& glCtx = this->gpu()->glContext();
SkString vertShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
this->appendUniformDecls(kVertex_Visibility, &vertShaderSrc);
@@ -879,12 +993,14 @@ bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const {
vertShaderSrc.append("void main() {\n");
vertShaderSrc.append(fVSCode);
vertShaderSrc.append("}\n");
- if (!attach_shader(glCtx, programId, GR_GL_VERTEX_SHADER, vertShaderSrc)) {
+ GrGLuint vertShaderId = attach_shader(glCtx, programId, GR_GL_VERTEX_SHADER, vertShaderSrc);
+ if (!vertShaderId) {
return false;
}
+ *shaderIds->append() = vertShaderId;
#if GR_GL_EXPERIMENTAL_GS
- if (fDesc.getHeader().fExperimentalGS) {
+ if (this->desc().getHeader().fExperimentalGS) {
SkASSERT(this->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration);
SkString geomShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
geomShaderSrc.append("layout(triangles) in;\n"
@@ -894,7 +1010,7 @@ bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const {
geomShaderSrc.append("void main() {\n");
geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n"
"\t\tgl_Position = gl_in[i].gl_Position;\n");
- if (fDesc.getHeader().fEmitsPointSize) {
+ if (this->desc().getHeader().fEmitsPointSize) {
geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n");
}
SkASSERT(fGSInputs.count() == fGSOutputs.count());
@@ -907,19 +1023,21 @@ bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const {
"\t}\n"
"\tEndPrimitive();\n");
geomShaderSrc.append("}\n");
- if (!attach_shader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc)) {
+ GrGLuint geomShaderId = attach_shader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc);
+ if (!geomShaderId) {
return false;
}
+ *shaderIds->append() = geomShaderId;
}
#endif
- return this->INHERITED::compileAndAttachShaders(programId);
+ return this->INHERITED::compileAndAttachShaders(programId, shaderIds);
}
void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const {
this->INHERITED::bindProgramLocations(programId);
- const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
+ const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
// Bind the attrib locations to same values for all shaders
SkASSERT(-1 != header.fPositionAttributeIndex);
@@ -951,22 +1069,19 @@ void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const {
////////////////////////////////////////////////////////////////////////////////
GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu,
- GrGLUniformManager& uniformManager,
+ GrGLUniformManager* uniformManager,
const GrGLProgramDesc& desc)
- : INHERITED(gpu, uniformManager, desc)
- , fNumTexCoordSets(0) {
-
+ : INHERITED(gpu, uniformManager, desc) {
SkASSERT(!desc.getHeader().fHasVertexCode);
- SkASSERT(gpu->glCaps().fixedFunctionSupport());
SkASSERT(gpu->glCaps().pathRenderingSupport());
SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput);
SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput);
}
int GrGLFragmentOnlyShaderBuilder::addTexCoordSets(int count) {
- int firstFreeCoordSet = fNumTexCoordSets;
- fNumTexCoordSets += count;
- SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fNumTexCoordSets);
+ int firstFreeCoordSet = fOutput.fTexCoordSetCnt;
+ fOutput.fTexCoordSetCnt += count;
+ SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fOutput.fTexCoordSetCnt);
return firstFreeCoordSet;
}
@@ -976,11 +1091,12 @@ GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects(
int effectCnt,
GrGLSLExpr4* inOutFSColor) {
- GrGLTexGenProgramEffectsBuilder texGenEffectsBuilder(this, effectCnt);
- this->INHERITED::createAndEmitEffects(&texGenEffectsBuilder,
+ GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this,
+ effectCnt);
+ this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder,
effectStages,
effectKeys,
effectCnt,
inOutFSColor);
- return texGenEffectsBuilder.finish();
+ return pathTexGenEffectsBuilder.finish();
}