aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--gyp/gpu.gypi18
-rw-r--r--include/core/SkString.h1
-rw-r--r--include/gpu/GrEffect.h2
-rw-r--r--src/core/SkString.cpp8
-rw-r--r--src/core/SkXfermode.cpp189
-rw-r--r--src/effects/SkAlphaThresholdFilter.cpp44
-rw-r--r--src/effects/SkArithmeticMode.cpp35
-rw-r--r--src/effects/SkBlurMaskFilter.cpp113
-rw-r--r--src/effects/SkColorFilters.cpp9
-rw-r--r--src/effects/SkColorMatrixFilter.cpp17
-rw-r--r--src/effects/SkDisplacementMapEffect.cpp45
-rw-r--r--src/effects/SkLightingImageFilter.cpp145
-rw-r--r--src/effects/SkLumaColorFilter.cpp9
-rw-r--r--src/effects/SkMagnifierImageFilter.cpp61
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp31
-rw-r--r--src/effects/SkPerlinNoiseShader.cpp69
-rw-r--r--src/effects/SkTableColorFilter.cpp41
-rw-r--r--src/effects/gradients/SkGradientShader.cpp51
-rw-r--r--src/effects/gradients/SkGradientShaderPriv.h4
-rw-r--r--src/effects/gradients/SkLinearGradient.cpp8
-rw-r--r--src/effects/gradients/SkRadialGradient.cpp8
-rw-r--r--src/effects/gradients/SkSweepGradient.cpp8
-rw-r--r--src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp107
-rw-r--r--src/effects/gradients/SkTwoPointRadialGradient.cpp17
-rw-r--r--src/gpu/GrAAConvexPathRenderer.cpp41
-rw-r--r--src/gpu/GrAARectRenderer.cpp72
-rw-r--r--src/gpu/GrOvalRenderer.cpp117
-rw-r--r--src/gpu/effects/GrBezierEffect.cpp198
-rw-r--r--src/gpu/effects/GrBicubicEffect.cpp31
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp29
-rw-r--r--src/gpu/effects/GrConvexPolyEffect.cpp65
-rw-r--r--src/gpu/effects/GrConvolutionEffect.cpp32
-rw-r--r--src/gpu/effects/GrCustomCoordsTextureEffect.cpp18
-rw-r--r--src/gpu/effects/GrDashingEffect.cpp73
-rwxr-xr-xsrc/gpu/effects/GrDistanceFieldTextureEffect.cpp206
-rw-r--r--src/gpu/effects/GrDistanceFieldTextureEffect.h4
-rw-r--r--src/gpu/effects/GrDitherEffect.cpp13
-rw-r--r--src/gpu/effects/GrMatrixConvolutionEffect.cpp52
-rw-r--r--src/gpu/effects/GrOvalEffect.cpp54
-rw-r--r--src/gpu/effects/GrRRectEffect.cpp138
-rw-r--r--src/gpu/effects/GrSimpleTextureEffect.cpp11
-rw-r--r--src/gpu/effects/GrTextureDomain.cpp71
-rw-r--r--src/gpu/effects/GrTextureDomain.h1
-rw-r--r--src/gpu/effects/GrYUVtoRGBEffect.cpp21
-rw-r--r--src/gpu/gl/GrGLEffect.h2
-rw-r--r--src/gpu/gl/GrGLProgram.cpp9
-rw-r--r--src/gpu/gl/GrGLProgram.h8
-rw-r--r--src/gpu/gl/GrGLProgramDataManager.cpp10
-rw-r--r--src/gpu/gl/GrGLProgramDataManager.h6
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp9
-rw-r--r--src/gpu/gl/GrGLProgramDesc.h9
-rw-r--r--src/gpu/gl/GrGLProgramEffects.cpp66
-rw-r--r--src/gpu/gl/GrGLProgramEffects.h54
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp1071
-rw-r--r--src/gpu/gl/GrGLVertexEffect.h8
-rw-r--r--src/gpu/gl/GrGpuGL.cpp1
-rw-r--r--src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp351
-rw-r--r--src/gpu/gl/builders/GrGLFragmentShaderBuilder.h118
-rw-r--r--src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp70
-rw-r--r--src/gpu/gl/builders/GrGLGeometryShaderBuilder.h32
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp409
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h (renamed from src/gpu/gl/GrGLShaderBuilder.h)253
-rw-r--r--src/gpu/gl/builders/GrGLSLPrettyPrint.cpp (renamed from src/gpu/gl/GrGLSLPrettyPrint.cpp)0
-rw-r--r--src/gpu/gl/builders/GrGLShaderBuilder.cpp155
-rw-r--r--src/gpu/gl/builders/GrGLShaderBuilder.h170
-rw-r--r--src/gpu/gl/builders/GrGLShaderStringBuilder.cpp85
-rw-r--r--src/gpu/gl/builders/GrGLShaderStringBuilder.h20
-rw-r--r--src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp200
-rw-r--r--src/gpu/gl/builders/GrGLVertexShaderBuilder.h81
-rw-r--r--tests/GLProgramsTest.cpp4
71 files changed, 3008 insertions, 2483 deletions
diff --git a/.gitignore b/.gitignore
index 27ddb22809..cedd0baa7d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,9 @@
.android_config
.gclient*
.gm-actuals
+.cproject
+.project
+.settings/
TAGS
common
gyp/build
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 56ef4b5a63..f00cfac733 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -208,7 +208,6 @@
'<(skia_src_path)/gpu/gl/GrGLPathRange.h',
'<(skia_src_path)/gpu/gl/GrGLPathRendering.cpp',
'<(skia_src_path)/gpu/gl/GrGLPathRendering.h',
- '<(skia_src_path)/gpu/gl/GrGLSLPrettyPrint.cpp',
'<(skia_src_path)/gpu/gl/GrGLProgram.cpp',
'<(skia_src_path)/gpu/gl/GrGLProgram.h',
'<(skia_src_path)/gpu/gl/GrGLProgramDesc.cpp',
@@ -219,8 +218,6 @@
'<(skia_src_path)/gpu/gl/GrGLProgramDataManager.h',
'<(skia_src_path)/gpu/gl/GrGLRenderTarget.cpp',
'<(skia_src_path)/gpu/gl/GrGLRenderTarget.h',
- '<(skia_src_path)/gpu/gl/GrGLShaderBuilder.cpp',
- '<(skia_src_path)/gpu/gl/GrGLShaderBuilder.h',
'<(skia_src_path)/gpu/gl/GrGLShaderVar.h',
'<(skia_src_path)/gpu/gl/GrGLSL.cpp',
'<(skia_src_path)/gpu/gl/GrGLSL.h',
@@ -240,6 +237,21 @@
'<(skia_src_path)/gpu/gl/GrGpuGL.h',
'<(skia_src_path)/gpu/gl/GrGpuGL_program.cpp',
+ # Files for building GLSL shaders
+ '<(skia_src_path)/gpu/gl/builders/GrGLSLPrettyPrint.cpp',
+ '<(skia_src_path)/gpu/gl/builders/GrGLShaderBuilder.cpp',
+ '<(skia_src_path)/gpu/gl/builders/GrGLShaderBuilder.h',
+ '<(skia_src_path)/gpu/gl/builders/GrGLProgramBuilder.cpp',
+ '<(skia_src_path)/gpu/gl/builders/GrGLProgramBuilder.h',
+ '<(skia_src_path)/gpu/gl/builders/GrGLShaderStringBuilder.cpp',
+ '<(skia_src_path)/gpu/gl/builders/GrGLShaderStringBuilder.h',
+ '<(skia_src_path)/gpu/gl/builders/GrGLVertexShaderBuilder.cpp',
+ '<(skia_src_path)/gpu/gl/builders/GrGLVertexShaderBuilder.h',
+ '<(skia_src_path)/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp',
+ '<(skia_src_path)/gpu/gl/builders/GrGLFragmentShaderBuilder.h',
+ '<(skia_src_path)/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp',
+ '<(skia_src_path)/gpu/gl/builders/GrGLGeometryShaderBuilder.h',
+
# Sk files
'<(skia_include_path)/gpu/SkGpuDevice.h',
'<(skia_include_path)/gpu/SkGr.h',
diff --git a/include/core/SkString.h b/include/core/SkString.h
index bc06cb0aba..8a962ae671 100644
--- a/include/core/SkString.h
+++ b/include/core/SkString.h
@@ -195,6 +195,7 @@ public:
void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
void appendVAList(const char format[], va_list);
void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
+ void prependVAList(const char format[], va_list);
void remove(size_t offset, size_t length);
diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h
index 8cb870ee15..4734c7c377 100644
--- a/include/gpu/GrEffect.h
+++ b/include/gpu/GrEffect.h
@@ -113,7 +113,7 @@ public:
bool willReadFragmentPosition() const { return fWillReadFragmentPosition; }
/** Will this effect emit custom vertex shader code?
- (To set this value the effect must inherit from GrVertexEffect.) */
+ (To set this value the effect must inherit from GrEffect.) */
bool hasVertexCode() const { return fHasVertexCode; }
int numVertexAttribs() const {
diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp
index 1e29dc7172..48459dbbd8 100644
--- a/src/core/SkString.cpp
+++ b/src/core/SkString.cpp
@@ -583,6 +583,14 @@ void SkString::prependf(const char format[], ...) {
this->prepend(buffer, strlen(buffer));
}
+void SkString::prependVAList(const char format[], va_list args) {
+ char buffer[kBufferSize];
+ VSNPRINTF(buffer, kBufferSize, format, args);
+
+ this->prepend(buffer, strlen(buffer));
+}
+
+
///////////////////////////////////////////////////////////////////////////////
void SkString::remove(size_t offset, size_t length) {
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index 7608b79cbc..b10b5e1328 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -783,7 +783,7 @@ void SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
#include "GrEffectUnitTest.h"
#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
/**
* GrEffect that implements the all the separable xfer modes that cannot be expressed as Coeffs.
@@ -821,7 +821,7 @@ public:
GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
: GrGLEffect(factory) {
}
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -830,82 +830,83 @@ public:
const TextureSamplerArray& samplers) SK_OVERRIDE {
SkXfermode::Mode mode = drawEffect.castEffect<XferEffect>().mode();
const GrTexture* backgroundTex = drawEffect.castEffect<XferEffect>().backgroundAccess().getTexture();
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
const char* dstColor;
if (backgroundTex) {
dstColor = "bgColor";
- builder->fsCodeAppendf("\t\tvec4 %s = ", dstColor);
- builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
- builder->fsCodeAppendf(";\n");
+ fsBuilder->codeAppendf("\t\tvec4 %s = ", dstColor);
+ fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
+ fsBuilder->codeAppendf(";\n");
} else {
- dstColor = builder->dstColor();
+ dstColor = fsBuilder->dstColor();
}
SkASSERT(NULL != dstColor);
// We don't try to optimize for this case at all
if (NULL == inputColor) {
- builder->fsCodeAppendf("\t\tconst vec4 ones = vec4(1);\n");
+ fsBuilder->codeAppendf("\t\tconst vec4 ones = vec4(1);\n");
inputColor = "ones";
}
- builder->fsCodeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode::ModeName(mode));
+ fsBuilder->codeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode::ModeName(mode));
// These all perform src-over on the alpha channel.
- builder->fsCodeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n",
+ fsBuilder->codeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n",
outputColor, inputColor, inputColor, dstColor);
switch (mode) {
case SkXfermode::kOverlay_Mode:
// Overlay is Hard-Light with the src and dst reversed
- HardLight(builder, outputColor, dstColor, inputColor);
+ HardLight(fsBuilder, outputColor, dstColor, inputColor);
break;
case SkXfermode::kDarken_Mode:
- builder->fsCodeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.rgb + %s.rgb, "
+ fsBuilder->codeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.rgb + %s.rgb, "
"(1.0 - %s.a) * %s.rgb + %s.rgb);\n",
outputColor,
inputColor, dstColor, inputColor,
dstColor, inputColor, dstColor);
break;
case SkXfermode::kLighten_Mode:
- builder->fsCodeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb, "
+ fsBuilder->codeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb, "
"(1.0 - %s.a) * %s.rgb + %s.rgb);\n",
outputColor,
inputColor, dstColor, inputColor,
dstColor, inputColor, dstColor);
break;
case SkXfermode::kColorDodge_Mode:
- ColorDodgeComponent(builder, outputColor, inputColor, dstColor, 'r');
- ColorDodgeComponent(builder, outputColor, inputColor, dstColor, 'g');
- ColorDodgeComponent(builder, outputColor, inputColor, dstColor, 'b');
+ ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'r');
+ ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'g');
+ ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'b');
break;
case SkXfermode::kColorBurn_Mode:
- ColorBurnComponent(builder, outputColor, inputColor, dstColor, 'r');
- ColorBurnComponent(builder, outputColor, inputColor, dstColor, 'g');
- ColorBurnComponent(builder, outputColor, inputColor, dstColor, 'b');
+ ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'r');
+ ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'g');
+ ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'b');
break;
case SkXfermode::kHardLight_Mode:
- HardLight(builder, outputColor, inputColor, dstColor);
+ HardLight(fsBuilder, outputColor, inputColor, dstColor);
break;
case SkXfermode::kSoftLight_Mode:
- builder->fsCodeAppendf("\t\tif (0.0 == %s.a) {\n", dstColor);
- builder->fsCodeAppendf("\t\t\t%s.rgba = %s;\n", outputColor, inputColor);
- builder->fsCodeAppendf("\t\t} else {\n");
- SoftLightComponentPosDstAlpha(builder, outputColor, inputColor, dstColor, 'r');
- SoftLightComponentPosDstAlpha(builder, outputColor, inputColor, dstColor, 'g');
- SoftLightComponentPosDstAlpha(builder, outputColor, inputColor, dstColor, 'b');
- builder->fsCodeAppendf("\t\t}\n");
+ fsBuilder->codeAppendf("\t\tif (0.0 == %s.a) {\n", dstColor);
+ fsBuilder->codeAppendf("\t\t\t%s.rgba = %s;\n", outputColor, inputColor);
+ fsBuilder->codeAppendf("\t\t} else {\n");
+ SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'r');
+ SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'g');
+ SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'b');
+ fsBuilder->codeAppendf("\t\t}\n");
break;
case SkXfermode::kDifference_Mode:
- builder->fsCodeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb -"
+ fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb -"
"2.0 * min(%s.rgb * %s.a, %s.rgb * %s.a);\n",
outputColor, inputColor, dstColor, inputColor, dstColor,
dstColor, inputColor);
break;
case SkXfermode::kExclusion_Mode:
- builder->fsCodeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb - "
+ fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb - "
"2.0 * %s.rgb * %s.rgb;\n",
outputColor, dstColor, inputColor, dstColor, inputColor);
break;
case SkXfermode::kMultiply_Mode:
- builder->fsCodeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + "
+ fsBuilder->codeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + "
"(1.0 - %s.a) * %s.rgb + "
"%s.rgb * %s.rgb;\n",
outputColor, inputColor, dstColor, dstColor, inputColor,
@@ -914,52 +915,52 @@ public:
case SkXfermode::kHue_Mode: {
// SetLum(SetSat(S * Da, Sat(D * Sa)), Sa*Da, D*Sa) + (1 - Sa) * D + (1 - Da) * S
SkString setSat, setLum;
- AddSatFunction(builder, &setSat);
- AddLumFunction(builder, &setLum);
- builder->fsCodeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
+ AddSatFunction(fsBuilder, &setSat);
+ AddLumFunction(fsBuilder, &setLum);
+ fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
dstColor, inputColor);
- builder->fsCodeAppendf("\t\t%s.rgb = %s(%s(%s.rgb * %s.a, dstSrcAlpha.rgb), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
+ fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(%s.rgb * %s.a, dstSrcAlpha.rgb), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
outputColor, setLum.c_str(), setSat.c_str(), inputColor,
dstColor);
- builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
+ fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
outputColor, inputColor, dstColor, dstColor, inputColor);
break;
}
case SkXfermode::kSaturation_Mode: {
// SetLum(SetSat(D * Sa, Sat(S * Da)), Sa*Da, D*Sa)) + (1 - Sa) * D + (1 - Da) * S
SkString setSat, setLum;
- AddSatFunction(builder, &setSat);
- AddLumFunction(builder, &setLum);
- builder->fsCodeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
+ AddSatFunction(fsBuilder, &setSat);
+ AddLumFunction(fsBuilder, &setLum);
+ fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
dstColor, inputColor);
- builder->fsCodeAppendf("\t\t%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s.a), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
+ fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s.a), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
outputColor, setLum.c_str(), setSat.c_str(), inputColor,
dstColor);
- builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
+ fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
outputColor, inputColor, dstColor, dstColor, inputColor);
break;
}
case SkXfermode::kColor_Mode: {
// SetLum(S * Da, Sa* Da, D * Sa) + (1 - Sa) * D + (1 - Da) * S
SkString setLum;
- AddLumFunction(builder, &setLum);
- builder->fsCodeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
+ AddLumFunction(fsBuilder, &setLum);
+ fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
inputColor, dstColor);
- builder->fsCodeAppendf("\t\t%s.rgb = %s(srcDstAlpha.rgb, srcDstAlpha.a, %s.rgb * %s.a);\n",
+ fsBuilder->codeAppendf("\t\t%s.rgb = %s(srcDstAlpha.rgb, srcDstAlpha.a, %s.rgb * %s.a);\n",
outputColor, setLum.c_str(), dstColor, inputColor);
- builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
+ fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
outputColor, inputColor, dstColor, dstColor, inputColor);
break;
}
case SkXfermode::kLuminosity_Mode: {
// SetLum(D * Sa, Sa* Da, S * Da) + (1 - Sa) * D + (1 - Da) * S
SkString setLum;
- AddLumFunction(builder, &setLum);
- builder->fsCodeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
+ AddLumFunction(fsBuilder, &setLum);
+ fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
inputColor, dstColor);
- builder->fsCodeAppendf("\t\t%s.rgb = %s(%s.rgb * %s.a, srcDstAlpha.a, srcDstAlpha.rgb);\n",
+ fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s.rgb * %s.a, srcDstAlpha.a, srcDstAlpha.rgb);\n",
outputColor, setLum.c_str(), dstColor, inputColor);
- builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
+ fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
outputColor, inputColor, dstColor, dstColor, inputColor);
break;
}
@@ -979,116 +980,116 @@ public:
}
private:
- static void HardLight(GrGLShaderBuilder* builder,
+ static void HardLight(GrGLFragmentShaderBuilder* fsBuilder,
const char* final,
const char* src,
const char* dst) {
static const char kComponents[] = {'r', 'g', 'b'};
for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) {
char component = kComponents[i];
- builder->fsCodeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
- builder->fsCodeAppendf("\t\t\t%s.%c = 2.0 * %s.%c * %s.%c;\n", final, component, src, component, dst, component);
- builder->fsCodeAppend("\t\t} else {\n");
- builder->fsCodeAppendf("\t\t\t%s.%c = %s.a * %s.a - 2.0 * (%s.a - %s.%c) * (%s.a - %s.%c);\n",
+ fsBuilder->codeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
+ fsBuilder->codeAppendf("\t\t\t%s.%c = 2.0 * %s.%c * %s.%c;\n", final, component, src, component, dst, component);
+ fsBuilder->codeAppend("\t\t} else {\n");
+ fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a - 2.0 * (%s.a - %s.%c) * (%s.a - %s.%c);\n",
final, component, src, dst, dst, dst, component, src, src, component);
- builder->fsCodeAppend("\t\t}\n");
+ fsBuilder->codeAppend("\t\t}\n");
}
- builder->fsCodeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb * (1.0 - %s.a);\n",
+ fsBuilder->codeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb * (1.0 - %s.a);\n",
final, src, dst, dst, src);
}
// Does one component of color-dodge
- static void ColorDodgeComponent(GrGLShaderBuilder* builder,
+ static void ColorDodgeComponent(GrGLFragmentShaderBuilder* fsBuilder,
const char* final,
const char* src,
const char* dst,
const char component) {
- builder->fsCodeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component);
- builder->fsCodeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
+ fsBuilder->codeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component);
+ fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
final, component, src, component, dst);
- builder->fsCodeAppend("\t\t} else {\n");
- builder->fsCodeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src, component);
- builder->fsCodeAppend("\t\t\tif (0.0 == d) {\n");
- builder->fsCodeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
+ fsBuilder->codeAppend("\t\t} else {\n");
+ fsBuilder->codeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src, component);
+ fsBuilder->codeAppend("\t\t\tif (0.0 == d) {\n");
+ fsBuilder->codeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
final, component, src, dst, src, component, dst, dst, component,
src);
- builder->fsCodeAppend("\t\t\t} else {\n");
- builder->fsCodeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n",
+ fsBuilder->codeAppend("\t\t\t} else {\n");
+ fsBuilder->codeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n",
dst, dst, component, src);
- builder->fsCodeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
+ fsBuilder->codeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
final, component, src, src, component, dst, dst, component, src);
- builder->fsCodeAppend("\t\t\t}\n");
- builder->fsCodeAppend("\t\t}\n");
+ fsBuilder->codeAppend("\t\t\t}\n");
+ fsBuilder->codeAppend("\t\t}\n");
}
// Does one component of color-burn
- static void ColorBurnComponent(GrGLShaderBuilder* builder,
+ static void ColorBurnComponent(GrGLFragmentShaderBuilder* fsBuilder,
const char* final,
const char* src,
const char* dst,
const char component) {
- builder->fsCodeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, component);
- builder->fsCodeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
+ fsBuilder->codeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, component);
+ fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
final, component, src, dst, src, component, dst, dst, component,
src);
- builder->fsCodeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, component);
- builder->fsCodeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
+ fsBuilder->codeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, component);
+ fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
final, component, dst, component, src);
- builder->fsCodeAppend("\t\t} else {\n");
- builder->fsCodeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / %s.%c);\n",
+ fsBuilder->codeAppend("\t\t} else {\n");
+ fsBuilder->codeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / %s.%c);\n",
dst, dst, dst, component, src, src, component);
- builder->fsCodeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
+ fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
final, component, src, src, component, dst, dst, component, src);
- builder->fsCodeAppend("\t\t}\n");
+ fsBuilder->codeAppend("\t\t}\n");
}
// Does one component of soft-light. Caller should have already checked that dst alpha > 0.
- static void SoftLightComponentPosDstAlpha(GrGLShaderBuilder* builder,
+ static void SoftLightComponentPosDstAlpha(GrGLFragmentShaderBuilder* fsBuilder,
const char* final,
const char* src,
const char* dst,
const char component) {
// if (2S < Sa)
- builder->fsCodeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
+ fsBuilder->codeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
// (D^2 (Sa-2 S))/Da+(1-Da) S+D (-Sa+2 S+1)
- builder->fsCodeAppendf("\t\t\t\t%s.%c = (%s.%c*%s.%c*(%s.a - 2.0*%s.%c)) / %s.a + (1.0 - %s.a) * %s.%c + %s.%c*(-%s.a + 2.0*%s.%c + 1.0);\n",
+ fsBuilder->codeAppendf("\t\t\t\t%s.%c = (%s.%c*%s.%c*(%s.a - 2.0*%s.%c)) / %s.a + (1.0 - %s.a) * %s.%c + %s.%c*(-%s.a + 2.0*%s.%c + 1.0);\n",
final, component, dst, component, dst, component, src, src,
component, dst, dst, src, component, dst, component, src, src,
component);
// else if (4D < Da)
- builder->fsCodeAppendf("\t\t\t} else if (4.0 * %s.%c <= %s.a) {\n",
+ fsBuilder->codeAppendf("\t\t\t} else if (4.0 * %s.%c <= %s.a) {\n",
dst, component, dst);
- builder->fsCodeAppendf("\t\t\t\tfloat DSqd = %s.%c * %s.%c;\n",
+ fsBuilder->codeAppendf("\t\t\t\tfloat DSqd = %s.%c * %s.%c;\n",
dst, component, dst, component);
- builder->fsCodeAppendf("\t\t\t\tfloat DCub = DSqd * %s.%c;\n", dst, component);
- builder->fsCodeAppendf("\t\t\t\tfloat DaSqd = %s.a * %s.a;\n", dst, dst);
- builder->fsCodeAppendf("\t\t\t\tfloat DaCub = DaSqd * %s.a;\n", dst);
+ fsBuilder->codeAppendf("\t\t\t\tfloat DCub = DSqd * %s.%c;\n", dst, component);
+ fsBuilder->codeAppendf("\t\t\t\tfloat DaSqd = %s.a * %s.a;\n", dst, dst);
+ fsBuilder->codeAppendf("\t\t\t\tfloat DaCub = DaSqd * %s.a;\n", dst);
// (Da^3 (-S)+Da^2 (S-D (3 Sa-6 S-1))+12 Da D^2 (Sa-2 S)-16 D^3 (Sa-2 S))/Da^2
- builder->fsCodeAppendf("\t\t\t\t%s.%c = (-DaCub*%s.%c + DaSqd*(%s.%c - %s.%c * (3.0*%s.a - 6.0*%s.%c - 1.0)) + 12.0*%s.a*DSqd*(%s.a - 2.0*%s.%c) - 16.0*DCub * (%s.a - 2.0*%s.%c)) / DaSqd;\n",
+ fsBuilder->codeAppendf("\t\t\t\t%s.%c = (-DaCub*%s.%c + DaSqd*(%s.%c - %s.%c * (3.0*%s.a - 6.0*%s.%c - 1.0)) + 12.0*%s.a*DSqd*(%s.a - 2.0*%s.%c) - 16.0*DCub * (%s.a - 2.0*%s.%c)) / DaSqd;\n",
final, component, src, component, src, component, dst, component,
src, src, component, dst, src, src, component, src, src,
component);
- builder->fsCodeAppendf("\t\t\t} else {\n");
+ fsBuilder->codeAppendf("\t\t\t} else {\n");
// -sqrt(Da * D) (Sa-2 S)-Da S+D (Sa-2 S+1)+S
- builder->fsCodeAppendf("\t\t\t\t%s.%c = -sqrt(%s.a*%s.%c)*(%s.a - 2.0*%s.%c) - %s.a*%s.%c + %s.%c*(%s.a - 2.0*%s.%c + 1.0) + %s.%c;\n",
+ fsBuilder->codeAppendf("\t\t\t\t%s.%c = -sqrt(%s.a*%s.%c)*(%s.a - 2.0*%s.%c) - %s.a*%s.%c + %s.%c*(%s.a - 2.0*%s.%c + 1.0) + %s.%c;\n",
final, component, dst, dst, component, src, src, component, dst,
src, component, dst, component, src, src, component, src,
component);
- builder->fsCodeAppendf("\t\t\t}\n");
+ fsBuilder->codeAppendf("\t\t\t}\n");
}
// Adds a function that takes two colors and an alpha as input. It produces a color with the
// hue and saturation of the first color, the luminosity of the second color, and the input
// alpha. It has this signature:
// vec3 set_luminance(vec3 hueSatColor, float alpha, vec3 lumColor).
- static void AddLumFunction(GrGLShaderBuilder* builder, SkString* setLumFunction) {
+ static void AddLumFunction(GrGLFragmentShaderBuilder* fsBuilder, SkString* setLumFunction) {
// Emit a helper that gets the luminance of a color.
SkString getFunction;
GrGLShaderVar getLumArgs[] = {
GrGLShaderVar("color", kVec3f_GrSLType),
};
SkString getLumBody("\treturn dot(vec3(0.3, 0.59, 0.11), color);\n");
- builder->fsEmitFunction(kFloat_GrSLType,
+ fsBuilder->emitFunction(kFloat_GrSLType,
"luminance",
SK_ARRAY_COUNT(getLumArgs), getLumArgs,
getLumBody.c_str(),
@@ -1113,7 +1114,7 @@ public:
"\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) / (maxComp - outLum);\n"
"\t}\n"
"\treturn outColor;\n");
- builder->fsEmitFunction(kVec3f_GrSLType,
+ fsBuilder->emitFunction(kVec3f_GrSLType,
"set_luminance",
SK_ARRAY_COUNT(setLumArgs), setLumArgs,
setLumBody.c_str(),
@@ -1123,14 +1124,14 @@ public:
// Adds a function that creates a color with the hue and luminosity of one input color and
// the saturation of another color. It will have this signature:
// float set_saturation(vec3 hueLumColor, vec3 satColor)
- static void AddSatFunction(GrGLShaderBuilder* builder, SkString* setSatFunction) {
+ static void AddSatFunction(GrGLFragmentShaderBuilder* fsBuilder, SkString* setSatFunction) {
// Emit a helper that gets the saturation of a color
SkString getFunction;
GrGLShaderVar getSatArgs[] = { GrGLShaderVar("color", kVec3f_GrSLType) };
SkString getSatBody;
getSatBody.printf("\treturn max(max(color.r, color.g), color.b) - "
"min(min(color.r, color.g), color.b);\n");
- builder->fsEmitFunction(kFloat_GrSLType,
+ fsBuilder->emitFunction(kFloat_GrSLType,
"saturation",
SK_ARRAY_COUNT(getSatArgs), getSatArgs,
getSatBody.c_str(),
@@ -1156,7 +1157,7 @@ public:
"\t} else {\n"
"\t\treturn vec3(0, 0, 0);\n"
"\t}\n";
- builder->fsEmitFunction(kVec3f_GrSLType,
+ fsBuilder->emitFunction(kVec3f_GrSLType,
"set_saturation_helper",
SK_ARRAY_COUNT(helperArgs), helperArgs,
kHelperBody,
@@ -1187,7 +1188,7 @@ public:
"\treturn hueLumColor;\n",
getFunction.c_str(), helpFunc, helpFunc, helpFunc, helpFunc,
helpFunc, helpFunc);
- builder->fsEmitFunction(kVec3f_GrSLType,
+ fsBuilder->emitFunction(kVec3f_GrSLType,
"set_saturation",
SK_ARRAY_COUNT(setSatArgs), setSatArgs,
setSatBody.c_str(),
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index 9c59347f73..8022724ab2 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -50,7 +50,7 @@ SkImageFilter* SkAlphaThresholdFilter::Create(const SkRegion& region,
#include "GrCoordTransform.h"
#include "GrEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrTBackendEffectFactory.h"
#include "GrTextureAccess.h"
@@ -118,7 +118,7 @@ class GrGLAlphaThresholdEffect : public GrGLEffect {
public:
GrGLAlphaThresholdEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -140,39 +140,41 @@ GrGLAlphaThresholdEffect::GrGLAlphaThresholdEffect(const GrBackendEffectFactory&
: INHERITED(factory) {
}
-void GrGLAlphaThresholdEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLAlphaThresholdEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString coords2D = builder->ensureFSCoords2D(coords, 0);
- SkString maskCoords2D = builder->ensureFSCoords2D(coords, 1);
fInnerThresholdVar = builder->addUniform(
- GrGLShaderBuilder::kFragment_Visibility,
+ GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "inner_threshold");
fOuterThresholdVar = builder->addUniform(
- GrGLShaderBuilder::kFragment_Visibility,
+ GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "outer_threshold");
- builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
- builder->fsCodeAppendf("\t\tvec2 mask_coord = %s;\n", maskCoords2D.c_str());
- builder->fsCodeAppend("\t\tvec4 input_color = ");
- builder->fsAppendTextureLookup(samplers[0], "coord");
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppend("\t\tvec4 mask_color = ");
- builder->fsAppendTextureLookup(samplers[1], "mask_coord");
- builder->fsCodeAppend(";\n");
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+ SkString maskCoords2D = fsBuilder->ensureFSCoords2D(coords, 1);
- builder->fsCodeAppendf("\t\tfloat inner_thresh = %s;\n",
+ fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
+ fsBuilder->codeAppendf("\t\tvec2 mask_coord = %s;\n", maskCoords2D.c_str());
+ fsBuilder->codeAppend("\t\tvec4 input_color = ");
+ fsBuilder->appendTextureLookup(samplers[0], "coord");
+ fsBuilder->codeAppend(";\n");
+ fsBuilder->codeAppend("\t\tvec4 mask_color = ");
+ fsBuilder->appendTextureLookup(samplers[1], "mask_coord");
+ fsBuilder->codeAppend(";\n");
+
+ fsBuilder->codeAppendf("\t\tfloat inner_thresh = %s;\n",
builder->getUniformCStr(fInnerThresholdVar));
- builder->fsCodeAppendf("\t\tfloat outer_thresh = %s;\n",
+ fsBuilder->codeAppendf("\t\tfloat outer_thresh = %s;\n",
builder->getUniformCStr(fOuterThresholdVar));
- builder->fsCodeAppend("\t\tfloat mask = mask_color.a;\n");
+ fsBuilder->codeAppend("\t\tfloat mask = mask_color.a;\n");
- builder->fsCodeAppend("vec4 color = input_color;\n");
- builder->fsCodeAppend("\t\tif (mask < 0.5) {\n"
+ fsBuilder->codeAppend("vec4 color = input_color;\n");
+ fsBuilder->codeAppend("\t\tif (mask < 0.5) {\n"
"\t\t\tif (color.a > outer_thresh) {\n"
"\t\t\t\tfloat scale = outer_thresh / color.a;\n"
"\t\t\t\tcolor.rgb *= scale;\n"
@@ -184,7 +186,7 @@ void GrGLAlphaThresholdEffect::emitCode(GrGLShaderBuilder* builder,
"\t\t\tcolor.a = inner_thresh;\n"
"\t\t}\n");
- builder->fsCodeAppendf("%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr4("color")).c_str());
}
diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp
index d3be826007..be636c5bbf 100644
--- a/src/effects/SkArithmeticMode.cpp
+++ b/src/effects/SkArithmeticMode.cpp
@@ -15,7 +15,7 @@
#include "GrContext.h"
#include "GrCoordTransform.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrTBackendEffectFactory.h"
#endif
@@ -252,7 +252,7 @@ public:
GrGLArithmeticEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
virtual ~GrGLArithmeticEffect();
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -359,7 +359,7 @@ GrGLArithmeticEffect::GrGLArithmeticEffect(const GrBackendEffectFactory& factory
GrGLArithmeticEffect::~GrGLArithmeticEffect() {
}
-void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLArithmeticEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -368,42 +368,43 @@ void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
GrTexture* backgroundTex = drawEffect.castEffect<GrArithmeticEffect>().backgroundTexture();
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
const char* dstColor;
if (backgroundTex) {
- builder->fsCodeAppend("\t\tvec4 bgColor = ");
- builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
- builder->fsCodeAppendf(";\n");
+ fsBuilder->codeAppend("\t\tvec4 bgColor = ");
+ fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
+ fsBuilder->codeAppendf(";\n");
dstColor = "bgColor";
} else {
- dstColor = builder->dstColor();
+ dstColor = fsBuilder->dstColor();
}
SkASSERT(NULL != dstColor);
- fKUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fKUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "k");
const char* kUni = builder->getUniformCStr(fKUni);
// We don't try to optimize for this case at all
if (NULL == inputColor) {
- builder->fsCodeAppendf("\t\tconst vec4 src = vec4(1);\n");
+ fsBuilder->codeAppendf("\t\tconst vec4 src = vec4(1);\n");
} else {
- builder->fsCodeAppendf("\t\tvec4 src = %s;\n", inputColor);
+ fsBuilder->codeAppendf("\t\tvec4 src = %s;\n", inputColor);
if (gUseUnpremul) {
- builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\n");
+ fsBuilder->codeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\n");
}
}
- builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor);
+ fsBuilder->codeAppendf("\t\tvec4 dst = %s;\n", dstColor);
if (gUseUnpremul) {
- builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n");
+ fsBuilder->codeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n");
}
- builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;\n", outputColor, kUni, kUni, kUni, kUni);
- builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
+ fsBuilder->codeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;\n", outputColor, kUni, kUni, kUni, kUni);
+ fsBuilder->codeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
if (gUseUnpremul) {
- builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
+ fsBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
} else if (fEnforcePMColor) {
- builder->fsCodeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor, outputColor, outputColor);
+ fsBuilder->codeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor, outputColor, outputColor);
}
}
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 4e469bca9b..e4133a8bce 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -22,7 +22,7 @@
#include "GrTexture.h"
#include "GrEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "effects/GrSimpleTextureEffect.h"
#include "GrTBackendEffectFactory.h"
#include "SkGrPixelRef.h"
@@ -610,7 +610,7 @@ class GrGLRectBlurEffect : public GrGLEffect {
public:
GrGLRectBlurEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -635,23 +635,23 @@ GrGLRectBlurEffect::GrGLRectBlurEffect(const GrBackendEffectFactory& factory, co
: INHERITED(factory) {
}
-void OutputRectBlurProfileLookup(GrGLShaderBuilder* builder,
+void OutputRectBlurProfileLookup(GrGLFragmentShaderBuilder* fsBuilder,
const GrGLShaderBuilder::TextureSampler& sampler,
const char *output,
const char *profileSize, const char *loc,
const char *blurred_width,
const char *sharp_width) {
- builder->fsCodeAppendf("\tfloat %s;\n", output);
- builder->fsCodeAppendf("\t\t{\n");
- builder->fsCodeAppendf("\t\t\tfloat coord = (0.5 * (abs(2.0*%s - %s) - %s))/%s;\n",
+ fsBuilder->codeAppendf("\tfloat %s;\n", output);
+ fsBuilder->codeAppendf("\t\t{\n");
+ fsBuilder->codeAppendf("\t\t\tfloat coord = (0.5 * (abs(2.0*%s - %s) - %s))/%s;\n",
loc, blurred_width, sharp_width, profileSize);
- builder->fsCodeAppendf("\t\t\t%s = ", output);
- builder->fsAppendTextureLookup(sampler, "vec2(coord,0.5)");
- builder->fsCodeAppend(".a;\n");
- builder->fsCodeAppendf("\t\t}\n");
+ fsBuilder->codeAppendf("\t\t\t%s = ", output);
+ fsBuilder->appendTextureLookup(sampler, "vec2(coord,0.5)");
+ fsBuilder->codeAppend(".a;\n");
+ fsBuilder->codeAppendf("\t\t}\n");
}
-void GrGLRectBlurEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLRectBlurEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -662,36 +662,37 @@ void GrGLRectBlurEffect::emitCode(GrGLShaderBuilder* builder,
const char *rectName;
const char *profileSizeName;
- fProxyRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
"proxyRect",
&rectName);
- fProfileSizeUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fProfileSizeUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType,
"profileSize",
&profileSizeName);
- const char *fragmentPos = builder->fragmentPosition();
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ const char *fragmentPos = fsBuilder->fragmentPosition();
if (inputColor) {
- builder->fsCodeAppendf("\tvec4 src=%s;\n", inputColor);
+ fsBuilder->codeAppendf("\tvec4 src=%s;\n", inputColor);
} else {
- builder->fsCodeAppendf("\tvec4 src=vec4(1)\n;");
+ fsBuilder->codeAppendf("\tvec4 src=vec4(1)\n;");
}
- builder->fsCodeAppendf("\tvec2 translatedPos = %s.xy - %s.xy;\n", fragmentPos, rectName );
- builder->fsCodeAppendf("\tfloat width = %s.z - %s.x;\n", rectName, rectName);
- builder->fsCodeAppendf("\tfloat height = %s.w - %s.y;\n", rectName, rectName);
+ fsBuilder->codeAppendf("\tvec2 translatedPos = %s.xy - %s.xy;\n", fragmentPos, rectName );
+ fsBuilder->codeAppendf("\tfloat width = %s.z - %s.x;\n", rectName, rectName);
+ fsBuilder->codeAppendf("\tfloat height = %s.w - %s.y;\n", rectName, rectName);
- builder->fsCodeAppendf("\tvec2 smallDims = vec2(width - %s, height-%s);\n", profileSizeName, profileSizeName);
- builder->fsCodeAppendf("\tfloat center = 2.0 * floor(%s/2.0 + .25) - 1.0;\n", profileSizeName);
- builder->fsCodeAppendf("\tvec2 wh = smallDims - vec2(center,center);\n");
+ fsBuilder->codeAppendf("\tvec2 smallDims = vec2(width - %s, height-%s);\n", profileSizeName, profileSizeName);
+ fsBuilder->codeAppendf("\tfloat center = 2.0 * floor(%s/2.0 + .25) - 1.0;\n", profileSizeName);
+ fsBuilder->codeAppendf("\tvec2 wh = smallDims - vec2(center,center);\n");
- OutputRectBlurProfileLookup(builder, samplers[0], "horiz_lookup", profileSizeName, "translatedPos.x", "width", "wh.x");
- OutputRectBlurProfileLookup(builder, samplers[0], "vert_lookup", profileSizeName, "translatedPos.y", "height", "wh.y");
+ OutputRectBlurProfileLookup(fsBuilder, samplers[0], "horiz_lookup", profileSizeName, "translatedPos.x", "width", "wh.x");
+ OutputRectBlurProfileLookup(fsBuilder, samplers[0], "vert_lookup", profileSizeName, "translatedPos.y", "height", "wh.y");
- builder->fsCodeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n");
- builder->fsCodeAppendf("\t%s = src * vec4(final);\n", outputColor );
+ fsBuilder->codeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n");
+ fsBuilder->codeAppendf("\t%s = src * vec4(final);\n", outputColor );
}
void GrGLRectBlurEffect::setData(const GrGLProgramDataManager& pdman,
@@ -971,7 +972,7 @@ class GrGLRRectBlurEffect : public GrGLEffect {
public:
GrGLRRectBlurEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -993,7 +994,7 @@ GrGLRRectBlurEffect::GrGLRRectBlurEffect(const GrBackendEffectFactory& factory,
: INHERITED (factory) {
}
-void GrGLRRectBlurEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLRRectBlurEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -1007,45 +1008,47 @@ void GrGLRRectBlurEffect::emitCode(GrGLShaderBuilder* builder,
// The proxy rect has left, top, right, and bottom edges correspond to
// components x, y, z, and w, respectively.
- fProxyRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
"proxyRect",
&rectName);
- fCornerRadiusUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fCornerRadiusUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType,
"cornerRadius",
&cornerRadiusName);
- fBlurRadiusUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fBlurRadiusUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType,
"blurRadius",
&blurRadiusName);
- const char* fragmentPos = builder->fragmentPosition();
+
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ const char* fragmentPos = fsBuilder->fragmentPosition();
// warp the fragment position to the appropriate part of the 9patch blur texture
- builder->fsCodeAppendf("\t\tvec2 rectCenter = (%s.xy + %s.zw)/2.0;\n", rectName, rectName);
- builder->fsCodeAppendf("\t\tvec2 translatedFragPos = %s.xy - %s.xy;\n", fragmentPos, rectName);
- builder->fsCodeAppendf("\t\tfloat threshold = %s + 2.0*%s;\n", cornerRadiusName, blurRadiusName );
- builder->fsCodeAppendf("\t\tvec2 middle = %s.zw - %s.xy - 2.0*threshold;\n", rectName, rectName );
-
- builder->fsCodeAppendf("\t\tif (translatedFragPos.x >= threshold && translatedFragPos.x < (middle.x+threshold)) {\n" );
- builder->fsCodeAppendf("\t\t\ttranslatedFragPos.x = threshold;\n");
- builder->fsCodeAppendf("\t\t} else if (translatedFragPos.x >= (middle.x + threshold)) {\n");
- builder->fsCodeAppendf("\t\t\ttranslatedFragPos.x -= middle.x - 1.0;\n");
- builder->fsCodeAppendf("\t\t}\n");
-
- builder->fsCodeAppendf("\t\tif (translatedFragPos.y > threshold && translatedFragPos.y < (middle.y+threshold)) {\n" );
- builder->fsCodeAppendf("\t\t\ttranslatedFragPos.y = threshold;\n");
- builder->fsCodeAppendf("\t\t} else if (translatedFragPos.y >= (middle.y + threshold)) {\n");
- builder->fsCodeAppendf("\t\t\ttranslatedFragPos.y -= middle.y - 1.0;\n");
- builder->fsCodeAppendf("\t\t}\n");
-
- builder->fsCodeAppendf("\t\tvec2 proxyDims = vec2(2.0*threshold+1.0);\n");
- builder->fsCodeAppendf("\t\tvec2 texCoord = translatedFragPos / proxyDims;\n");
-
- builder->fsCodeAppendf("\t%s = ", outputColor);
- builder->fsAppendTextureLookupAndModulate(inputColor, samplers[0], "texCoord");
- builder->fsCodeAppend(";\n");
+ fsBuilder->codeAppendf("\t\tvec2 rectCenter = (%s.xy + %s.zw)/2.0;\n", rectName, rectName);
+ fsBuilder->codeAppendf("\t\tvec2 translatedFragPos = %s.xy - %s.xy;\n", fragmentPos, rectName);
+ fsBuilder->codeAppendf("\t\tfloat threshold = %s + 2.0*%s;\n", cornerRadiusName, blurRadiusName );
+ fsBuilder->codeAppendf("\t\tvec2 middle = %s.zw - %s.xy - 2.0*threshold;\n", rectName, rectName );
+
+ fsBuilder->codeAppendf("\t\tif (translatedFragPos.x >= threshold && translatedFragPos.x < (middle.x+threshold)) {\n" );
+ fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x = threshold;\n");
+ fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.x >= (middle.x + threshold)) {\n");
+ fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x -= middle.x - 1.0;\n");
+ fsBuilder->codeAppendf("\t\t}\n");
+
+ fsBuilder->codeAppendf("\t\tif (translatedFragPos.y > threshold && translatedFragPos.y < (middle.y+threshold)) {\n" );
+ fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y = threshold;\n");
+ fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.y >= (middle.y + threshold)) {\n");
+ fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y -= middle.y - 1.0;\n");
+ fsBuilder->codeAppendf("\t\t}\n");
+
+ fsBuilder->codeAppendf("\t\tvec2 proxyDims = vec2(2.0*threshold+1.0);\n");
+ fsBuilder->codeAppendf("\t\tvec2 texCoord = translatedFragPos / proxyDims;\n");
+
+ fsBuilder->codeAppendf("\t%s = ", outputColor);
+ fsBuilder->appendTextureLookupAndModulate(inputColor, samplers[0], "texCoord");
+ fsBuilder->codeAppend(";\n");
}
void GrGLRRectBlurEffect::setData(const GrGLProgramDataManager& pdman,
diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp
index bcaabf6c9b..e825695d58 100644
--- a/src/effects/SkColorFilters.cpp
+++ b/src/effects/SkColorFilters.cpp
@@ -127,7 +127,7 @@ SkFlattenable* SkModeColorFilter::CreateProc(SkReadBuffer& buffer) {
#include "GrEffectUnitTest.h"
#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "SkGr.h"
namespace {
@@ -222,7 +222,7 @@ public:
: INHERITED(factory) {
}
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -234,7 +234,7 @@ public:
SkASSERT(SkXfermode::kDst_Mode != mode);
const char* colorFilterColorUniName = NULL;
if (drawEffect.castEffect<ModeColorFilterEffect>().willUseFilterColor()) {
- fFilterColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fFilterColorUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "FilterColor",
&colorFilterColorUniName);
}
@@ -242,7 +242,8 @@ public:
GrGLSLExpr4 filter =
color_filter_expression(mode, GrGLSLExpr4(colorFilterColorUniName), GrGLSLExpr4(inputColor));
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor, filter.c_str());
+ builder->getFragmentShaderBuilder()->
+ codeAppendf("\t%s = %s;\n", outputColor, filter.c_str());
}
static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index f62e0f1462..beed67efcf 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -335,7 +335,7 @@ bool SkColorMatrixFilter::asColorMatrix(SkScalar matrix[20]) const {
#include "GrEffect.h"
#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
class ColorMatrixEffect : public GrEffect {
public:
@@ -406,17 +406,17 @@ public:
: INHERITED(factory) {
}
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE {
- fMatrixHandle = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fMatrixHandle = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kMat44f_GrSLType,
"ColorMatrix");
- fVectorHandle = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fVectorHandle = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
"ColorMatrixVector");
@@ -424,16 +424,17 @@ public:
// could optimize this case, but we aren't for now.
inputColor = "vec4(1)";
}
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
// The max() is to guard against 0 / 0 during unpremul when the incoming color is
// transparent black.
- builder->fsCodeAppendf("\tfloat nonZeroAlpha = max(%s.a, 0.00001);\n", inputColor);
- builder->fsCodeAppendf("\t%s = %s * vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha) + %s;\n",
+ fsBuilder->codeAppendf("\tfloat nonZeroAlpha = max(%s.a, 0.00001);\n", inputColor);
+ fsBuilder->codeAppendf("\t%s = %s * vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha) + %s;\n",
outputColor,
builder->getUniformCStr(fMatrixHandle),
inputColor,
builder->getUniformCStr(fVectorHandle));
- builder->fsCodeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
- builder->fsCodeAppendf("\t%s.rgb *= %s.a;\n", outputColor, outputColor);
+ fsBuilder->codeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
+ fsBuilder->codeAppendf("\t%s.rgb *= %s.a;\n", outputColor, outputColor);
}
virtual void setData(const GrGLProgramDataManager& uniManager,
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index 27fc0d3722..a1d29bf427 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -14,7 +14,7 @@
#include "GrContext.h"
#include "GrCoordTransform.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrTBackendEffectFactory.h"
#endif
@@ -302,7 +302,7 @@ public:
const GrDrawEffect& drawEffect);
virtual ~GrGLDisplacementMapEffect();
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -540,7 +540,7 @@ GrGLDisplacementMapEffect::GrGLDisplacementMapEffect(const GrBackendEffectFactor
GrGLDisplacementMapEffect::~GrGLDisplacementMapEffect() {
}
-void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLDisplacementMapEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -549,7 +549,7 @@ void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
sk_ignore_unused_variable(inputColor);
- fScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fScaleUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "Scale");
const char* scaleUni = builder->getUniformCStr(fScaleUni);
const char* dColor = "dColor";
@@ -559,29 +559,30 @@ void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder,
// a number smaller than that to approximate 0, but
// leave room for 32-bit float GPU rounding errors.
- builder->fsCodeAppendf("\t\tvec4 %s = ", dColor);
- builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
- builder->fsCodeAppend(";\n");
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("\t\tvec4 %s = ", dColor);
+ fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
+ fsBuilder->codeAppend(";\n");
// Unpremultiply the displacement
- builder->fsCodeAppendf("\t\t%s.rgb = (%s.a < %s) ? vec3(0.0) : clamp(%s.rgb / %s.a, 0.0, 1.0);",
+ fsBuilder->codeAppendf("\t\t%s.rgb = (%s.a < %s) ? vec3(0.0) : clamp(%s.rgb / %s.a, 0.0, 1.0);",
dColor, dColor, nearZero, dColor, dColor);
- builder->fsCodeAppendf("\t\tvec2 %s = %s + %s*(%s.",
+ fsBuilder->codeAppendf("\t\tvec2 %s = %s + %s*(%s.",
cCoords, coords[1].c_str(), scaleUni, dColor);
switch (fXChannelSelector) {
case SkDisplacementMapEffect::kR_ChannelSelectorType:
- builder->fsCodeAppend("r");
+ fsBuilder->codeAppend("r");
break;
case SkDisplacementMapEffect::kG_ChannelSelectorType:
- builder->fsCodeAppend("g");
+ fsBuilder->codeAppend("g");
break;
case SkDisplacementMapEffect::kB_ChannelSelectorType:
- builder->fsCodeAppend("b");
+ fsBuilder->codeAppend("b");
break;
case SkDisplacementMapEffect::kA_ChannelSelectorType:
- builder->fsCodeAppend("a");
+ fsBuilder->codeAppend("a");
break;
case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
default:
@@ -590,31 +591,31 @@ void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder,
switch (fYChannelSelector) {
case SkDisplacementMapEffect::kR_ChannelSelectorType:
- builder->fsCodeAppend("r");
+ fsBuilder->codeAppend("r");
break;
case SkDisplacementMapEffect::kG_ChannelSelectorType:
- builder->fsCodeAppend("g");
+ fsBuilder->codeAppend("g");
break;
case SkDisplacementMapEffect::kB_ChannelSelectorType:
- builder->fsCodeAppend("b");
+ fsBuilder->codeAppend("b");
break;
case SkDisplacementMapEffect::kA_ChannelSelectorType:
- builder->fsCodeAppend("a");
+ fsBuilder->codeAppend("a");
break;
case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
default:
SkDEBUGFAIL("Unknown Y channel selector");
}
- builder->fsCodeAppend("-vec2(0.5));\t\t");
+ fsBuilder->codeAppend("-vec2(0.5));\t\t");
// FIXME : This can be achieved with a "clamp to border" texture repeat mode and
// a 0 border color instead of computing if cCoords is out of bounds here.
- builder->fsCodeAppendf(
+ fsBuilder->codeAppendf(
"bool %s = (%s.x < 0.0) || (%s.y < 0.0) || (%s.x > 1.0) || (%s.y > 1.0);\t\t",
outOfBounds, cCoords, cCoords, cCoords, cCoords);
- builder->fsCodeAppendf("%s = %s ? vec4(0.0) : ", outputColor, outOfBounds);
- builder->fsAppendTextureLookup(samplers[1], cCoords, coords[1].type());
- builder->fsCodeAppend(";\n");
+ fsBuilder->codeAppendf("%s = %s ? vec4(0.0) : ", outputColor, outOfBounds);
+ fsBuilder->appendTextureLookup(samplers[1], cCoords, coords[1].type());
+ fsBuilder->codeAppend(";\n");
}
void GrGLDisplacementMapEffect::setData(const GrGLProgramDataManager& pdman,
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index d93f4cc9e2..c3834c6977 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -17,7 +17,7 @@
#if SK_SUPPORT_GPU
#include "effects/GrSingleTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrEffect.h"
#include "GrTBackendEffectFactory.h"
@@ -432,7 +432,7 @@ public:
* This is called by GrGLLightingEffect::emitCode() before either of the two virtual functions
* below. It adds a vec3f uniform visible in the FS that represents the constant light color.
*/
- void emitLightColorUniform(GrGLShaderBuilder*);
+ void emitLightColorUniform(GrGLProgramBuilder*);
/**
* These two functions are called from GrGLLightingEffect's emitCode() function.
@@ -442,8 +442,8 @@ public:
* the FS. The default of emitLightColor appends the name of the constant light color uniform
* and so this function only needs to be overridden if the light color varies spatially.
*/
- virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) = 0;
- virtual void emitLightColor(GrGLShaderBuilder*, const char *surfaceToLight);
+ virtual void emitSurfaceToLight(GrGLProgramBuilder*, const char* z) = 0;
+ virtual void emitLightColor(GrGLProgramBuilder*, const char *surfaceToLight);
// This is called from GrGLLightingEffect's setData(). Subclasses of GrGLLight must call
// INHERITED::setData().
@@ -470,7 +470,7 @@ public:
virtual ~GrGLDistantLight() {}
virtual void setData(const GrGLProgramDataManager&,
const SkLight* light) const SK_OVERRIDE;
- virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
+ virtual void emitSurfaceToLight(GrGLProgramBuilder*, const char* z) SK_OVERRIDE;
private:
typedef GrGLLight INHERITED;
@@ -484,7 +484,7 @@ public:
virtual ~GrGLPointLight() {}
virtual void setData(const GrGLProgramDataManager&,
const SkLight* light) const SK_OVERRIDE;
- virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
+ virtual void emitSurfaceToLight(GrGLProgramBuilder*, const char* z) SK_OVERRIDE;
private:
typedef GrGLLight INHERITED;
@@ -498,8 +498,8 @@ public:
virtual ~GrGLSpotLight() {}
virtual void setData(const GrGLProgramDataManager&,
const SkLight* light) const SK_OVERRIDE;
- virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
- virtual void emitLightColor(GrGLShaderBuilder*, const char *surfaceToLight) SK_OVERRIDE;
+ virtual void emitSurfaceToLight(GrGLProgramBuilder*, const char* z) SK_OVERRIDE;
+ virtual void emitLightColor(GrGLProgramBuilder*, const char *surfaceToLight) SK_OVERRIDE;
private:
typedef GrGLLight INHERITED;
@@ -1206,7 +1206,7 @@ public:
const GrDrawEffect& effect);
virtual ~GrGLLightingEffect();
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -1222,7 +1222,7 @@ public:
virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE;
protected:
- virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) = 0;
+ virtual void emitLightFunc(GrGLProgramBuilder*, SkString* funcName) = 0;
private:
typedef GrGLEffect INHERITED;
@@ -1238,7 +1238,7 @@ class GrGLDiffuseLightingEffect : public GrGLLightingEffect {
public:
GrGLDiffuseLightingEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& drawEffect);
- virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) SK_OVERRIDE;
+ virtual void emitLightFunc(GrGLProgramBuilder*, SkString* funcName) SK_OVERRIDE;
virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE;
private:
@@ -1253,7 +1253,7 @@ class GrGLSpecularLightingEffect : public GrGLLightingEffect {
public:
GrGLSpecularLightingEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& effect);
- virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) SK_OVERRIDE;
+ virtual void emitLightFunc(GrGLProgramBuilder*, SkString* funcName) SK_OVERRIDE;
virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE;
private:
@@ -1341,19 +1341,17 @@ GrGLLightingEffect::~GrGLLightingEffect() {
delete fLight;
}
-void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLLightingEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString coords2D = builder->ensureFSCoords2D(coords, 0);
-
- fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType,
"ImageIncrement");
- fSurfaceScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fSurfaceScaleUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType,
"SurfaceScale");
fLight->emitLightColorUniform(builder);
@@ -1369,7 +1367,10 @@ void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder,
GrGLShaderVar("scale", kFloat_GrSLType),
};
SkString sobelFuncName;
- builder->fsEmitFunction(kFloat_GrSLType,
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+
+ fsBuilder->emitFunction(kFloat_GrSLType,
"sobel",
SK_ARRAY_COUNT(gSobelArgs),
gSobelArgs,
@@ -1381,7 +1382,7 @@ void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder,
GrGLShaderVar("scale", kFloat_GrSLType),
};
SkString pointToNormalName;
- builder->fsEmitFunction(kVec3f_GrSLType,
+ fsBuilder->emitFunction(kVec3f_GrSLType,
"pointToNormal",
SK_ARRAY_COUNT(gPointToNormalArgs),
gPointToNormalArgs,
@@ -1400,15 +1401,15 @@ void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder,
sobelFuncName.c_str(),
sobelFuncName.c_str());
SkString interiorNormalName;
- builder->fsEmitFunction(kVec3f_GrSLType,
+ fsBuilder->emitFunction(kVec3f_GrSLType,
"interiorNormal",
SK_ARRAY_COUNT(gInteriorNormalArgs),
gInteriorNormalArgs,
interiorNormalBody.c_str(),
&interiorNormalName);
- builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
- builder->fsCodeAppend("\t\tfloat m[9];\n");
+ fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
+ fsBuilder->codeAppend("\t\tfloat m[9];\n");
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
const char* surfScale = builder->getUniformCStr(fSurfaceScaleUni);
@@ -1418,23 +1419,23 @@ void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder,
for (int dx = -1; dx <= 1; dx++) {
SkString texCoords;
texCoords.appendf("coord + vec2(%d, %d) * %s", dx, dy, imgInc);
- builder->fsCodeAppendf("\t\tm[%d] = ", index++);
- builder->fsAppendTextureLookup(samplers[0], texCoords.c_str());
- builder->fsCodeAppend(".a;\n");
+ fsBuilder->codeAppendf("\t\tm[%d] = ", index++);
+ fsBuilder->appendTextureLookup(samplers[0], texCoords.c_str());
+ fsBuilder->codeAppend(".a;\n");
}
}
- builder->fsCodeAppend("\t\tvec3 surfaceToLight = ");
+ fsBuilder->codeAppend("\t\tvec3 surfaceToLight = ");
SkString arg;
arg.appendf("%s * m[4]", surfScale);
fLight->emitSurfaceToLight(builder, arg.c_str());
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppendf("\t\t%s = %s(%s(m, %s), surfaceToLight, ",
+ fsBuilder->codeAppend(";\n");
+ fsBuilder->codeAppendf("\t\t%s = %s(%s(m, %s), surfaceToLight, ",
outputColor, lightFunc.c_str(), interiorNormalName.c_str(), surfScale);
fLight->emitLightColor(builder, "surfaceToLight");
- builder->fsCodeAppend(");\n");
+ fsBuilder->codeAppend(");\n");
SkString modulate;
GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
- builder->fsCodeAppend(modulate.c_str());
+ fsBuilder->codeAppend(modulate.c_str());
}
void GrGLLightingEffect::GenKey(const GrDrawEffect& drawEffect,
@@ -1462,9 +1463,9 @@ GrGLDiffuseLightingEffect::GrGLDiffuseLightingEffect(const GrBackendEffectFactor
: INHERITED(factory, drawEffect) {
}
-void GrGLDiffuseLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkString* funcName) {
+void GrGLDiffuseLightingEffect::emitLightFunc(GrGLProgramBuilder* builder, SkString* funcName) {
const char* kd;
- fKDUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fKDUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType,
"KD",
&kd);
@@ -1477,12 +1478,12 @@ void GrGLDiffuseLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkStri
SkString lightBody;
lightBody.appendf("\tfloat colorScale = %s * dot(normal, surfaceToLight);\n", kd);
lightBody.appendf("\treturn vec4(lightColor * clamp(colorScale, 0.0, 1.0), 1.0);\n");
- builder->fsEmitFunction(kVec4f_GrSLType,
- "light",
- SK_ARRAY_COUNT(gLightArgs),
- gLightArgs,
- lightBody.c_str(),
- funcName);
+ builder->getFragmentShaderBuilder()->emitFunction(kVec4f_GrSLType,
+ "light",
+ SK_ARRAY_COUNT(gLightArgs),
+ gLightArgs,
+ lightBody.c_str(),
+ funcName);
}
void GrGLDiffuseLightingEffect::setData(const GrGLProgramDataManager& pdman,
@@ -1541,13 +1542,13 @@ GrGLSpecularLightingEffect::GrGLSpecularLightingEffect(const GrBackendEffectFact
: INHERITED(factory, drawEffect) {
}
-void GrGLSpecularLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkString* funcName) {
+void GrGLSpecularLightingEffect::emitLightFunc(GrGLProgramBuilder* builder, SkString* funcName) {
const char* ks;
const char* shininess;
- fKSUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fKSUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "KS", &ks);
- fShininessUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fShininessUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "Shininess", &shininess);
static const GrGLShaderVar gLightArgs[] = {
@@ -1560,12 +1561,12 @@ void GrGLSpecularLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkStr
lightBody.appendf("\tfloat colorScale = %s * pow(dot(normal, halfDir), %s);\n", ks, shininess);
lightBody.appendf("\tvec3 color = lightColor * clamp(colorScale, 0.0, 1.0);\n");
lightBody.appendf("\treturn vec4(color, max(max(color.r, color.g), color.b));\n");
- builder->fsEmitFunction(kVec4f_GrSLType,
- "light",
- SK_ARRAY_COUNT(gLightArgs),
- gLightArgs,
- lightBody.c_str(),
- funcName);
+ builder->getFragmentShaderBuilder()->emitFunction(kVec4f_GrSLType,
+ "light",
+ SK_ARRAY_COUNT(gLightArgs),
+ gLightArgs,
+ lightBody.c_str(),
+ funcName);
}
void GrGLSpecularLightingEffect::setData(const GrGLProgramDataManager& pdman,
@@ -1577,14 +1578,15 @@ void GrGLSpecularLightingEffect::setData(const GrGLProgramDataManager& pdman,
}
///////////////////////////////////////////////////////////////////////////////
-void GrGLLight::emitLightColorUniform(GrGLShaderBuilder* builder) {
- fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+void GrGLLight::emitLightColorUniform(GrGLProgramBuilder* builder) {
+ fColorUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec3f_GrSLType, "LightColor");
}
-void GrGLLight::emitLightColor(GrGLShaderBuilder* builder,
+void GrGLLight::emitLightColor(GrGLProgramBuilder* builder,
const char *surfaceToLight) {
- builder->fsCodeAppend(builder->getUniformCStr(this->lightColorUni()));
+ builder->getFragmentShaderBuilder()->
+ codeAppend(builder->getUniformCStr(this->lightColorUni()));
}
void GrGLLight::setData(const GrGLProgramDataManager& pdman,
@@ -1602,11 +1604,11 @@ void GrGLDistantLight::setData(const GrGLProgramDataManager& pdman,
setUniformNormal3(pdman, fDirectionUni, distantLight->direction());
}
-void GrGLDistantLight::emitSurfaceToLight(GrGLShaderBuilder* builder, const char* z) {
+void GrGLDistantLight::emitSurfaceToLight(GrGLProgramBuilder* builder, const char* z) {
const char* dir;
- fDirectionUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec3f_GrSLType,
+ fDirectionUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec3f_GrSLType,
"LightDirection", &dir);
- builder->fsCodeAppend(dir);
+ builder->getFragmentShaderBuilder()->codeAppend(dir);
}
///////////////////////////////////////////////////////////////////////////////
@@ -1619,11 +1621,13 @@ void GrGLPointLight::setData(const GrGLProgramDataManager& pdman,
setUniformPoint3(pdman, fLocationUni, pointLight->location());
}
-void GrGLPointLight::emitSurfaceToLight(GrGLShaderBuilder* builder, const char* z) {
+void GrGLPointLight::emitSurfaceToLight(GrGLProgramBuilder* builder, const char* z) {
const char* loc;
- fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec3f_GrSLType,
+ fLocationUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec3f_GrSLType,
"LightLocation", &loc);
- builder->fsCodeAppendf("normalize(%s - vec3(%s.xy, %s))", loc, builder->fragmentPosition(), z);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))",
+ loc, fsBuilder->fragmentPosition(), z);
}
///////////////////////////////////////////////////////////////////////////////
@@ -1641,15 +1645,17 @@ void GrGLSpotLight::setData(const GrGLProgramDataManager& pdman,
setUniformNormal3(pdman, fSUni, spotLight->s());
}
-void GrGLSpotLight::emitSurfaceToLight(GrGLShaderBuilder* builder, const char* z) {
+void GrGLSpotLight::emitSurfaceToLight(GrGLProgramBuilder* builder, const char* z) {
const char* location;
- fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fLocationUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec3f_GrSLType, "LightLocation", &location);
- builder->fsCodeAppendf("normalize(%s - vec3(%s.xy, %s))",
- location, builder->fragmentPosition(), z);
+
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))",
+ location, fsBuilder->fragmentPosition(), z);
}
-void GrGLSpotLight::emitLightColor(GrGLShaderBuilder* builder,
+void GrGLSpotLight::emitLightColor(GrGLProgramBuilder* builder,
const char *surfaceToLight) {
const char* color = builder->getUniformCStr(this->lightColorUni()); // created by parent class.
@@ -1659,15 +1665,15 @@ void GrGLSpotLight::emitLightColor(GrGLShaderBuilder* builder,
const char* cosOuter;
const char* coneScale;
const char* s;
- fExponentUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fExponentUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "Exponent", &exponent);
- fCosInnerConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fCosInnerConeAngleUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "CosInnerConeAngle", &cosInner);
- fCosOuterConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fCosOuterConeAngleUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "CosOuterConeAngle", &cosOuter);
- fConeScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fConeScaleUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "ConeScale", &coneScale);
- fSUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fSUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec3f_GrSLType, "S", &s);
static const GrGLShaderVar gLightColorArgs[] = {
@@ -1684,14 +1690,15 @@ void GrGLSpotLight::emitLightColor(GrGLShaderBuilder* builder,
color, cosOuter, coneScale);
lightColorBody.appendf("\t}\n");
lightColorBody.appendf("\treturn %s;\n", color);
- builder->fsEmitFunction(kVec3f_GrSLType,
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->emitFunction(kVec3f_GrSLType,
"lightColor",
SK_ARRAY_COUNT(gLightColorArgs),
gLightColorArgs,
lightColorBody.c_str(),
&fLightColorFunc);
- builder->fsCodeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight);
+ fsBuilder->codeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight);
}
#endif
diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp
index 26621bb02e..c1ce05c530 100644
--- a/src/effects/SkLumaColorFilter.cpp
+++ b/src/effects/SkLumaColorFilter.cpp
@@ -12,7 +12,7 @@
#if SK_SUPPORT_GPU
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrContext.h"
#include "GrTBackendEffectFactory.h"
#endif
@@ -89,7 +89,7 @@ public:
static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder* b) {}
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -100,12 +100,13 @@ public:
inputColor = "vec4(1)";
}
- builder->fsCodeAppendf("\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb);\n",
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb);\n",
SK_ITU_BT709_LUM_COEFF_R,
SK_ITU_BT709_LUM_COEFF_G,
SK_ITU_BT709_LUM_COEFF_B,
inputColor);
- builder->fsCodeAppendf("\t%s = vec4(0, 0, 0, luma);\n",
+ fsBuilder->codeAppendf("\t%s = vec4(0, 0, 0, luma);\n",
outputColor);
}
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index cb0fc2423f..bf6f4a7725 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -16,7 +16,7 @@
#if SK_SUPPORT_GPU
#include "effects/GrSingleTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
#include "GrTBackendEffectFactory.h"
@@ -95,7 +95,7 @@ class GrGLMagnifierEffect : public GrGLEffect {
public:
GrGLMagnifierEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -117,57 +117,58 @@ GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory,
: INHERITED(factory) {
}
-void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLMagnifierEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString coords2D = builder->ensureFSCoords2D(coords, 0);
fOffsetVar = builder->addUniform(
- GrGLShaderBuilder::kFragment_Visibility |
- GrGLShaderBuilder::kVertex_Visibility,
+ GrGLProgramBuilder::kFragment_Visibility |
+ GrGLProgramBuilder::kVertex_Visibility,
kVec2f_GrSLType, "Offset");
fInvZoomVar = builder->addUniform(
- GrGLShaderBuilder::kFragment_Visibility |
- GrGLShaderBuilder::kVertex_Visibility,
+ GrGLProgramBuilder::kFragment_Visibility |
+ GrGLProgramBuilder::kVertex_Visibility,
kVec2f_GrSLType, "InvZoom");
fInvInsetVar = builder->addUniform(
- GrGLShaderBuilder::kFragment_Visibility |
- GrGLShaderBuilder::kVertex_Visibility,
+ GrGLProgramBuilder::kFragment_Visibility |
+ GrGLProgramBuilder::kVertex_Visibility,
kVec2f_GrSLType, "InvInset");
- builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
- builder->fsCodeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n",
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+ fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
+ fsBuilder->codeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n",
builder->getUniformCStr(fOffsetVar),
coords2D.c_str(),
builder->getUniformCStr(fInvZoomVar));
- builder->fsCodeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\n");
+ fsBuilder->codeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\n");
- builder->fsCodeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr(fInvInsetVar));
+ fsBuilder->codeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr(fInvInsetVar));
- builder->fsCodeAppend("\t\tfloat weight = 0.0;\n");
- builder->fsCodeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n");
- builder->fsCodeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n");
- builder->fsCodeAppend("\t\t\tfloat dist = length(delta);\n");
- builder->fsCodeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n");
- builder->fsCodeAppend("\t\t\tweight = min(dist * dist, 1.0);\n");
- builder->fsCodeAppend("\t\t} else {\n");
- builder->fsCodeAppend("\t\t\tvec2 delta_squared = delta * delta;\n");
- builder->fsCodeAppend("\t\t\tweight = min(min(delta_squared.x, delta_squared.y), 1.0);\n");
- builder->fsCodeAppend("\t\t}\n");
+ fsBuilder->codeAppend("\t\tfloat weight = 0.0;\n");
+ fsBuilder->codeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n");
+ fsBuilder->codeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n");
+ fsBuilder->codeAppend("\t\t\tfloat dist = length(delta);\n");
+ fsBuilder->codeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n");
+ fsBuilder->codeAppend("\t\t\tweight = min(dist * dist, 1.0);\n");
+ fsBuilder->codeAppend("\t\t} else {\n");
+ fsBuilder->codeAppend("\t\t\tvec2 delta_squared = delta * delta;\n");
+ fsBuilder->codeAppend("\t\t\tweight = min(min(delta_squared.x, delta_squared.y), 1.0);\n");
+ fsBuilder->codeAppend("\t\t}\n");
- builder->fsCodeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n");
- builder->fsCodeAppend("\t\tvec4 output_color = ");
- builder->fsAppendTextureLookup(samplers[0], "mix_coord");
- builder->fsCodeAppend(";\n");
+ fsBuilder->codeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n");
+ fsBuilder->codeAppend("\t\tvec4 output_color = ");
+ fsBuilder->appendTextureLookup(samplers[0], "mix_coord");
+ fsBuilder->codeAppend(";\n");
- builder->fsCodeAppendf("\t\t%s = output_color;", outputColor);
+ fsBuilder->codeAppendf("\t\t%s = output_color;", outputColor);
SkString modulate;
GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
- builder->fsCodeAppend(modulate.c_str());
+ fsBuilder->codeAppend(modulate.c_str());
}
void GrGLMagnifierEffect::setData(const GrGLProgramDataManager& pdman,
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index bb8478c907..eef2a7d623 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -17,7 +17,7 @@
#include "GrTexture.h"
#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "effects/Gr1DKernelEffect.h"
#endif
@@ -329,7 +329,7 @@ class GrGLMorphologyEffect : public GrGLEffect {
public:
GrGLMorphologyEffect (const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -359,25 +359,26 @@ GrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendEffectFactory& factory
fType = m.type();
}
-void GrGLMorphologyEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLMorphologyEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString coords2D = builder->ensureFSCoords2D(coords, 0);
- fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "ImageIncrement");
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
const char* func;
switch (fType) {
case GrMorphologyEffect::kErode_MorphologyType:
- builder->fsCodeAppendf("\t\t%s = vec4(1, 1, 1, 1);\n", outputColor);
+ fsBuilder->codeAppendf("\t\t%s = vec4(1, 1, 1, 1);\n", outputColor);
func = "min";
break;
case GrMorphologyEffect::kDilate_MorphologyType:
- builder->fsCodeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor);
+ fsBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor);
func = "max";
break;
default:
@@ -387,16 +388,16 @@ void GrGLMorphologyEffect::emitCode(GrGLShaderBuilder* builder,
}
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
- builder->fsCodeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
- builder->fsCodeAppendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width());
- builder->fsCodeAppendf("\t\t\t%s = %s(%s, ", outputColor, func, outputColor);
- builder->fsAppendTextureLookup(samplers[0], "coord");
- builder->fsCodeAppend(");\n");
- builder->fsCodeAppendf("\t\t\tcoord += %s;\n", imgInc);
- builder->fsCodeAppend("\t\t}\n");
+ fsBuilder->codeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
+ fsBuilder->codeAppendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width());
+ fsBuilder->codeAppendf("\t\t\t%s = %s(%s, ", outputColor, func, outputColor);
+ fsBuilder->appendTextureLookup(samplers[0], "coord");
+ fsBuilder->codeAppend(");\n");
+ fsBuilder->codeAppendf("\t\t\tcoord += %s;\n", imgInc);
+ fsBuilder->codeAppend("\t\t}\n");
SkString modulate;
GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
- builder->fsCodeAppend(modulate.c_str());
+ fsBuilder->codeAppend(modulate.c_str());
}
void GrGLMorphologyEffect::GenKey(const GrDrawEffect& drawEffect,
diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp
index 427b451dd0..b0ebb39342 100644
--- a/src/effects/SkPerlinNoiseShader.cpp
+++ b/src/effects/SkPerlinNoiseShader.cpp
@@ -18,7 +18,7 @@
#include "GrContext.h"
#include "GrCoordTransform.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrTBackendEffectFactory.h"
#include "SkGr.h"
#endif
@@ -515,7 +515,7 @@ public:
const GrDrawEffect& drawEffect);
virtual ~GrGLPerlinNoise() {}
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -663,7 +663,7 @@ GrGLPerlinNoise::GrGLPerlinNoise(const GrBackendEffectFactory& factory, const Gr
, fNumOctaves(drawEffect.castEffect<GrPerlinNoiseEffect>().numOctaves()) {
}
-void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
+void GrGLPerlinNoise::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -672,18 +672,19 @@ void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
sk_ignore_unused_variable(inputColor);
- SkString vCoords = builder->ensureFSCoords2D(coords, 0);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString vCoords = fsBuilder->ensureFSCoords2D(coords, 0);
- fBaseFrequencyUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fBaseFrequencyUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "baseFrequency");
const char* baseFrequencyUni = builder->getUniformCStr(fBaseFrequencyUni);
- fAlphaUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fAlphaUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "alpha");
const char* alphaUni = builder->getUniformCStr(fAlphaUni);
const char* stitchDataUni = NULL;
if (fStitchTiles) {
- fStitchDataUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fStitchDataUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "stitchData");
stitchDataUni = builder->getUniformCStr(fStitchDataUni);
}
@@ -755,7 +756,7 @@ void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
xCoords.appendf("vec2(%s.x, 0.5)", floorVal);
noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx);
- builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
+ fsBuilder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
noiseCode.append(".r;");
}
@@ -765,7 +766,7 @@ void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
xCoords.appendf("vec2(%s.z, 0.5)", floorVal);
noiseCode.appendf("\n\t%s.y = ", latticeIdx);
- builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
+ fsBuilder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
noiseCode.append(".r;");
}
@@ -789,7 +790,7 @@ void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
SkString latticeCoords("");
latticeCoords.appendf("vec2(%s.x, %s)", bcoords, chanCoord);
noiseCode.appendf("\n\tvec4 %s = ", lattice);
- builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
+ fsBuilder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
kVec2f_GrSLType);
noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
@@ -801,7 +802,7 @@ void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
SkString latticeCoords("");
latticeCoords.appendf("vec2(%s.y, %s)", bcoords, chanCoord);
noiseCode.append("\n\tlattice = ");
- builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
+ fsBuilder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
kVec2f_GrSLType);
noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
@@ -817,7 +818,7 @@ void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
SkString latticeCoords("");
latticeCoords.appendf("vec2(%s.w, %s)", bcoords, chanCoord);
noiseCode.append("\n\tlattice = ");
- builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
+ fsBuilder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
kVec2f_GrSLType);
noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
@@ -829,7 +830,7 @@ void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
SkString latticeCoords("");
latticeCoords.appendf("vec2(%s.z, %s)", bcoords, chanCoord);
noiseCode.append("\n\tlattice = ");
- builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
+ fsBuilder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
kVec2f_GrSLType);
noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
@@ -842,38 +843,38 @@ void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
SkString noiseFuncName;
if (fStitchTiles) {
- builder->fsEmitFunction(kFloat_GrSLType,
+ fsBuilder->emitFunction(kFloat_GrSLType,
"perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs),
gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName);
} else {
- builder->fsEmitFunction(kFloat_GrSLType,
+ fsBuilder->emitFunction(kFloat_GrSLType,
"perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs),
gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName);
}
// There are rounding errors if the floor operation is not performed here
- builder->fsCodeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;",
+ fsBuilder->codeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;",
noiseVec, vCoords.c_str(), baseFrequencyUni);
// Clear the color accumulator
- builder->fsCodeAppendf("\n\t\t%s = vec4(0.0);", outputColor);
+ fsBuilder->codeAppendf("\n\t\t%s = vec4(0.0);", outputColor);
if (fStitchTiles) {
// Set up TurbulenceInitial stitch values.
- builder->fsCodeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni);
+ fsBuilder->codeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni);
}
- builder->fsCodeAppendf("\n\t\tfloat %s = 1.0;", ratio);
+ fsBuilder->codeAppendf("\n\t\tfloat %s = 1.0;", ratio);
// Loop over all octaves
- builder->fsCodeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {", fNumOctaves);
+ fsBuilder->codeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {", fNumOctaves);
- builder->fsCodeAppendf("\n\t\t\t%s += ", outputColor);
+ fsBuilder->codeAppendf("\n\t\t\t%s += ", outputColor);
if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
- builder->fsCodeAppend("abs(");
+ fsBuilder->codeAppend("abs(");
}
if (fStitchTiles) {
- builder->fsCodeAppendf(
+ fsBuilder->codeAppendf(
"vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s),"
"\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))",
noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData,
@@ -881,7 +882,7 @@ void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData,
noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData);
} else {
- builder->fsCodeAppendf(
+ fsBuilder->codeAppendf(
"vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s),"
"\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))",
noiseFuncName.c_str(), chanCoordR, noiseVec,
@@ -890,31 +891,31 @@ void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
noiseFuncName.c_str(), chanCoordA, noiseVec);
}
if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
- builder->fsCodeAppendf(")"); // end of "abs("
+ fsBuilder->codeAppendf(")"); // end of "abs("
}
- builder->fsCodeAppendf(" * %s;", ratio);
+ fsBuilder->codeAppendf(" * %s;", ratio);
- builder->fsCodeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec);
- builder->fsCodeAppendf("\n\t\t\t%s *= 0.5;", ratio);
+ fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec);
+ fsBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio);
if (fStitchTiles) {
- builder->fsCodeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData);
+ fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData);
}
- builder->fsCodeAppend("\n\t\t}"); // end of the for loop on octaves
+ fsBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves
if (fType == SkPerlinNoiseShader::kFractalNoise_Type) {
// The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
// by fractalNoise and (turbulenceFunctionResult) by turbulence.
- builder->fsCodeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", outputColor, outputColor);
+ fsBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", outputColor, outputColor);
}
- builder->fsCodeAppendf("\n\t\t%s.a *= %s;", outputColor, alphaUni);
+ fsBuilder->codeAppendf("\n\t\t%s.a *= %s;", outputColor, alphaUni);
// Clamp values
- builder->fsCodeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", outputColor, outputColor);
+ fsBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", outputColor, outputColor);
// Pre-multiply the result
- builder->fsCodeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
+ fsBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
outputColor, outputColor, outputColor, outputColor);
}
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 54e1efe550..8b391eebf4 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -278,7 +278,7 @@ bool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const {
#include "GrEffect.h"
#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "SkGr.h"
class GLColorTableEffect;
@@ -316,7 +316,7 @@ class GLColorTableEffect : public GrGLEffect {
public:
GLColorTableEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -337,7 +337,7 @@ GLColorTableEffect::GLColorTableEffect(const GrBackendEffectFactory& factory, co
: INHERITED(factory) {
}
-void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
+void GLColorTableEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -347,38 +347,39 @@ void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
static const float kColorScaleFactor = 255.0f / 256.0f;
static const float kColorOffsetFactor = 1.0f / 512.0f;
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
if (NULL == inputColor) {
// the input color is solid white (all ones).
static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
- builder->fsCodeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
+ fsBuilder->codeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
kMaxValue, kMaxValue, kMaxValue, kMaxValue);
} else {
- builder->fsCodeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", inputColor);
- builder->fsCodeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n", inputColor);
- builder->fsCodeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
+ fsBuilder->codeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", inputColor);
+ fsBuilder->codeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n", inputColor);
+ fsBuilder->codeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
kColorScaleFactor,
kColorOffsetFactor, kColorOffsetFactor,
kColorOffsetFactor, kColorOffsetFactor);
}
- builder->fsCodeAppendf("\t\t%s.a = ", outputColor);
- builder->fsAppendTextureLookup(samplers[0], "vec2(coord.a, 0.125)");
- builder->fsCodeAppend(";\n");
+ fsBuilder->codeAppendf("\t\t%s.a = ", outputColor);
+ fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.a, 0.125)");
+ fsBuilder->codeAppend(";\n");
- builder->fsCodeAppendf("\t\t%s.r = ", outputColor);
- builder->fsAppendTextureLookup(samplers[0], "vec2(coord.r, 0.375)");
- builder->fsCodeAppend(";\n");
+ fsBuilder->codeAppendf("\t\t%s.r = ", outputColor);
+ fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.r, 0.375)");
+ fsBuilder->codeAppend(";\n");
- builder->fsCodeAppendf("\t\t%s.g = ", outputColor);
- builder->fsAppendTextureLookup(samplers[0], "vec2(coord.g, 0.625)");
- builder->fsCodeAppend(";\n");
+ fsBuilder->codeAppendf("\t\t%s.g = ", outputColor);
+ fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.g, 0.625)");
+ fsBuilder->codeAppend(";\n");
- builder->fsCodeAppendf("\t\t%s.b = ", outputColor);
- builder->fsAppendTextureLookup(samplers[0], "vec2(coord.b, 0.875)");
- builder->fsCodeAppend(";\n");
+ fsBuilder->codeAppendf("\t\t%s.b = ", outputColor);
+ fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.b, 0.875)");
+ fsBuilder->codeAppend(";\n");
- builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
+ fsBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index b14a3f7e4f..4f60cfee66 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -927,7 +927,7 @@ SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
#include "effects/GrTextureStripAtlas.h"
#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "SkGr.h"
GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory)
@@ -937,24 +937,24 @@ GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory)
GrGLGradientEffect::~GrGLGradientEffect() { }
-void GrGLGradientEffect::emitUniforms(GrGLShaderBuilder* builder, uint32_t baseKey) {
+void GrGLGradientEffect::emitUniforms(GrGLProgramBuilder* builder, uint32_t baseKey) {
if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(baseKey)) { // 2 Color case
- fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fColorStartUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "GradientStartColor");
- fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fColorEndUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "GradientEndColor");
} else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(baseKey)){ // 3 Color Case
- fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fColorStartUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "GradientStartColor");
- fColorMidUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fColorMidUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "GradientMidColor");
- fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fColorEndUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "GradientEndColor");
} else { // if not a fast case
- fFSYUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fFSYUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "GradientYCoordFS");
}
}
@@ -1037,14 +1037,15 @@ uint32_t GrGLGradientEffect::GenBaseGradientKey(const GrDrawEffect& drawEffect)
return key;
}
-void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
+void GrGLGradientEffect::emitColor(GrGLProgramBuilder* builder,
const char* gradientTValue,
uint32_t baseKey,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) {
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(baseKey)){
- builder->fsCodeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
+ fsBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
builder->getUniformVariable(fColorStartUni).c_str(),
builder->getUniformVariable(fColorEndUni).c_str(),
gradientTValue);
@@ -1054,44 +1055,44 @@ void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
// case. Make sure the key reflects this optimization (and note that it can use the same
// shader as thekBeforeIterp case). This same optimization applies to the 3 color case below.
if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(baseKey)) {
- builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
+ fsBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
}
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
} else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(baseKey)){
- builder->fsCodeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
+ fsBuilder->codeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
gradientTValue);
- builder->fsCodeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n",
+ fsBuilder->codeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n",
builder->getUniformVariable(fColorStartUni).c_str());
if (kTegra3_GrGLRenderer == builder->ctxInfo().renderer()) {
// The Tegra3 compiler will sometimes never return if we have
// min(abs(oneMinus2t), 1.0), or do the abs first in a separate expression.
- builder->fsCodeAppend("\tfloat minAbs = abs(oneMinus2t);\n");
- builder->fsCodeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n");
- builder->fsCodeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n",
+ fsBuilder->codeAppend("\tfloat minAbs = abs(oneMinus2t);\n");
+ fsBuilder->codeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n");
+ fsBuilder->codeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n",
builder->getUniformVariable(fColorMidUni).c_str());
} else {
- builder->fsCodeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n",
+ fsBuilder->codeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n",
builder->getUniformVariable(fColorMidUni).c_str());
}
- builder->fsCodeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n",
+ fsBuilder->codeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n",
builder->getUniformVariable(fColorEndUni).c_str());
if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(baseKey)) {
- builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
+ fsBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
}
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
} else {
- builder->fsCodeAppendf("\tvec2 coord = vec2(%s, %s);\n",
+ fsBuilder->codeAppendf("\tvec2 coord = vec2(%s, %s);\n",
gradientTValue,
builder->getUniformVariable(fFSYUni).c_str());
- builder->fsCodeAppendf("\t%s = ", outputColor);
- builder->fsAppendTextureLookupAndModulate(inputColor,
+ fsBuilder->codeAppendf("\t%s = ", outputColor);
+ fsBuilder->appendTextureLookupAndModulate(inputColor,
samplers[0],
"coord");
- builder->fsCodeAppend(";\n");
+ fsBuilder->codeAppend(";\n");
}
}
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index 7c9d9c319b..8f14bbf6e0 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -413,13 +413,13 @@ protected:
// Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
// should call this method from their emitCode().
- void emitUniforms(GrGLShaderBuilder* builder, uint32_t baseKey);
+ void emitUniforms(GrGLProgramBuilder* builder, uint32_t baseKey);
// emit code that gets a fragment's color from an expression for t; Has branches for 3 separate
// control flows inside -- 2 color gradients, 3 color symmetric gradients (both using
// native GLSL mix), and 4+ color gradients that use the traditional texture lookup.
- void emitColor(GrGLShaderBuilder* builder,
+ void emitColor(GrGLProgramBuilder* builder,
const char* gradientTValue,
uint32_t baseKey,
const char* outputColor,
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 9d939bf4a2..551afaab02 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -460,7 +460,7 @@ void SkLinearGradient::LinearGradientContext::shadeSpan16(int x, int y,
#if SK_SUPPORT_GPU
#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "SkGr.h"
/////////////////////////////////////////////////////////////////////
@@ -473,7 +473,7 @@ public:
virtual ~GrGLLinearGradient() { }
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -550,7 +550,7 @@ GrEffect* GrLinearGradient::TestCreate(SkRandom* random,
/////////////////////////////////////////////////////////////////////
-void GrGLLinearGradient::emitCode(GrGLShaderBuilder* builder,
+void GrGLLinearGradient::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -559,7 +559,7 @@ void GrGLLinearGradient::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
uint32_t baseKey = key.get32(0);
this->emitUniforms(builder, baseKey);
- SkString t = builder->ensureFSCoords2D(coords, 0);
+ SkString t = builder->getFragmentShaderBuilder()->ensureFSCoords2D(coords, 0);
t.append(".x");
this->emitColor(builder, t.c_str(), baseKey, outputColor, inputColor, samplers);
}
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index fb1d40a7ab..aeae24a0af 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -470,7 +470,7 @@ void SkRadialGradient::RadialGradientContext::shadeSpan(int x, int y,
#if SK_SUPPORT_GPU
#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "SkGr.h"
class GrGLRadialGradient : public GrGLGradientEffect {
@@ -480,7 +480,7 @@ public:
const GrDrawEffect&) : INHERITED (factory) { }
virtual ~GrGLRadialGradient() { }
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -559,7 +559,7 @@ GrEffect* GrRadialGradient::TestCreate(SkRandom* random,
/////////////////////////////////////////////////////////////////////
-void GrGLRadialGradient::emitCode(GrGLShaderBuilder* builder,
+void GrGLRadialGradient::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -569,7 +569,7 @@ void GrGLRadialGradient::emitCode(GrGLShaderBuilder* builder,
uint32_t baseKey = key.get32(0);
this->emitUniforms(builder, baseKey);
SkString t("length(");
- t.append(builder->ensureFSCoords2D(coords, 0));
+ t.append(builder->getFragmentShaderBuilder()->ensureFSCoords2D(coords, 0));
t.append(")");
this->emitColor(builder, t.c_str(), baseKey, outputColor, inputColor, samplers);
}
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index 1bb595cb3c..c56cf1494c 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -185,7 +185,7 @@ void SkSweepGradient::SweepGradientContext::shadeSpan16(int x, int y, uint16_t*
#if SK_SUPPORT_GPU
#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "SkGr.h"
class GrGLSweepGradient : public GrGLGradientEffect {
@@ -195,7 +195,7 @@ public:
const GrDrawEffect&) : INHERITED (factory) { }
virtual ~GrGLSweepGradient() { }
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -265,7 +265,7 @@ GrEffect* GrSweepGradient::TestCreate(SkRandom* random,
/////////////////////////////////////////////////////////////////////
-void GrGLSweepGradient::emitCode(GrGLShaderBuilder* builder,
+void GrGLSweepGradient::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -274,7 +274,7 @@ void GrGLSweepGradient::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
uint32_t baseKey = key.get32(0);
this->emitUniforms(builder, baseKey);
- SkString coords2D = builder->ensureFSCoords2D(coords, 0);
+ SkString coords2D = builder->getFragmentShaderBuilder()->ensureFSCoords2D(coords, 0);
const GrGLContextInfo ctxInfo = builder->ctxInfo();
SkString t;
// 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi]
diff --git a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
index 4298207ed7..a3ba479cb7 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
@@ -12,7 +12,7 @@
#if SK_SUPPORT_GPU
#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
// For brevity
typedef GrGLProgramDataManager::UniformHandle UniformHandle;
@@ -137,7 +137,7 @@ public:
GLEdge2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&);
virtual ~GLEdge2PtConicalEffect() { }
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -217,7 +217,7 @@ GLEdge2PtConicalEffect::GLEdge2PtConicalEffect(const GrBackendEffectFactory& fac
, fCachedRadius(-SK_ScalarMax)
, fCachedDiffRadius(-SK_ScalarMax) {}
-void GLEdge2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
+void GLEdge2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -226,7 +226,7 @@ void GLEdge2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
uint32_t baseKey = key.get32(0);
this->emitUniforms(builder, baseKey);
- fParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+ fParamUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "Conical2FSParams", 3);
SkString cName("c");
@@ -243,8 +243,9 @@ void GLEdge2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
SkASSERT(coords[0].type() == coords[1].type());
const char* coords2D;
SkString bVar;
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
if (kVec3f_GrSLType == coords[0].type()) {
- builder->fsCodeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n",
+ fsBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n",
coords[0].c_str(), coords[0].c_str(), coords[1].c_str(), coords[1].c_str());
coords2D = "interpolants.xy";
bVar = "interpolants.z";
@@ -255,22 +256,22 @@ void GLEdge2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
// output will default to transparent black (we simply won't write anything
// else to it if invalid, instead of discarding or returning prematurely)
- builder->fsCodeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
+ fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
// c = (x^2)+(y^2) - params[1]
- builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
+ fsBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
cName.c_str(), coords2D, coords2D, p1.c_str());
// linear case: t = -c/b
- builder->fsCodeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(),
+ fsBuilder->codeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(),
cName.c_str(), bVar.c_str());
// if r(t) > 0, then t will be the x coordinate
- builder->fsCodeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
+ fsBuilder->codeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
p2.c_str(), p0.c_str());
- builder->fsCodeAppend("\t");
+ fsBuilder->codeAppend("\t");
this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
- builder->fsCodeAppend("\t}\n");
+ fsBuilder->codeAppend("\t}\n");
}
void GLEdge2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
@@ -413,7 +414,7 @@ public:
GLFocalOutside2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&);
virtual ~GLFocalOutside2PtConicalEffect() { }
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -493,7 +494,7 @@ GLFocalOutside2PtConicalEffect::GLFocalOutside2PtConicalEffect(const GrBackendEf
fIsFlipped = data.isFlipped();
}
-void GLFocalOutside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
+void GLFocalOutside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -502,7 +503,7 @@ void GLFocalOutside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
uint32_t baseKey = key.get32(0);
this->emitUniforms(builder, baseKey);
- fParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+ fParamUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "Conical2FSParams", 2);
SkString tName("t");
SkString p0; // focalX
@@ -512,33 +513,34 @@ void GLFocalOutside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
builder->getUniformVariable(fParamUni).appendArrayAccess(1, &p1);
// if we have a vec3 from being in perspective, convert it to a vec2 first
- SkString coords2DString = builder->ensureFSCoords2D(coords, 0);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
const char* coords2D = coords2DString.c_str();
// t = p.x * focal.x +/- sqrt(p.x^2 + (1 - focal.x^2) * p.y^2)
// output will default to transparent black (we simply won't write anything
// else to it if invalid, instead of discarding or returning prematurely)
- builder->fsCodeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
+ fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
- builder->fsCodeAppendf("\tfloat xs = %s.x * %s.x;\n", coords2D, coords2D);
- builder->fsCodeAppendf("\tfloat ys = %s.y * %s.y;\n", coords2D, coords2D);
- builder->fsCodeAppendf("\tfloat d = xs + %s * ys;\n", p1.c_str());
+ fsBuilder->codeAppendf("\tfloat xs = %s.x * %s.x;\n", coords2D, coords2D);
+ fsBuilder->codeAppendf("\tfloat ys = %s.y * %s.y;\n", coords2D, coords2D);
+ fsBuilder->codeAppendf("\tfloat d = xs + %s * ys;\n", p1.c_str());
// Must check to see if we flipped the circle order (to make sure start radius < end radius)
// If so we must also flip sign on sqrt
if (!fIsFlipped) {
- builder->fsCodeAppendf("\tfloat %s = %s.x * %s + sqrt(d);\n", tName.c_str(),
+ fsBuilder->codeAppendf("\tfloat %s = %s.x * %s + sqrt(d);\n", tName.c_str(),
coords2D, p0.c_str());
} else {
- builder->fsCodeAppendf("\tfloat %s = %s.x * %s - sqrt(d);\n", tName.c_str(),
+ fsBuilder->codeAppendf("\tfloat %s = %s.x * %s - sqrt(d);\n", tName.c_str(),
coords2D, p0.c_str());
}
- builder->fsCodeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str());
- builder->fsCodeAppend("\t\t");
+ fsBuilder->codeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str());
+ fsBuilder->codeAppend("\t\t");
this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
- builder->fsCodeAppend("\t}\n");
+ fsBuilder->codeAppend("\t}\n");
}
void GLFocalOutside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
@@ -618,7 +620,7 @@ public:
GLFocalInside2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&);
virtual ~GLFocalInside2PtConicalEffect() {}
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -695,7 +697,7 @@ GLFocalInside2PtConicalEffect::GLFocalInside2PtConicalEffect(const GrBackendEffe
, fFSVaryingName(NULL)
, fCachedFocal(SK_ScalarMax) {}
-void GLFocalInside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
+void GLFocalInside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -704,7 +706,7 @@ void GLFocalInside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
uint32_t baseKey = key.get32(0);
this->emitUniforms(builder, baseKey);
- fFocalUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fFocalUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "Conical2FSParams");
SkString tName("t");
@@ -713,11 +715,12 @@ void GLFocalInside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
GrGLShaderVar focal = builder->getUniformVariable(fFocalUni);
// if we have a vec3 from being in perspective, convert it to a vec2 first
- SkString coords2DString = builder->ensureFSCoords2D(coords, 0);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
const char* coords2D = coords2DString.c_str();
// t = p.x * focalX + length(p)
- builder->fsCodeAppendf("\tfloat %s = %s.x * %s + length(%s);\n", tName.c_str(),
+ fsBuilder->codeAppendf("\tfloat %s = %s.x * %s + length(%s);\n", tName.c_str(),
coords2D, focal.c_str(), coords2D);
this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
@@ -859,7 +862,7 @@ public:
GLCircleInside2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&);
virtual ~GLCircleInside2PtConicalEffect() {}
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -944,7 +947,7 @@ GLCircleInside2PtConicalEffect::GLCircleInside2PtConicalEffect(const GrBackendEf
, fCachedB(SK_ScalarMax)
, fCachedC(SK_ScalarMax) {}
-void GLCircleInside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
+void GLCircleInside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -953,9 +956,9 @@ void GLCircleInside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
uint32_t baseKey = key.get32(0);
this->emitUniforms(builder, baseKey);
- fCenterUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fCenterUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "Conical2FSCenter");
- fParamUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fParamUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec3f_GrSLType, "Conical2FSParams");
SkString tName("t");
@@ -966,7 +969,8 @@ void GLCircleInside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
GrGLShaderVar params = builder->getUniformVariable(fParamUni);
// if we have a vec3 from being in perspective, convert it to a vec2 first
- SkString coords2DString = builder->ensureFSCoords2D(coords, 0);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
const char* coords2D = coords2DString.c_str();
// p = coords2D
@@ -977,9 +981,9 @@ void GLCircleInside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
// C = 1 / A
// d = dot(e, p) + B
// t = d +/- sqrt(d^2 - A * dot(p, p) + C)
- builder->fsCodeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D);
- builder->fsCodeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(), params.c_str());
- builder->fsCodeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n",
+ fsBuilder->codeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D);
+ fsBuilder->codeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(), params.c_str());
+ fsBuilder->codeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n",
tName.c_str(), params.c_str(), params.c_str());
this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
@@ -1085,7 +1089,7 @@ public:
GLCircleOutside2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&);
virtual ~GLCircleOutside2PtConicalEffect() {}
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -1178,7 +1182,7 @@ GLCircleOutside2PtConicalEffect::GLCircleOutside2PtConicalEffect(const GrBackend
fIsFlipped = data.isFlipped();
}
-void GLCircleOutside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
+void GLCircleOutside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -1187,9 +1191,9 @@ void GLCircleOutside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
uint32_t baseKey = key.get32(0);
this->emitUniforms(builder, baseKey);
- fCenterUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fCenterUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "Conical2FSCenter");
- fParamUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fParamUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "Conical2FSParams");
SkString tName("t");
@@ -1200,12 +1204,13 @@ void GLCircleOutside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
GrGLShaderVar params = builder->getUniformVariable(fParamUni);
// if we have a vec3 from being in perspective, convert it to a vec2 first
- SkString coords2DString = builder->ensureFSCoords2D(coords, 0);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
const char* coords2D = coords2DString.c_str();
// output will default to transparent black (we simply won't write anything
// else to it if invalid, instead of discarding or returning prematurely)
- builder->fsCodeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
+ fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
// p = coords2D
// e = center end
@@ -1216,22 +1221,22 @@ void GLCircleOutside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
// d = dot(e, p) + B
// t = d +/- sqrt(d^2 - A * dot(p, p) + C)
- builder->fsCodeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D);
- builder->fsCodeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(), params.c_str());
- builder->fsCodeAppendf("\tfloat deter = d * d - %s.x * pDotp + %s.z;\n", params.c_str(), params.c_str());
+ fsBuilder->codeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D);
+ fsBuilder->codeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(), params.c_str());
+ fsBuilder->codeAppendf("\tfloat deter = d * d - %s.x * pDotp + %s.z;\n", params.c_str(), params.c_str());
// Must check to see if we flipped the circle order (to make sure start radius < end radius)
// If so we must also flip sign on sqrt
if (!fIsFlipped) {
- builder->fsCodeAppendf("\tfloat %s = d + sqrt(deter);\n", tName.c_str());
+ fsBuilder->codeAppendf("\tfloat %s = d + sqrt(deter);\n", tName.c_str());
} else {
- builder->fsCodeAppendf("\tfloat %s = d - sqrt(deter);\n", tName.c_str());
+ fsBuilder->codeAppendf("\tfloat %s = d - sqrt(deter);\n", tName.c_str());
}
- builder->fsCodeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n", tName.c_str(), params.c_str());
- builder->fsCodeAppend("\t\t");
+ fsBuilder->codeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n", tName.c_str(), params.c_str());
+ fsBuilder->codeAppend("\t\t");
this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
- builder->fsCodeAppend("\t}\n");
+ fsBuilder->codeAppend("\t}\n");
}
void GLCircleOutside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp
index 754a53261b..bb5ec04bfd 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -398,7 +398,7 @@ void SkTwoPointRadialGradient::init() {
#if SK_SUPPORT_GPU
#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "SkGr.h"
// For brevity
@@ -411,7 +411,7 @@ public:
GrGLRadial2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffect&);
virtual ~GrGLRadial2Gradient() { }
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -567,7 +567,7 @@ GrGLRadial2Gradient::GrGLRadial2Gradient(const GrBackendEffectFactory& factory,
fIsDegenerate = data.isDegenerate();
}
-void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder,
+void GrGLRadial2Gradient::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -576,7 +576,7 @@ void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
uint32_t baseKey = key.get32(0);
this->emitUniforms(builder, baseKey);
- fParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+ fParamUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "Radial2FSParams", 6);
SkString cName("c");
@@ -596,12 +596,13 @@ void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder,
builder->getUniformVariable(fParamUni).appendArrayAccess(4, &p4);
builder->getUniformVariable(fParamUni).appendArrayAccess(5, &p5);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
// We interpolate the linear component in coords[1].
SkASSERT(coords[0].type() == coords[1].type());
const char* coords2D;
SkString bVar;
if (kVec3f_GrSLType == coords[0].type()) {
- builder->fsCodeAppendf("\tvec3 interpolants = vec3(%s.xy, %s.x) / %s.z;\n",
+ fsBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy, %s.x) / %s.z;\n",
coords[0].c_str(), coords[1].c_str(), coords[0].c_str());
coords2D = "interpolants.xy";
bVar = "interpolants.z";
@@ -611,7 +612,7 @@ void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder,
}
// c = (x^2)+(y^2) - params[4]
- builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
+ fsBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
cName.c_str(), coords2D, coords2D, p4.c_str());
// If we aren't degenerate, emit some extra code, and accept a slightly
@@ -619,13 +620,13 @@ void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder,
if (!fIsDegenerate) {
// ac4 = 4.0 * params[0] * c
- builder->fsCodeAppendf("\tfloat %s = %s * 4.0 * %s;\n",
+ fsBuilder->codeAppendf("\tfloat %s = %s * 4.0 * %s;\n",
ac4Name.c_str(), p0.c_str(),
cName.c_str());
// root = sqrt(b^2-4ac)
// (abs to avoid exception due to fp precision)
- builder->fsCodeAppendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
+ fsBuilder->codeAppendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
rootName.c_str(), bVar.c_str(), bVar.c_str(),
ac4Name.c_str());
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index b2c32acd95..b29c7c80a3 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -6,6 +6,7 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrAAConvexPathRenderer.h"
#include "GrContext.h"
@@ -19,7 +20,6 @@
#include "SkTraceEvent.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLVertexEffect.h"
@@ -531,7 +531,7 @@ public:
GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
: INHERITED (factory) {}
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -539,35 +539,38 @@ public:
const TransformedCoordsArray&,
const TextureSamplerArray& samplers) SK_OVERRIDE {
const char *vsName, *fsName;
- const SkString* attrName =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
- builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n");
-
- SkAssertResult(builder->enableFeature(
- GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
builder->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+
+ SkAssertResult(fsBuilder->enableFeature(
+ GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+ fsBuilder->codeAppendf("\t\tfloat edgeAlpha;\n");
+
// keep the derivative instructions outside the conditional
- builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
- builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
- builder->fsCodeAppendf("\t\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName);
+ fsBuilder->codeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
+ fsBuilder->codeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
+ fsBuilder->codeAppendf("\t\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName);
// today we know z and w are in device space. We could use derivatives
- builder->fsCodeAppendf("\t\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName,
+ fsBuilder->codeAppendf("\t\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName,
fsName);
- builder->fsCodeAppendf ("\t\t} else {\n");
- builder->fsCodeAppendf("\t\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
+ fsBuilder->codeAppendf ("\t\t} else {\n");
+ fsBuilder->codeAppendf("\t\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
"\t\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n",
fsName, fsName);
- builder->fsCodeAppendf("\t\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
+ fsBuilder->codeAppendf("\t\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
fsName);
- builder->fsCodeAppendf("\t\t\tedgeAlpha = "
+ fsBuilder->codeAppendf("\t\t\tedgeAlpha = "
"clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n\t\t}\n");
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
- builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+ const SkString* attr0Name =
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
}
static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*) {}
@@ -589,7 +592,7 @@ private:
GR_DECLARE_EFFECT_TEST;
- typedef GrVertexEffect INHERITED;
+ typedef GrEffect INHERITED;
};
GR_DEFINE_EFFECT_TEST(QuadEdgeEffect);
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index 1d350c335b..b4790bb99d 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -5,10 +5,10 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrAARectRenderer.h"
#include "GrGpu.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLVertexEffect.h"
#include "GrTBackendEffectFactory.h"
#include "SkColorPriv.h"
@@ -44,7 +44,7 @@ public:
GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
: INHERITED (factory) {}
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -56,35 +56,38 @@ public:
// zw -> w/2+0.5, h/2+0.5
const char *vsRectName, *fsRectName;
builder->addVarying(kVec4f_GrSLType, "Rect", &vsRectName, &fsRectName);
+
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
const SkString* attr0Name =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsRectName, attr0Name->c_str());
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsRectName, attr0Name->c_str());
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
// TODO: compute all these offsets, spans, and scales in the VS
- builder->fsCodeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", fsRectName);
- builder->fsCodeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", fsRectName);
- builder->fsCodeAppend("\tfloat outset = 0.5;\n");
+ fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", fsRectName);
+ fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", fsRectName);
+ fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
// For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
// < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
- builder->fsCodeAppend("\tfloat spanW = insetW + outset;\n");
- builder->fsCodeAppend("\tfloat spanH = insetH + outset;\n");
+ fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
+ fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
// For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
// value of coverage that is used. In other words it is the coverage that is
// used in the interior of the rect after the ramp.
- builder->fsCodeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
- builder->fsCodeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
+ fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
+ fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
// Compute the coverage for the rect's width
- builder->fsCodeAppendf(
+ fsBuilder->codeAppendf(
"\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.0);\n", fsRectName,
fsRectName);
// Compute the coverage for the rect's height and merge with the width
- builder->fsCodeAppendf(
+ fsBuilder->codeAppendf(
"\tcoverage = coverage*scaleH*clamp((%s.w-abs(%s.y))/spanH, 0.0, 1.0);\n",
fsRectName, fsRectName);
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("coverage")).c_str());
}
@@ -160,7 +163,7 @@ public:
GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
: INHERITED (factory) {}
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -172,50 +175,53 @@ public:
const char *vsRectEdgeName, *fsRectEdgeName;
builder->addVarying(kVec4f_GrSLType, "RectEdge",
&vsRectEdgeName, &fsRectEdgeName);
+
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
const SkString* attr0Name =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsRectEdgeName, attr0Name->c_str());
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsRectEdgeName, attr0Name->c_str());
// setup the varying for width/2+.5 and height/2+.5
const char *vsWidthHeightName, *fsWidthHeightName;
builder->addVarying(kVec2f_GrSLType, "WidthHeight",
&vsWidthHeightName, &fsWidthHeightName);
const SkString* attr1Name =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsWidthHeightName, attr1Name->c_str());
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsWidthHeightName, attr1Name->c_str());
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
// TODO: compute all these offsets, spans, and scales in the VS
- builder->fsCodeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", fsWidthHeightName);
- builder->fsCodeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", fsWidthHeightName);
- builder->fsCodeAppend("\tfloat outset = 0.5;\n");
+ fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", fsWidthHeightName);
+ fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", fsWidthHeightName);
+ fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
// For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
// < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
- builder->fsCodeAppend("\tfloat spanW = insetW + outset;\n");
- builder->fsCodeAppend("\tfloat spanH = insetH + outset;\n");
+ fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
+ fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
// For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
// value of coverage that is used. In other words it is the coverage that is
// used in the interior of the rect after the ramp.
- builder->fsCodeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
- builder->fsCodeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
+ fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
+ fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
// Compute the coverage for the rect's width
- builder->fsCodeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
- builder->fragmentPosition(), fsRectEdgeName);
- builder->fsCodeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n",
+ fsBuilder->codeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
+ fsBuilder->fragmentPosition(), fsRectEdgeName);
+ fsBuilder->codeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n",
fsRectEdgeName, fsRectEdgeName);
- builder->fsCodeAppendf(
+ fsBuilder->codeAppendf(
"\tfloat coverage = scaleW*clamp((%s.x-perpDot)/spanW, 0.0, 1.0);\n",
fsWidthHeightName);
// Compute the coverage for the rect's height and merge with the width
- builder->fsCodeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n",
+ fsBuilder->codeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n",
fsRectEdgeName);
- builder->fsCodeAppendf(
+ fsBuilder->codeAppendf(
"\tcoverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.0, 1.0);\n",
fsWidthHeightName);
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("coverage")).c_str());
}
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index 395c90be05..dcce889559 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -5,12 +5,12 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrOvalRenderer.h"
#include "GrEffect.h"
#include "gl/GrGLEffect.h"
#include "gl/GrGLSL.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLVertexEffect.h"
#include "GrTBackendEffectFactory.h"
@@ -95,7 +95,7 @@ public:
GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
: INHERITED (factory) {}
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -106,18 +106,20 @@ public:
const char *vsName, *fsName;
builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName);
- const SkString* attrName =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+ const SkString* attr0Name =
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
- builder->fsCodeAppendf("\tfloat d = length(%s.xy);\n", fsName);
- builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("\tfloat d = length(%s.xy);\n", fsName);
+ fsBuilder->codeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName);
if (circleEffect.isStroked()) {
- builder->fsCodeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0, 1.0);\n", fsName);
- builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n");
+ fsBuilder->codeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0, 1.0);\n", fsName);
+ fsBuilder->codeAppend("\tedgeAlpha *= innerAlpha;\n");
}
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
}
@@ -206,7 +208,7 @@ public:
GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
: INHERITED (factory) {}
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -219,35 +221,38 @@ public:
const char *vsRadiiName, *fsRadiiName;
builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName, &fsOffsetName);
+
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
const SkString* attr0Name =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name->c_str());
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name->c_str());
builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, &fsRadiiName);
const SkString* attr1Name =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsRadiiName, attr1Name->c_str());
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsRadiiName, attr1Name->c_str());
// for outer curve
- builder->fsCodeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffsetName, fsRadiiName);
- builder->fsCodeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
- builder->fsCodeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fsRadiiName);
- builder->fsCodeAppend("\tfloat grad_dot = dot(grad, grad);\n");
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffsetName, fsRadiiName);
+ fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
+ fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fsRadiiName);
+ fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n");
// avoid calling inversesqrt on zero.
- builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
- builder->fsCodeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
- builder->fsCodeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
+ fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
+ fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
// for inner curve
if (ellipseEffect.isStroked()) {
- builder->fsCodeAppendf("\tscaledOffset = %s*%s.zw;\n", fsOffsetName, fsRadiiName);
- builder->fsCodeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
- builder->fsCodeAppendf("\tgrad = 2.0*scaledOffset*%s.zw;\n", fsRadiiName);
- builder->fsCodeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
- builder->fsCodeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
+ fsBuilder->codeAppendf("\tscaledOffset = %s*%s.zw;\n", fsOffsetName, fsRadiiName);
+ fsBuilder->codeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
+ fsBuilder->codeAppendf("\tgrad = 2.0*scaledOffset*%s.zw;\n", fsRadiiName);
+ fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
+ fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
}
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
}
@@ -344,7 +349,7 @@ public:
GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
: INHERITED (factory) {}
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -353,57 +358,59 @@ public:
const TextureSamplerArray& samplers) SK_OVERRIDE {
const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIEllipseEdgeEffect>();
- SkAssertResult(builder->enableFeature(
- GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
-
const char *vsOffsetName0, *fsOffsetName0;
builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0",
&vsOffsetName0, &fsOffsetName0);
+
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
const SkString* attr0Name =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName0, attr0Name->c_str());
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName0, attr0Name->c_str());
const char *vsOffsetName1, *fsOffsetName1;
builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1",
&vsOffsetName1, &fsOffsetName1);
const SkString* attr1Name =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName1, attr1Name->c_str());
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1, attr1Name->c_str());
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkAssertResult(fsBuilder->enableFeature(
+ GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
// for outer curve
- builder->fsCodeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetName0);
- builder->fsCodeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
- builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0);
- builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0);
- builder->fsCodeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
+ fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetName0);
+ fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
+ fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0);
+ fsBuilder->codeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0);
+ fsBuilder->codeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
"\t 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);\n",
fsOffsetName0, fsOffsetName0, fsOffsetName0, fsOffsetName0);
- builder->fsCodeAppend("\tfloat grad_dot = dot(grad, grad);\n");
+ fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n");
// avoid calling inversesqrt on zero.
- builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
- builder->fsCodeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
+ fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
+ fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
if (kHairline == ellipseEffect.getMode()) {
// can probably do this with one step
- builder->fsCodeAppend("\tfloat edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);\n");
- builder->fsCodeAppend("\tedgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\tedgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);\n");
} else {
- builder->fsCodeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
}
// for inner curve
if (kStroke == ellipseEffect.getMode()) {
- builder->fsCodeAppendf("\tscaledOffset = %s.xy;\n", fsOffsetName1);
- builder->fsCodeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
- builder->fsCodeAppendf("\tduvdx = dFdx(%s);\n", fsOffsetName1);
- builder->fsCodeAppendf("\tduvdy = dFdy(%s);\n", fsOffsetName1);
- builder->fsCodeAppendf("\tgrad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
+ fsBuilder->codeAppendf("\tscaledOffset = %s.xy;\n", fsOffsetName1);
+ fsBuilder->codeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
+ fsBuilder->codeAppendf("\tduvdx = dFdx(%s);\n", fsOffsetName1);
+ fsBuilder->codeAppendf("\tduvdy = dFdy(%s);\n", fsOffsetName1);
+ fsBuilder->codeAppendf("\tgrad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
"\t 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);\n",
fsOffsetName1, fsOffsetName1, fsOffsetName1, fsOffsetName1);
- builder->fsCodeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
- builder->fsCodeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
+ fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
}
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
}
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index 6f3772d798..7384f62856 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -5,10 +5,10 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrBezierEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLVertexEffect.h"
#include "GrTBackendEffectFactory.h"
@@ -17,7 +17,7 @@ class GrGLConicEffect : public GrGLVertexEffect {
public:
GrGLConicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -42,7 +42,7 @@ GrGLConicEffect::GrGLConicEffect(const GrBackendEffectFactory& factory,
fEdgeType = ce.getEdgeType();
}
-void GrGLConicEffect::emitCode(GrGLFullShaderBuilder* builder,
+void GrGLConicEffect::emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -53,67 +53,70 @@ void GrGLConicEffect::emitCode(GrGLFullShaderBuilder* builder,
builder->addVarying(kVec4f_GrSLType, "ConicCoeffs",
&vsName, &fsName);
+
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
const SkString* attr0Name =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
- builder->fsCodeAppend("\t\tfloat edgeAlpha;\n");
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppend("\t\tfloat edgeAlpha;\n");
switch (fEdgeType) {
case kHairlineAA_GrEffectEdgeType: {
- SkAssertResult(builder->enableFeature(
- GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
- builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
- builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
- builder->fsCodeAppendf("\t\tfloat dfdx =\n"
+ SkAssertResult(fsBuilder->enableFeature(
+ GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+ fsBuilder->codeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
+ fsBuilder->codeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
+ fsBuilder->codeAppendf("\t\tfloat dfdx =\n"
"\t\t\t2.0*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
fsName, fsName, fsName);
- builder->fsCodeAppendf("\t\tfloat dfdy =\n"
+ fsBuilder->codeAppendf("\t\tfloat dfdy =\n"
"\t\t\t2.0*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
fsName, fsName, fsName);
- builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
- builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
- builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
+ fsBuilder->codeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
+ fsBuilder->codeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
+ fsBuilder->codeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
fsName, fsName);
- builder->fsCodeAppend("\t\tfunc = abs(func);\n");
- builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
- builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
+ fsBuilder->codeAppend("\t\tfunc = abs(func);\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = func / gFM;\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
// Add line below for smooth cubic ramp
- // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+ // fsBuilder->codeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
break;
}
case kFillAA_GrEffectEdgeType: {
- SkAssertResult(builder->enableFeature(
- GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
- builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
- builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
- builder->fsCodeAppendf("\t\tfloat dfdx =\n"
+ SkAssertResult(fsBuilder->enableFeature(
+ GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+ fsBuilder->codeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
+ fsBuilder->codeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
+ fsBuilder->codeAppendf("\t\tfloat dfdx =\n"
"\t\t\t2.0*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
fsName, fsName, fsName);
- builder->fsCodeAppendf("\t\tfloat dfdy =\n"
+ fsBuilder->codeAppendf("\t\tfloat dfdy =\n"
"\t\t\t2.0*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
fsName, fsName, fsName);
- builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
- builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
- builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
+ fsBuilder->codeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
+ fsBuilder->codeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
+ fsBuilder->codeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
fsName, fsName);
- builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
- builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = func / gFM;\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
// Add line below for smooth cubic ramp
- // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+ // fsBuilder->codeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
break;
}
case kFillBW_GrEffectEdgeType: {
- builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
+ fsBuilder->codeAppendf("\t\tedgeAlpha = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
fsName, fsName);
- builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
break;
}
default:
SkFAIL("Shouldn't get here");
}
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
}
@@ -167,7 +170,7 @@ class GrGLQuadEffect : public GrGLVertexEffect {
public:
GrGLQuadEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -192,7 +195,7 @@ GrGLQuadEffect::GrGLQuadEffect(const GrBackendEffectFactory& factory,
fEdgeType = ce.getEdgeType();
}
-void GrGLQuadEffect::emitCode(GrGLFullShaderBuilder* builder,
+void GrGLQuadEffect::emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -200,61 +203,61 @@ void GrGLQuadEffect::emitCode(GrGLFullShaderBuilder* builder,
const TransformedCoordsArray&,
const TextureSamplerArray& samplers) {
const char *vsName, *fsName;
+ builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName);
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
const SkString* attrName =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
- builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n");
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
- builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("\t\tfloat edgeAlpha;\n");
switch (fEdgeType) {
case kHairlineAA_GrEffectEdgeType: {
- SkAssertResult(builder->enableFeature(
- GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
- builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
- builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
- builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
+ SkAssertResult(fsBuilder->enableFeature(
+ GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+ fsBuilder->codeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
+ fsBuilder->codeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
+ fsBuilder->codeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
"\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n",
fsName, fsName);
- builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
+ fsBuilder->codeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
fsName);
- builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n");
- builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
// Add line below for smooth cubic ramp
- // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+ // fsBuilder->codeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
break;
}
case kFillAA_GrEffectEdgeType: {
- SkAssertResult(builder->enableFeature(
- GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
- builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
- builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
- builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
+ SkAssertResult(fsBuilder->enableFeature(
+ GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+ fsBuilder->codeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
+ fsBuilder->codeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
+ fsBuilder->codeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
"\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n",
fsName, fsName);
- builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
+ fsBuilder->codeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
fsName);
- builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha / sqrt(dot(gF, gF));\n");
- builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = edgeAlpha / sqrt(dot(gF, gF));\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
// Add line below for smooth cubic ramp
- // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+ // fsBuilder->codeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
break;
}
case kFillBW_GrEffectEdgeType: {
- builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
+ fsBuilder->codeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
fsName);
- builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
break;
}
default:
SkFAIL("Shouldn't get here");
}
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
-
-
- builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
}
void GrGLQuadEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
@@ -307,7 +310,7 @@ class GrGLCubicEffect : public GrGLVertexEffect {
public:
GrGLCubicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -332,7 +335,7 @@ GrGLCubicEffect::GrGLCubicEffect(const GrBackendEffectFactory& factory,
fEdgeType = ce.getEdgeType();
}
-void GrGLCubicEffect::emitCode(GrGLFullShaderBuilder* builder,
+void GrGLCubicEffect::emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -343,67 +346,70 @@ void GrGLCubicEffect::emitCode(GrGLFullShaderBuilder* builder,
builder->addVarying(kVec4f_GrSLType, "CubicCoeffs",
&vsName, &fsName);
+
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
const SkString* attr0Name =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
- builder->fsCodeAppend("\t\tfloat edgeAlpha;\n");
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppend("\t\tfloat edgeAlpha;\n");
switch (fEdgeType) {
case kHairlineAA_GrEffectEdgeType: {
- SkAssertResult(builder->enableFeature(
- GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
- builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
- builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
- builder->fsCodeAppendf("\t\tfloat dfdx =\n"
+ SkAssertResult(fsBuilder->enableFeature(
+ GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+ fsBuilder->codeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
+ fsBuilder->codeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
+ fsBuilder->codeAppendf("\t\tfloat dfdx =\n"
"\t\t3.0*%s.x*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
fsName, fsName, fsName, fsName);
- builder->fsCodeAppendf("\t\tfloat dfdy =\n"
+ fsBuilder->codeAppendf("\t\tfloat dfdy =\n"
"\t\t3.0*%s.x*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
fsName, fsName, fsName, fsName);
- builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
- builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
- builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
+ fsBuilder->codeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
+ fsBuilder->codeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
+ fsBuilder->codeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
fsName, fsName, fsName, fsName, fsName);
- builder->fsCodeAppend("\t\tfunc = abs(func);\n");
- builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
- builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
+ fsBuilder->codeAppend("\t\tfunc = abs(func);\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = func / gFM;\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
// Add line below for smooth cubic ramp
- // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+ // fsBuilder->codeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
break;
}
case kFillAA_GrEffectEdgeType: {
- SkAssertResult(builder->enableFeature(
- GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
- builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
- builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
- builder->fsCodeAppendf("\t\tfloat dfdx =\n"
+ SkAssertResult(fsBuilder->enableFeature(
+ GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+ fsBuilder->codeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
+ fsBuilder->codeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
+ fsBuilder->codeAppendf("\t\tfloat dfdx =\n"
"\t\t3.0*%s.x*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
fsName, fsName, fsName, fsName);
- builder->fsCodeAppendf("\t\tfloat dfdy =\n"
+ fsBuilder->codeAppendf("\t\tfloat dfdy =\n"
"\t\t3.0*%s.x*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
fsName, fsName, fsName, fsName);
- builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
- builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
- builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
+ fsBuilder->codeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
+ fsBuilder->codeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
+ fsBuilder->codeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
fsName, fsName, fsName, fsName, fsName);
- builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
- builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = func / gFM;\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
// Add line below for smooth cubic ramp
- // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+ // fsBuilder->codeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
break;
}
case kFillBW_GrEffectEdgeType: {
- builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
+ fsBuilder->codeAppendf("\t\tedgeAlpha = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
fsName, fsName, fsName, fsName, fsName);
- builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
+ fsBuilder->codeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
break;
}
default:
SkFAIL("Shouldn't get here");
}
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
}
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp
index fb98b4ac4c..27d482ae2e 100644
--- a/src/gpu/effects/GrBicubicEffect.cpp
+++ b/src/gpu/effects/GrBicubicEffect.cpp
@@ -5,9 +5,9 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrBicubicEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#define DS(x) SkDoubleToScalar(x)
@@ -24,7 +24,7 @@ public:
GrGLBicubicEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -54,7 +54,7 @@ GrGLBicubicEffect::GrGLBicubicEffect(const GrBackendEffectFactory& factory, cons
: INHERITED(factory) {
}
-void GrGLBicubicEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLBicubicEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -63,10 +63,9 @@ void GrGLBicubicEffect::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
const GrTextureDomain& domain = drawEffect.castEffect<GrBicubicEffect>().domain();
- SkString coords2D = builder->ensureFSCoords2D(coords, 0);
- fCoefficientsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fCoefficientsUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kMat44f_GrSLType, "Coefficients");
- fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "ImageIncrement");
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
@@ -82,7 +81,9 @@ void GrGLBicubicEffect::emitCode(GrGLShaderBuilder* builder,
GrGLShaderVar("c2", kVec4f_GrSLType),
GrGLShaderVar("c3", kVec4f_GrSLType),
};
- builder->fsEmitFunction(kVec4f_GrSLType,
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+ fsBuilder->emitFunction(kVec4f_GrSLType,
"cubicBlend",
SK_ARRAY_COUNT(gCubicBlendArgs),
gCubicBlendArgs,
@@ -90,28 +91,28 @@ void GrGLBicubicEffect::emitCode(GrGLShaderBuilder* builder,
"\tvec4 c = coefficients * ts;\n"
"\treturn c.x * c0 + c.y * c1 + c.z * c2 + c.w * c3;\n",
&cubicBlendName);
- builder->fsCodeAppendf("\tvec2 coord = %s - %s * vec2(0.5);\n", coords2D.c_str(), imgInc);
+ fsBuilder->codeAppendf("\tvec2 coord = %s - %s * vec2(0.5);\n", coords2D.c_str(), imgInc);
// We unnormalize the coord in order to determine our fractional offset (f) within the texel
// We then snap coord to a texel center and renormalize. The snap prevents cases where the
// starting coords are near a texel boundary and accumulations of imgInc would cause us to skip/
// double hit a texel.
- builder->fsCodeAppendf("\tcoord /= %s;\n", imgInc);
- builder->fsCodeAppend("\tvec2 f = fract(coord);\n");
- builder->fsCodeAppendf("\tcoord = (coord - f + vec2(0.5)) * %s;\n", imgInc);
- builder->fsCodeAppend("\tvec4 rowColors[4];\n");
+ fsBuilder->codeAppendf("\tcoord /= %s;\n", imgInc);
+ fsBuilder->codeAppend("\tvec2 f = fract(coord);\n");
+ fsBuilder->codeAppendf("\tcoord = (coord - f + vec2(0.5)) * %s;\n", imgInc);
+ fsBuilder->codeAppend("\tvec4 rowColors[4];\n");
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
SkString coord;
coord.printf("coord + %s * vec2(%d, %d)", imgInc, x - 1, y - 1);
SkString sampleVar;
sampleVar.printf("rowColors[%d]", x);
- fDomain.sampleTexture(builder, domain, sampleVar.c_str(), coord, samplers[0]);
+ fDomain.sampleTexture(fsBuilder, domain, sampleVar.c_str(), coord, samplers[0]);
}
- builder->fsCodeAppendf("\tvec4 s%d = %s(%s, f.x, rowColors[0], rowColors[1], rowColors[2], rowColors[3]);\n", y, cubicBlendName.c_str(), coeff);
+ fsBuilder->codeAppendf("\tvec4 s%d = %s(%s, f.x, rowColors[0], rowColors[1], rowColors[2], rowColors[3]);\n", y, cubicBlendName.c_str(), coeff);
}
SkString bicubicColor;
bicubicColor.printf("%s(%s, f.y, s0, s1, s2, s3)", cubicBlendName.c_str(), coeff);
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor, (GrGLSLExpr4(bicubicColor.c_str()) * GrGLSLExpr4(inputColor)).c_str());
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, (GrGLSLExpr4(bicubicColor.c_str()) * GrGLSLExpr4(inputColor)).c_str());
}
void GrGLBicubicEffect::setData(const GrGLProgramDataManager& pdman,
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index d7ba6865c9..84e60cd76c 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -10,7 +10,7 @@
#include "GrTBackendEffectFactory.h"
#include "GrSimpleTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "SkMatrix.h"
class GrGLConfigConversionEffect : public GrGLEffect {
@@ -23,7 +23,7 @@ public:
fPMConversion = effect.pmConversion();
}
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
@@ -34,20 +34,23 @@ public:
GrGLShaderVar tmpVar("tmpColor", kVec4f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
SkString tmpDecl;
tmpVar.appendDecl(builder->ctxInfo(), &tmpDecl);
- builder->fsCodeAppendf("%s;", tmpDecl.c_str());
- builder->fsCodeAppendf("%s = ", tmpVar.c_str());
- builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
- builder->fsCodeAppend(";");
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+
+ fsBuilder->codeAppendf("%s;", tmpDecl.c_str());
+
+ fsBuilder->codeAppendf("%s = ", tmpVar.c_str());
+ fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
+ fsBuilder->codeAppend(";");
if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) {
SkASSERT(fSwapRedAndBlue);
- builder->fsCodeAppendf("%s = %s.bgra;", outputColor, tmpVar.c_str());
+ fsBuilder->codeAppendf("%s = %s.bgra;", outputColor, tmpVar.c_str());
} else {
const char* swiz = fSwapRedAndBlue ? "bgr" : "rgb";
switch (fPMConversion) {
case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion:
- builder->fsCodeAppendf(
+ fsBuilder->codeAppendf(
"%s = vec4(ceil(%s.%s * %s.a * 255.0) / 255.0, %s.a);",
tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
break;
@@ -56,17 +59,17 @@ public:
// In Intel GPUs, the integer value converted from floor(%s.r * 255.0) / 255.0
// is less than the integer value converted from %s.r by 1 when the %s.r is
// converted from the integer value 2^n, such as 1, 2, 4, 8, etc.
- builder->fsCodeAppendf(
+ fsBuilder->codeAppendf(
"%s = vec4(floor(%s.%s * %s.a * 255.0 + 0.001) / 255.0, %s.a);",
tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
break;
case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion:
- builder->fsCodeAppendf(
+ fsBuilder->codeAppendf(
"%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.%s / %s.a * 255.0) / 255.0, %s.a);",
tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
break;
case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversion:
- builder->fsCodeAppendf(
+ fsBuilder->codeAppendf(
"%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.%s / %s.a * 255.0) / 255.0, %s.a);",
tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
break;
@@ -74,11 +77,11 @@ public:
SkFAIL("Unknown conversion op.");
break;
}
- builder->fsCodeAppendf("%s = %s;", outputColor, tmpVar.c_str());
+ fsBuilder->codeAppendf("%s = %s;", outputColor, tmpVar.c_str());
}
SkString modulate;
GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
- builder->fsCodeAppend(modulate.c_str());
+ fsBuilder->codeAppend(modulate.c_str());
}
static inline void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index 41911c12b0..71a8befece 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -5,10 +5,10 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrConvexPolyEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLSL.h"
#include "GrTBackendEffectFactory.h"
@@ -89,7 +89,7 @@ class GLAARectEffect : public GrGLEffect {
public:
GLAARectEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -113,7 +113,7 @@ GLAARectEffect::GLAARectEffect(const GrBackendEffectFactory& factory,
fPrevRect.fLeft = SK_ScalarNaN;
}
-void GLAARectEffect::emitCode(GrGLShaderBuilder* builder,
+void GLAARectEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -124,34 +124,36 @@ void GLAARectEffect::emitCode(GrGLShaderBuilder* builder,
const char *rectName;
// The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5),
// respectively.
- fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
"rect",
&rectName);
- const char* fragmentPos = builder->fragmentPosition();
+
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ const char* fragmentPos = fsBuilder->fragmentPosition();
if (GrEffectEdgeTypeIsAA(aare.getEdgeType())) {
// The amount of coverage removed in x and y by the edges is computed as a pair of negative
// numbers, xSub and ySub.
- builder->fsCodeAppend("\t\tfloat xSub, ySub;\n");
- builder->fsCodeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName);
- builder->fsCodeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName);
- builder->fsCodeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos);
+ fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n");
+ fsBuilder->codeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName);
+ fsBuilder->codeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos);
+ fsBuilder->codeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName);
+ fsBuilder->codeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos);
// Now compute coverage in x and y and multiply them to get the fraction of the pixel
// covered.
- builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
+ fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
} else {
- builder->fsCodeAppendf("\t\tfloat alpha = 1.0;\n");
- builder->fsCodeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
- builder->fsCodeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
- builder->fsCodeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
- builder->fsCodeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
+ fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
+ fsBuilder->codeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
+ fsBuilder->codeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
+ fsBuilder->codeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
+ fsBuilder->codeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
}
if (GrEffectEdgeTypeIsInverseFill(aare.getEdgeType())) {
- builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n");
+ fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
}
- builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
}
@@ -181,7 +183,7 @@ class GrGLConvexPolyEffect : public GrGLEffect {
public:
GrGLConvexPolyEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -205,7 +207,7 @@ GrGLConvexPolyEffect::GrGLConvexPolyEffect(const GrBackendEffectFactory& factory
fPrevEdges[0] = SK_ScalarNaN;
}
-void GrGLConvexPolyEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLConvexPolyEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -215,34 +217,35 @@ void GrGLConvexPolyEffect::emitCode(GrGLShaderBuilder* builder,
const GrConvexPolyEffect& cpe = drawEffect.castEffect<GrConvexPolyEffect>();
const char *edgeArrayName;
- fEdgeUniform = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+ fEdgeUniform = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
kVec3f_GrSLType,
"edges",
cpe.getEdgeCount(),
&edgeArrayName);
- builder->fsCodeAppend("\t\tfloat alpha = 1.0;\n");
- builder->fsCodeAppend("\t\tfloat edge;\n");
- const char* fragmentPos = builder->fragmentPosition();
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppend("\t\tfloat alpha = 1.0;\n");
+ fsBuilder->codeAppend("\t\tfloat edge;\n");
+ const char* fragmentPos = fsBuilder->fragmentPosition();
for (int i = 0; i < cpe.getEdgeCount(); ++i) {
- builder->fsCodeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
+ fsBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
edgeArrayName, i, fragmentPos, fragmentPos);
if (GrEffectEdgeTypeIsAA(cpe.getEdgeType())) {
- builder->fsCodeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
} else {
- builder->fsCodeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n");
+ fsBuilder->codeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n");
}
- builder->fsCodeAppend("\t\talpha *= edge;\n");
+ fsBuilder->codeAppend("\t\talpha *= edge;\n");
}
// Woe is me. See skbug.com/2149.
if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) {
- builder->fsCodeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n");
+ fsBuilder->codeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n");
}
if (GrEffectEdgeTypeIsInverseFill(cpe.getEdgeType())) {
- builder->fsCodeAppend("\talpha = 1.0 - alpha;\n");
+ fsBuilder->codeAppend("\talpha = 1.0 - alpha;\n");
}
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
}
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp
index e0cf35b242..ba9f8146c8 100644
--- a/src/gpu/effects/GrConvolutionEffect.cpp
+++ b/src/gpu/effects/GrConvolutionEffect.cpp
@@ -5,9 +5,9 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrConvolutionEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
#include "GrTBackendEffectFactory.h"
@@ -19,7 +19,7 @@ class GrGLConvolutionEffect : public GrGLEffect {
public:
GrGLConvolutionEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -55,30 +55,32 @@ GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& facto
fDirection = c.direction();
}
-void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLConvolutionEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString coords2D = builder->ensureFSCoords2D(coords, 0);
- fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "ImageIncrement");
if (this->useBounds()) {
- fBoundsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fBoundsUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "Bounds");
}
- fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+ fKernelUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "Kernel", this->width());
- builder->fsCodeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+
+ fsBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor);
int width = this->width();
const GrGLShaderVar& kernel = builder->getUniformVariable(fKernelUni);
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
- builder->fsCodeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
+ fsBuilder->codeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
// Manually unroll loop because some drivers don't; yields 20-30% speedup.
for (int i = 0; i < width; i++) {
@@ -86,21 +88,21 @@ void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
SkString kernelIndex;
index.appendS32(i);
kernel.appendArrayAccess(index.c_str(), &kernelIndex);
- builder->fsCodeAppendf("\t\t%s += ", outputColor);
- builder->fsAppendTextureLookup(samplers[0], "coord");
+ fsBuilder->codeAppendf("\t\t%s += ", outputColor);
+ fsBuilder->appendTextureLookup(samplers[0], "coord");
if (this->useBounds()) {
const char* bounds = builder->getUniformCStr(fBoundsUni);
const char* component = this->direction() == Gr1DKernelEffect::kY_Direction ? "y" : "x";
- builder->fsCodeAppendf(" * float(coord.%s >= %s.x && coord.%s <= %s.y)",
+ fsBuilder->codeAppendf(" * float(coord.%s >= %s.x && coord.%s <= %s.y)",
component, bounds, component, bounds);
}
- builder->fsCodeAppendf(" * %s;\n", kernelIndex.c_str());
- builder->fsCodeAppendf("\t\tcoord += %s;\n", imgInc);
+ fsBuilder->codeAppendf(" * %s;\n", kernelIndex.c_str());
+ fsBuilder->codeAppendf("\t\tcoord += %s;\n", imgInc);
}
SkString modulate;
GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
- builder->fsCodeAppend(modulate.c_str());
+ fsBuilder->codeAppend(modulate.c_str());
}
void GrGLConvolutionEffect::setData(const GrGLProgramDataManager& pdman,
diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
index d235d5fb76..0401c6c7ef 100644
--- a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
+++ b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
@@ -5,9 +5,9 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrCustomCoordsTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
#include "gl/GrGLVertexEffect.h"
@@ -19,7 +19,7 @@ public:
GrGLCustomCoordsTextureEffect(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect)
: INHERITED (factory) {}
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -34,16 +34,18 @@ public:
builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsVaryingNamePtr);
fsCoordName = fsVaryingNamePtr;
- const char* attrName =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str();
- builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, attrName);
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+ const SkString* attr0Name =
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsVaryingName, attr0Name->c_str());
- builder->fsCodeAppendf("\t%s = ", outputColor);
- builder->fsAppendTextureLookupAndModulate(inputColor,
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("\t%s = ", outputColor);
+ fsBuilder->appendTextureLookupAndModulate(inputColor,
samplers[0],
fsCoordName.c_str(),
kVec2f_GrSLType);
- builder->fsCodeAppend(";\n");
+ fsBuilder->codeAppend(";\n");
}
virtual void setData(const GrGLProgramDataManager& pdman,
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp
index f3af65e3b6..4b2bafefdb 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrDashingEffect.h"
#include "../GrAARectRenderer.h"
@@ -12,7 +13,6 @@
#include "effects/GrVertexEffect.h"
#include "gl/GrGLEffect.h"
#include "gl/GrGLVertexEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLSL.h"
#include "GrContext.h"
#include "GrCoordTransform.h"
@@ -468,7 +468,7 @@ class GLDashingCircleEffect : public GrGLVertexEffect {
public:
GLDashingCircleEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -496,7 +496,7 @@ GLDashingCircleEffect::GLDashingCircleEffect(const GrBackendEffectFactory& facto
fPrevIntervalLength = SK_ScalarMax;
}
-void GLDashingCircleEffect::emitCode(GrGLFullShaderBuilder* builder,
+void GLDashingCircleEffect::emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -507,32 +507,35 @@ void GLDashingCircleEffect::emitCode(GrGLFullShaderBuilder* builder,
const char *paramName;
// The param uniforms, xyz, refer to circle radius - 0.5, cicles center x coord, and
// the total interval length of the dash.
- fParamUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fParamUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec3f_GrSLType,
"params",
&paramName);
const char *vsCoordName, *fsCoordName;
builder->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName);
+
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
const SkString* attr0Name =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str());
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str());
// transforms all points so that we can compare them to our test circle
- builder->fsCodeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.z;\n",
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.z;\n",
fsCoordName, fsCoordName, paramName, paramName);
- builder->fsCodeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName);
- builder->fsCodeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName);
- builder->fsCodeAppend("\t\tfloat dist = length(center - fragPosShifted);\n");
+ fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName);
+ fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName);
+ fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n");
if (GrEffectEdgeTypeIsAA(dce.getEdgeType())) {
- builder->fsCodeAppendf("\t\tfloat diff = dist - %s.x;\n", paramName);
- builder->fsCodeAppend("\t\tdiff = 1.0 - diff;\n");
- builder->fsCodeAppend("\t\tfloat alpha = clamp(diff, 0.0, 1.0);\n");
+ fsBuilder->codeAppendf("\t\tfloat diff = dist - %s.x;\n", paramName);
+ fsBuilder->codeAppend("\t\tdiff = 1.0 - diff;\n");
+ fsBuilder->codeAppend("\t\tfloat alpha = clamp(diff, 0.0, 1.0);\n");
} else {
- builder->fsCodeAppendf("\t\tfloat alpha = 1.0;\n");
- builder->fsCodeAppendf("\t\talpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;\n", paramName);
+ fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
+ fsBuilder->codeAppendf("\t\talpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;\n", paramName);
}
- builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
}
@@ -673,7 +676,7 @@ class GLDashingLineEffect : public GrGLVertexEffect {
public:
GLDashingLineEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -700,7 +703,7 @@ GLDashingLineEffect::GLDashingLineEffect(const GrBackendEffectFactory& factory,
fPrevIntervalLength = SK_ScalarMax;
}
-void GLDashingLineEffect::emitCode(GrGLFullShaderBuilder* builder,
+void GLDashingLineEffect::emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -711,45 +714,47 @@ void GLDashingLineEffect::emitCode(GrGLFullShaderBuilder* builder,
const char *rectName;
// The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5),
// respectively.
- fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
"rect",
&rectName);
const char *intervalName;
// The interval uniform's refers to the total length of the interval (on + off)
- fIntervalUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fIntervalUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType,
"interval",
&intervalName);
const char *vsCoordName, *fsCoordName;
builder->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName);
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
const SkString* attr0Name =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
- builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str());
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str());
// transforms all points so that we can compare them to our test rect
- builder->fsCodeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n",
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n",
fsCoordName, fsCoordName, intervalName, intervalName);
- builder->fsCodeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName);
+ fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName);
if (GrEffectEdgeTypeIsAA(de.getEdgeType())) {
// The amount of coverage removed in x and y by the edges is computed as a pair of negative
// numbers, xSub and ySub.
- builder->fsCodeAppend("\t\tfloat xSub, ySub;\n");
- builder->fsCodeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n", rectName);
- builder->fsCodeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n", rectName);
- builder->fsCodeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n", rectName);
- builder->fsCodeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n", rectName);
+ fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n");
+ fsBuilder->codeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n", rectName);
+ fsBuilder->codeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n", rectName);
+ fsBuilder->codeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n", rectName);
+ fsBuilder->codeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n", rectName);
// Now compute coverage in x and y and multiply them to get the fraction of the pixel
// covered.
- builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
+ fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
} else {
// Assuming the bounding geometry is tight so no need to check y values
- builder->fsCodeAppendf("\t\tfloat alpha = 1.0;\n");
- builder->fsCodeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName);
- builder->fsCodeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;\n", rectName);
+ fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
+ fsBuilder->codeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName);
+ fsBuilder->codeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;\n", rectName);
}
- builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
}
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
index 7ef1cbb2ba..eaaefebc54 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -5,9 +5,9 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrDistanceFieldTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
#include "gl/GrGLVertexEffect.h"
@@ -36,7 +36,7 @@ public:
: INHERITED (factory)
, fTextureSize(SkISize::Make(-1,-1)) {}
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -45,7 +45,9 @@ public:
const TextureSamplerArray& samplers) SK_OVERRIDE {
SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldTextureEffect>().numVertexAttribs());
- SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkAssertResult(fsBuilder->enableFeature(
+ GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
const GrDistanceFieldTextureEffect& dfTexEffect =
drawEffect.castEffect<GrDistanceFieldTextureEffect>();
@@ -55,73 +57,74 @@ public:
builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr);
fsCoordName = fsCoordNamePtr;
- const char* attrName0 =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str();
- builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0);
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+ const SkString* attr0Name =
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str());
const char* textureSizeUniName = NULL;
- fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "TextureSize",
&textureSizeUniName);
- builder->fsCodeAppend("\tvec4 texColor = ");
- builder->fsAppendTextureLookup(samplers[0],
+ fsBuilder->codeAppend("\tvec4 texColor = ");
+ fsBuilder->appendTextureLookup(samplers[0],
fsCoordName.c_str(),
kVec2f_GrSLType);
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppend("\tfloat distance = "
+ fsBuilder->codeAppend(";\n");
+ fsBuilder->codeAppend("\tfloat distance = "
SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ")"
"+ " SK_DistanceFieldNonLCDFactor ";\n");
// we adjust for the effect of the transformation on the distance by using
// the length of the gradient of the texture coordinates. We use st coordinates
// to ensure we're mapping 1:1 from texel space to pixel space.
- builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
- builder->fsCodeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName);
- builder->fsCodeAppend("\tfloat afwidth;\n");
+ fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
+ fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName);
+ fsBuilder->codeAppend("\tfloat afwidth;\n");
if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
// this gives us a smooth step across approximately one fragment
- builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx(st.x);\n");
+ fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx(st.x);\n");
} else {
- builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n");
- builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n");
+ fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
+ fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
- builder->fsCodeAppend("\tvec2 uv_grad;\n");
+ fsBuilder->codeAppend("\tvec2 uv_grad;\n");
if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
// this is to compensate for the Adreno, which likes to drop tiles on division by 0
- builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
- builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n");
- builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
- builder->fsCodeAppend("\t} else {\n");
- builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
- builder->fsCodeAppend("\t}\n");
+ fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
+ fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
+ fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
+ fsBuilder->codeAppend("\t} else {\n");
+ fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
+ fsBuilder->codeAppend("\t}\n");
} else {
- builder->fsCodeAppend("\tuv_grad = normalize(uv);\n");
+ fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
}
- builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
- builder->fsCodeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
+ fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
+ fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
// this gives us a smooth step across approximately one fragment
- builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
+ fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
}
- builder->fsCodeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n");
+ fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n");
#ifdef SK_GAMMA_APPLY_TO_A8
// adjust based on gamma
const char* luminanceUniName = NULL;
// width, height, 1/(3*width)
- fLuminanceUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fLuminanceUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "Luminance",
&luminanceUniName);
- builder->fsCodeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName);
- builder->fsCodeAppend("\tvec4 gammaColor = ");
- builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppend("\tval = gammaColor.r;\n");
+ fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName);
+ fsBuilder->codeAppend("\tvec4 gammaColor = ");
+ fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
+ fsBuilder->codeAppend(";\n");
+ fsBuilder->codeAppend("\tval = gammaColor.r;\n");
#endif
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")).c_str());
}
@@ -261,7 +264,7 @@ public:
: INHERITED (factory)
, fTextureSize(SkISize::Make(-1,-1)) {}
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -270,7 +273,6 @@ public:
const TextureSamplerArray& samplers) SK_OVERRIDE {
SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>().numVertexAttribs());
- SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
const GrDistanceFieldLCDTextureEffect& dfTexEffect =
drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>();
@@ -280,49 +282,55 @@ public:
builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr);
fsCoordName = fsCoordNamePtr;
- const char* attrName0 =
- builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str();
- builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0);
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+ const SkString* attr0Name =
+ vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str());
const char* textureSizeUniName = NULL;
// width, height, 1/(3*width)
- fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec3f_GrSLType, "TextureSize",
&textureSizeUniName);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+
+ SkAssertResult(fsBuilder->enableFeature(
+ GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+
// create LCD offset adjusted by inverse of transform
- builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
- builder->fsCodeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName);
+ fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
+ fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName);
bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
if (isUniformScale) {
- builder->fsCodeAppend("\tfloat dx = dFdx(st.x);\n");
- builder->fsCodeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", textureSizeUniName);
+ fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n");
+ fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", textureSizeUniName);
} else {
- builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n");
- builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n");
- builder->fsCodeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUniName);
+ fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
+ fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
+ fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUniName);
}
// green is distance to uv center
- builder->fsCodeAppend("\tvec4 texColor = ");
- builder->fsAppendTextureLookup(samplers[0], "uv", kVec2f_GrSLType);
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppend("\tvec3 distance;\n");
- builder->fsCodeAppend("\tdistance.y = texColor.r;\n");
+ fsBuilder->codeAppend("\tvec4 texColor = ");
+ fsBuilder->appendTextureLookup(samplers[0], "uv", kVec2f_GrSLType);
+ fsBuilder->codeAppend(";\n");
+ fsBuilder->codeAppend("\tvec3 distance;\n");
+ fsBuilder->codeAppend("\tdistance.y = texColor.r;\n");
// red is distance to left offset
- builder->fsCodeAppend("\tvec2 uv_adjusted = uv - offset;\n");
- builder->fsCodeAppend("\ttexColor = ");
- builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType);
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppend("\tdistance.x = texColor.r;\n");
+ fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
+ fsBuilder->codeAppend("\ttexColor = ");
+ fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType);
+ fsBuilder->codeAppend(";\n");
+ fsBuilder->codeAppend("\tdistance.x = texColor.r;\n");
// blue is distance to right offset
- builder->fsCodeAppend("\tuv_adjusted = uv + offset;\n");
- builder->fsCodeAppend("\ttexColor = ");
- builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType);
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppend("\tdistance.z = texColor.r;\n");
+ fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
+ fsBuilder->codeAppend("\ttexColor = ");
+ fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType);
+ fsBuilder->codeAppend(";\n");
+ fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");
- builder->fsCodeAppend("\tdistance = "
+ fsBuilder->codeAppend("\tdistance = "
"vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"))"
"+ vec3(" SK_DistanceFieldLCDFactor ");\n");
@@ -334,58 +342,58 @@ public:
// for each color component. However, this is only important when using perspective
// transformations, and even then using a single factor seems like a reasonable
// trade-off between quality and speed.
- builder->fsCodeAppend("\tfloat afwidth;\n");
+ fsBuilder->codeAppend("\tfloat afwidth;\n");
if (isUniformScale) {
// this gives us a smooth step across approximately one fragment
- builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\n");
+ fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\n");
} else {
- builder->fsCodeAppend("\tvec2 uv_grad;\n");
+ fsBuilder->codeAppend("\tvec2 uv_grad;\n");
if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
// this is to compensate for the Adreno, which likes to drop tiles on division by 0
- builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
- builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n");
- builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
- builder->fsCodeAppend("\t} else {\n");
- builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
- builder->fsCodeAppend("\t}\n");
+ fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
+ fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
+ fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
+ fsBuilder->codeAppend("\t} else {\n");
+ fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
+ fsBuilder->codeAppend("\t}\n");
} else {
- builder->fsCodeAppend("\tuv_grad = normalize(uv);\n");
+ fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
}
- builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
- builder->fsCodeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
+ fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
+ fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
// this gives us a smooth step across approximately one fragment
- builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
+ fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
}
- builder->fsCodeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);\n");
+ fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);\n");
// adjust based on gamma
const char* textColorUniName = NULL;
// width, height, 1/(3*width)
- fTextColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fTextColorUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec3f_GrSLType, "TextColor",
&textColorUniName);
- builder->fsCodeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName);
- builder->fsCodeAppend("\tvec4 gammaColor = ");
- builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppend("\tval.x = gammaColor.r;\n");
-
- builder->fsCodeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName);
- builder->fsCodeAppend("\tgammaColor = ");
- builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppend("\tval.y = gammaColor.r;\n");
-
- builder->fsCodeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName);
- builder->fsCodeAppend("\tgammaColor = ");
- builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppend("\tval.z = gammaColor.r;\n");
-
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName);
+ fsBuilder->codeAppend("\tvec4 gammaColor = ");
+ fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
+ fsBuilder->codeAppend(";\n");
+ fsBuilder->codeAppend("\tval.x = gammaColor.r;\n");
+
+ fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName);
+ fsBuilder->codeAppend("\tgammaColor = ");
+ fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
+ fsBuilder->codeAppend(";\n");
+ fsBuilder->codeAppend("\tval.y = gammaColor.r;\n");
+
+ fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName);
+ fsBuilder->codeAppend("\tgammaColor = ");
+ fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
+ fsBuilder->codeAppend(";\n");
+ fsBuilder->codeAppend("\tval.z = gammaColor.r;\n");
+
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr4("val")).c_str());
}
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.h b/src/gpu/effects/GrDistanceFieldTextureEffect.h
index ab84753fff..dca1949c50 100644
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.h
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h
@@ -86,7 +86,7 @@ private:
GR_DECLARE_EFFECT_TEST;
- typedef GrVertexEffect INHERITED;
+ typedef GrEffect INHERITED;
};
/**
@@ -131,7 +131,7 @@ private:
GR_DECLARE_EFFECT_TEST;
- typedef GrVertexEffect INHERITED;
+ typedef GrEffect INHERITED;
};
#endif
diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp
index a431897a4e..443df9ed36 100644
--- a/src/gpu/effects/GrDitherEffect.cpp
+++ b/src/gpu/effects/GrDitherEffect.cpp
@@ -5,10 +5,10 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrDitherEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLSL.h"
#include "GrTBackendEffectFactory.h"
@@ -70,7 +70,7 @@ class GLDitherEffect : public GrGLEffect {
public:
GLDitherEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -87,13 +87,14 @@ GLDitherEffect::GLDitherEffect(const GrBackendEffectFactory& factory,
: INHERITED (factory) {
}
-void GLDitherEffect::emitCode(GrGLShaderBuilder* builder,
+void GLDitherEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray&,
const TextureSamplerArray& samplers) {
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
// Generate a random number based on the fragment position. For this
// random number generator, we use the "GLSL rand" function
// that seems to be floating around on the internet. It works under
@@ -103,10 +104,10 @@ void GLDitherEffect::emitCode(GrGLShaderBuilder* builder,
// For each channel c, add the random offset to the pixel to either bump
// it up or let it remain constant during quantization.
- builder->fsCodeAppendf("\t\tfloat r = "
+ fsBuilder->codeAppendf("\t\tfloat r = "
"fract(sin(dot(%s.xy ,vec2(12.9898,78.233))) * 43758.5453);\n",
- builder->fragmentPosition());
- builder->fsCodeAppendf("\t\t%s = (1.0/255.0) * vec4(r, r, r, r) + %s;\n",
+ fsBuilder->fragmentPosition());
+ fsBuilder->codeAppendf("\t\t%s = (1.0/255.0) * vec4(r, r, r, r) + %s;\n",
outputColor, GrGLSLExpr4(inputColor).c_str());
}
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index 01cf944592..e573996e80 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -4,8 +4,8 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrMatrixConvolutionEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLEffect.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
@@ -15,7 +15,7 @@ class GrGLMatrixConvolutionEffect : public GrGLEffect {
public:
GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& effect);
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -51,7 +51,7 @@ GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFa
fConvolveAlpha = m.convolveAlpha();
}
-void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLMatrixConvolutionEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -60,20 +60,20 @@ void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
const TextureSamplerArray& samplers) {
sk_ignore_unused_variable(inputColor);
const GrTextureDomain& domain = drawEffect.castEffect<GrMatrixConvolutionEffect>().domain();
- SkString coords2D = builder->ensureFSCoords2D(coords, 0);
- fBoundsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+
+ fBoundsUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "Bounds");
- fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "ImageIncrement");
- fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+ fKernelUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType,
"Kernel",
fKernelSize.width() * fKernelSize.height());
- fKernelOffsetUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fKernelOffsetUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, "KernelOffset");
- fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fGainUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "Gain");
- fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fBiasUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "Bias");
const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni);
@@ -84,38 +84,40 @@ void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
int kWidth = fKernelSize.width();
int kHeight = fKernelSize.height();
- builder->fsCodeAppend("vec4 sum = vec4(0, 0, 0, 0);");
- builder->fsCodeAppendf("vec2 coord = %s - %s * %s;", coords2D.c_str(), kernelOffset,
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+ fsBuilder->codeAppend("vec4 sum = vec4(0, 0, 0, 0);");
+ fsBuilder->codeAppendf("vec2 coord = %s - %s * %s;", coords2D.c_str(), kernelOffset,
imgInc);
- builder->fsCodeAppend("vec4 c;");
+ fsBuilder->codeAppend("vec4 c;");
for (int y = 0; y < kHeight; y++) {
for (int x = 0; x < kWidth; x++) {
- GrGLShaderBuilder::FSBlock block(builder);
- builder->fsCodeAppendf("float k = %s[%d * %d + %d];", kernel, y, kWidth, x);
+ GrGLShaderBuilder::ShaderBlock block(fsBuilder);
+ fsBuilder->codeAppendf("float k = %s[%d * %d + %d];", kernel, y, kWidth, x);
SkString coord;
coord.printf("coord + vec2(%d, %d) * %s", x, y, imgInc);
- fDomain.sampleTexture(builder, domain, "c", coord, samplers[0]);
+ fDomain.sampleTexture(fsBuilder, domain, "c", coord, samplers[0]);
if (!fConvolveAlpha) {
- builder->fsCodeAppend("c.rgb /= c.a;");
+ fsBuilder->codeAppend("c.rgb /= c.a;");
}
- builder->fsCodeAppend("sum += c * k;");
+ fsBuilder->codeAppend("sum += c * k;");
}
}
if (fConvolveAlpha) {
- builder->fsCodeAppendf("%s = sum * %s + %s;", outputColor, gain, bias);
- builder->fsCodeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);",
+ fsBuilder->codeAppendf("%s = sum * %s + %s;", outputColor, gain, bias);
+ fsBuilder->codeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);",
outputColor, outputColor, outputColor);
} else {
- fDomain.sampleTexture(builder, domain, "c", coords2D, samplers[0]);
- builder->fsCodeAppendf("%s.a = c.a;", outputColor);
- builder->fsCodeAppendf("%s.rgb = sum.rgb * %s + %s;", outputColor, gain, bias);
- builder->fsCodeAppendf("%s.rgb *= %s.a;", outputColor, outputColor);
+ fDomain.sampleTexture(fsBuilder, domain, "c", coords2D, samplers[0]);
+ fsBuilder->codeAppendf("%s.a = c.a;", outputColor);
+ fsBuilder->codeAppendf("%s.rgb = sum.rgb * %s + %s;", outputColor, gain, bias);
+ fsBuilder->codeAppendf("%s.rgb *= %s.a;", outputColor, outputColor);
}
SkString modulate;
GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
- builder->fsCodeAppend(modulate.c_str());
+ fsBuilder->codeAppend(modulate.c_str());
}
void GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
diff --git a/src/gpu/effects/GrOvalEffect.cpp b/src/gpu/effects/GrOvalEffect.cpp
index d915250fe5..369b78042c 100644
--- a/src/gpu/effects/GrOvalEffect.cpp
+++ b/src/gpu/effects/GrOvalEffect.cpp
@@ -5,10 +5,10 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrOvalEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLSL.h"
#include "GrTBackendEffectFactory.h"
@@ -100,7 +100,7 @@ class GLCircleEffect : public GrGLEffect {
public:
GLCircleEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -126,7 +126,7 @@ GLCircleEffect::GLCircleEffect(const GrBackendEffectFactory& factory,
fPrevRadius = -1.f;
}
-void GLCircleEffect::emitCode(GrGLShaderBuilder* builder,
+void GLCircleEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -137,27 +137,29 @@ void GLCircleEffect::emitCode(GrGLShaderBuilder* builder,
const char *circleName;
// The circle uniform is (center.x, center.y, radius + 0.5) for regular fills and
// (... ,radius - 0.5) for inverse fills.
- fCircleUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fCircleUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec3f_GrSLType,
"circle",
&circleName);
- const char* fragmentPos = builder->fragmentPosition();
+
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ const char* fragmentPos = fsBuilder->fragmentPosition();
SkASSERT(kHairlineAA_GrEffectEdgeType != ce.getEdgeType());
if (GrEffectEdgeTypeIsInverseFill(ce.getEdgeType())) {
- builder->fsCodeAppendf("\t\tfloat d = length(%s.xy - %s.xy) - %s.z;\n",
+ fsBuilder->codeAppendf("\t\tfloat d = length(%s.xy - %s.xy) - %s.z;\n",
circleName, fragmentPos, circleName);
} else {
- builder->fsCodeAppendf("\t\tfloat d = %s.z - length(%s.xy - %s.xy);\n",
+ fsBuilder->codeAppendf("\t\tfloat d = %s.z - length(%s.xy - %s.xy);\n",
circleName, fragmentPos, circleName);
}
if (GrEffectEdgeTypeIsAA(ce.getEdgeType())) {
- builder->fsCodeAppend("\t\td = clamp(d, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\t\td = clamp(d, 0.0, 1.0);\n");
} else {
- builder->fsCodeAppend("\t\td = d > 0.5 ? 1.0 : 0.0;\n");
+ fsBuilder->codeAppend("\t\td = d > 0.5 ? 1.0 : 0.0;\n");
}
- builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("d")).c_str());
}
@@ -272,7 +274,7 @@ class GLEllipseEffect : public GrGLEffect {
public:
GLEllipseEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -298,7 +300,7 @@ GLEllipseEffect::GLEllipseEffect(const GrBackendEffectFactory& factory,
fPrevRadii.fX = -1.f;
}
-void GLEllipseEffect::emitCode(GrGLShaderBuilder* builder,
+void GLEllipseEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -308,41 +310,43 @@ void GLEllipseEffect::emitCode(GrGLShaderBuilder* builder,
const EllipseEffect& ee = drawEffect.castEffect<EllipseEffect>();
const char *ellipseName;
// The ellipse uniform is (center.x, center.y, 1 / rx^2, 1 / ry^2)
- fEllipseUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fEllipseUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
"ellipse",
&ellipseName);
- const char* fragmentPos = builder->fragmentPosition();
+
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ const char* fragmentPos = fsBuilder->fragmentPosition();
// d is the offset to the ellipse center
- builder->fsCodeAppendf("\t\tvec2 d = %s.xy - %s.xy;\n", fragmentPos, ellipseName);
- builder->fsCodeAppendf("\t\tvec2 Z = d * %s.zw;\n", ellipseName);
+ fsBuilder->codeAppendf("\t\tvec2 d = %s.xy - %s.xy;\n", fragmentPos, ellipseName);
+ fsBuilder->codeAppendf("\t\tvec2 Z = d * %s.zw;\n", ellipseName);
// implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1.
- builder->fsCodeAppend("\t\tfloat implicit = dot(Z, d) - 1.0;\n");
+ fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, d) - 1.0;\n");
// grad_dot is the squared length of the gradient of the implicit.
- builder->fsCodeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
+ fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
// avoid calling inversesqrt on zero.
- builder->fsCodeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
- builder->fsCodeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
+ fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
+ fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
switch (ee.getEdgeType()) {
case kFillAA_GrEffectEdgeType:
- builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
break;
case kInverseFillAA_GrEffectEdgeType:
- builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
break;
case kFillBW_GrEffectEdgeType:
- builder->fsCodeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 0.0 : 1.0;\n");
+ fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 0.0 : 1.0;\n");
break;
case kInverseFillBW_GrEffectEdgeType:
- builder->fsCodeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 1.0 : 0.0;\n");
+ fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 1.0 : 0.0;\n");
break;
case kHairlineAA_GrEffectEdgeType:
SkFAIL("Hairline not expected here.");
}
- builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
}
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index 5a2b0c3d59..8a3fc44704 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -5,10 +5,10 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrRRectEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLSL.h"
#include "GrConvexPolyEffect.h"
#include "GrOvalEffect.h"
@@ -134,7 +134,7 @@ class GLCircularRRectEffect : public GrGLEffect {
public:
GLCircularRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -159,7 +159,7 @@ GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendEffectFactory& facto
fPrevRRect.setEmpty();
}
-void GLCircularRRectEffect::emitCode(GrGLShaderBuilder* builder,
+void GLCircularRRectEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -173,15 +173,17 @@ void GLCircularRRectEffect::emitCode(GrGLShaderBuilder* builder,
// edges correspond to components x, y, z, and w, respectively. When a side of the rrect has
// only rectangular corners, that side's value corresponds to the rect edge's value outset by
// half a pixel.
- fInnerRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
"innerRect",
&rectName);
- fRadiusPlusHalfUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fRadiusPlusHalfUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType,
"radiusPlusHalf",
&radiusPlusHalfName);
- const char* fragmentPos = builder->fragmentPosition();
+
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ const char* fragmentPos = fsBuilder->fragmentPosition();
// At each quarter-circle corner we compute a vector that is the offset of the fragment position
// from the circle center. The vector is pinned in x and y to be in the quarter-plane relevant
// to that corner. This means that points near the interior near the rrect top edge will have
@@ -199,95 +201,95 @@ void GLCircularRRectEffect::emitCode(GrGLShaderBuilder* builder,
// alphas together.
switch (crre.getCircularCornerFlags()) {
case CircularRRectEffect::kAll_CornerFlags:
- builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
- builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
- builder->fsCodeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
+ fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
+ fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
+ fsBuilder->codeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kTopLeft_CornerFlag:
- builder->fsCodeAppendf("\t\tvec2 dxy = max(%s.xy - %s.xy, 0.0);\n",
+ fsBuilder->codeAppendf("\t\tvec2 dxy = max(%s.xy - %s.xy, 0.0);\n",
rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kTopRight_CornerFlag:
- builder->fsCodeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.z, %s.y - %s.y), 0.0);\n",
+ fsBuilder->codeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.z, %s.y - %s.y), 0.0);\n",
fragmentPos, rectName, rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
fragmentPos, rectName);
- builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kBottomRight_CornerFlag:
- builder->fsCodeAppendf("\t\tvec2 dxy = max(%s.xy - %s.zw, 0.0);\n",
+ fsBuilder->codeAppendf("\t\tvec2 dxy = max(%s.xy - %s.zw, 0.0);\n",
fragmentPos, rectName);
- builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
fragmentPos, rectName);
- builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
fragmentPos, rectName);
- builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kBottomLeft_CornerFlag:
- builder->fsCodeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.x, %s.y - %s.w), 0.0);\n",
+ fsBuilder->codeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.x, %s.y - %s.w), 0.0);\n",
rectName, fragmentPos, fragmentPos, rectName);
- builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
fragmentPos, rectName);
- builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kLeft_CornerFlags:
- builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos, rectName);
- builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, dy1)), 0.0);\n");
- builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
+ fsBuilder->codeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos, rectName);
+ fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, dy1)), 0.0);\n");
+ fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kTop_CornerFlags:
- builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos, rectName);
- builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy0.y), 0.0);\n");
- builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
+ fsBuilder->codeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos, rectName);
+ fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy0.y), 0.0);\n");
+ fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kRight_CornerFlags:
- builder->fsCodeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
- builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1.y)), 0.0);\n");
- builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, fragmentPos);
+ fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
+ fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1.y)), 0.0);\n");
+ fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
fragmentPos, rectName);
- builder->fsCodeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kBottom_CornerFlags:
- builder->fsCodeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
- builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy1.y), 0.0);\n");
- builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, fragmentPos);
+ fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
+ fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy1.y), 0.0);\n");
+ fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
fragmentPos, rectName);
- builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+ fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
}
if (kInverseFillAA_GrEffectEdgeType == crre.getEdgeType()) {
- builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n");
+ fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
}
- builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
}
@@ -486,7 +488,7 @@ class GLEllipticalRRectEffect : public GrGLEffect {
public:
GLEllipticalRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -511,7 +513,7 @@ GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendEffectFactory& f
fPrevRRect.setEmpty();
}
-void GLEllipticalRRectEffect::emitCode(GrGLShaderBuilder* builder,
+void GLEllipticalRRectEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -521,11 +523,13 @@ void GLEllipticalRRectEffect::emitCode(GrGLShaderBuilder* builder,
const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEffect>();
const char *rectName;
// The inner rect is the rrect bounds inset by the x/y radii
- fInnerRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
"innerRect",
&rectName);
- const char* fragmentPos = builder->fragmentPosition();
+
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ const char* fragmentPos = fsBuilder->fragmentPosition();
// At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos
// to the ellipse center. The vector is pinned in x and y to be in the quarter-plane relevant
// to that corner. This means that points near the interior near the rrect top edge will have
@@ -537,31 +541,31 @@ void GLEllipticalRRectEffect::emitCode(GrGLShaderBuilder* builder,
// The code below is a simplified version of the above that performs maxs on the vector
// components before computing distances and alpha values so that only one distance computation
// need be computed to determine the min alpha.
- builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
- builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
+ fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
+ fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
switch (erre.getRRect().getType()) {
case SkRRect::kSimple_Type: {
const char *invRadiiXYSqdName;
- fInvRadiiSqdUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fInvRadiiSqdUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType,
"invRadiiXY",
&invRadiiXYSqdName);
- builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
+ fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
// Z is the x/y offsets divided by squared radii.
- builder->fsCodeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName);
+ fsBuilder->codeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName);
break;
}
case SkRRect::kNinePatch_Type: {
const char *invRadiiLTRBSqdName;
- fInvRadiiSqdUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fInvRadiiSqdUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
"invRadiiLTRB",
&invRadiiLTRBSqdName);
- builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
+ fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
// Z is the x/y offsets divided by squared radii. We only care about the (at most) one
// corner where both the x and y offsets are positive, hence the maxes. (The inverse
// squared radii will always be positive.)
- builder->fsCodeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);\n",
+ fsBuilder->codeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);\n",
invRadiiLTRBSqdName, invRadiiLTRBSqdName);
break;
}
@@ -569,20 +573,20 @@ void GLEllipticalRRectEffect::emitCode(GrGLShaderBuilder* builder,
SkFAIL("RRect should always be simple or nine-patch.");
}
// implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1.
- builder->fsCodeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n");
+ fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n");
// grad_dot is the squared length of the gradient of the implicit.
- builder->fsCodeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
+ fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
// avoid calling inversesqrt on zero.
- builder->fsCodeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
- builder->fsCodeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
+ fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
+ fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
if (kFillAA_GrEffectEdgeType == erre.getEdgeType()) {
- builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
} else {
- builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
+ fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
}
- builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
}
diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp
index 74926bc145..fe55ce9c7c 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.cpp
+++ b/src/gpu/effects/GrSimpleTextureEffect.cpp
@@ -5,9 +5,9 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrSimpleTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
#include "GrTBackendEffectFactory.h"
@@ -19,19 +19,20 @@ public:
: INHERITED (factory) {
}
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) SK_OVERRIDE {
- builder->fsCodeAppendf("\t%s = ", outputColor);
- builder->fsAppendTextureLookupAndModulate(inputColor,
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ fsBuilder->codeAppendf("\t%s = ", outputColor);
+ fsBuilder->appendTextureLookupAndModulate(inputColor,
samplers[0],
coords[0].c_str(),
coords[0].type());
- builder->fsCodeAppend(";\n");
+ fsBuilder->codeAppend(";\n");
}
private:
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 2bad5e8fc5..40006a3f49 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -5,11 +5,11 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrTextureDomain.h"
#include "GrSimpleTextureEffect.h"
#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "SkFloatingPoint.h"
@@ -49,23 +49,25 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLShaderBuilder* builder,
SkASSERT((Mode)-1 == fMode || textureDomain.mode() == fMode);
SkDEBUGCODE(fMode = textureDomain.mode();)
+ GrGLProgramBuilder* program = builder->getProgramBuilder();
+
if (textureDomain.mode() != kIgnore_Mode && !fDomainUni.isValid()) {
const char* name;
SkString uniName("TexDom");
if (textureDomain.fIndex >= 0) {
uniName.appendS32(textureDomain.fIndex);
}
- fDomainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
- kVec4f_GrSLType, uniName.c_str(), &name);
+ fDomainUni = program->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec4f_GrSLType,
+ uniName.c_str(), &name);
fDomainName = name;
}
switch (textureDomain.mode()) {
case kIgnore_Mode: {
- builder->fsCodeAppendf("\t%s = ", outColor);
- builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
+ builder->codeAppendf("\t%s = ", outColor);
+ builder->appendTextureLookupAndModulate(inModulateColor, sampler,
inCoords.c_str());
- builder->fsCodeAppend(";\n");
+ builder->codeAppend(";\n");
break;
}
case kClamp_Mode: {
@@ -73,49 +75,49 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLShaderBuilder* builder,
clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)",
inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str());
- builder->fsCodeAppendf("\t%s = ", outColor);
- builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
+ builder->codeAppendf("\t%s = ", outColor);
+ builder->appendTextureLookupAndModulate(inModulateColor, sampler,
clampedCoords.c_str());
- builder->fsCodeAppend(";\n");
+ builder->codeAppend(";\n");
break;
}
case kDecal_Mode: {
// Add a block since we're going to declare variables.
- GrGLShaderBuilder::FSBlock block(builder);
+ GrGLShaderBuilder::ShaderBlock block(builder);
const char* domain = fDomainName.c_str();
- if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) {
+ if (kImagination_GrGLVendor == program->ctxInfo().vendor()) {
// On the NexusS and GalaxyNexus, the other path (with the 'any'
// call) causes the compilation error "Calls to any function that
// may require a gradient calculation inside a conditional block
// may return undefined results". This appears to be an issue with
// the 'any' call since even the simple "result=black; if (any())
// result=white;" code fails to compile.
- builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n");
- builder->fsCodeAppend("\tvec4 inside = ");
- builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
+ builder->codeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n");
+ builder->codeAppend("\tvec4 inside = ");
+ builder->appendTextureLookupAndModulate(inModulateColor, sampler,
inCoords.c_str());
- builder->fsCodeAppend(";\n");
- builder->fsCodeAppendf("\tfloat x = (%s).x;\n", inCoords.c_str());
- builder->fsCodeAppendf("\tfloat y = (%s).y;\n", inCoords.c_str());
+ builder->codeAppend(";\n");
+ builder->codeAppendf("\tfloat x = (%s).x;\n", inCoords.c_str());
+ builder->codeAppendf("\tfloat y = (%s).y;\n", inCoords.c_str());
- builder->fsCodeAppendf("\tx = abs(2.0*(x - %s.x)/(%s.z - %s.x) - 1.0);\n",
+ builder->codeAppendf("\tx = abs(2.0*(x - %s.x)/(%s.z - %s.x) - 1.0);\n",
domain, domain, domain);
- builder->fsCodeAppendf("\ty = abs(2.0*(y - %s.y)/(%s.w - %s.y) - 1.0);\n",
+ builder->codeAppendf("\ty = abs(2.0*(y - %s.y)/(%s.w - %s.y) - 1.0);\n",
domain, domain, domain);
- builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n");
- builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n", outColor);
+ builder->codeAppend("\tfloat blend = step(1.0, max(x, y));\n");
+ builder->codeAppendf("\t%s = mix(inside, outside, blend);\n", outColor);
} else {
- builder->fsCodeAppend("\tbvec4 outside;\n");
- builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", inCoords.c_str(),
+ builder->codeAppend("\tbvec4 outside;\n");
+ builder->codeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", inCoords.c_str(),
domain);
- builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", inCoords.c_str(),
+ builder->codeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", inCoords.c_str(),
domain);
- builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ",
+ builder->codeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ",
outColor);
- builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
+ builder->appendTextureLookupAndModulate(inModulateColor, sampler,
inCoords.c_str());
- builder->fsCodeAppend(";\n");
+ builder->codeAppend(";\n");
}
break;
}
@@ -125,10 +127,10 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLShaderBuilder* builder,
inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str(),
fDomainName.c_str(), fDomainName.c_str());
- builder->fsCodeAppendf("\t%s = ", outColor);
- builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
+ builder->codeAppendf("\t%s = ", outColor);
+ builder->appendTextureLookupAndModulate(inModulateColor, sampler,
clampedCoords.c_str());
- builder->fsCodeAppend(";\n");
+ builder->codeAppend(";\n");
break;
}
}
@@ -167,7 +169,7 @@ class GrGLTextureDomainEffect : public GrGLEffect {
public:
GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
- virtual void emitCode(GrGLShaderBuilder*,
+ virtual void emitCode(GrGLProgramBuilder*,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
@@ -189,7 +191,7 @@ GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& f
: INHERITED(factory) {
}
-void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
+void GrGLTextureDomainEffect::emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
@@ -199,8 +201,9 @@ void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
const GrTextureDomainEffect& effect = drawEffect.castEffect<GrTextureDomainEffect>();
const GrTextureDomain& domain = effect.textureDomain();
- SkString coords2D = builder->ensureFSCoords2D(coords, 0);
- fGLDomain.sampleTexture(builder, domain, outputColor, coords2D, samplers[0], inputColor);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+ fGLDomain.sampleTexture(fsBuilder, domain, outputColor, coords2D, samplers[0], inputColor);
}
void GrGLTextureDomainEffect::setData(const GrGLProgramDataManager& pdman,
diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h
index 577098a4ad..6cb5ad408e 100644
--- a/src/gpu/effects/GrTextureDomain.h
+++ b/src/gpu/effects/GrTextureDomain.h
@@ -11,6 +11,7 @@
#include "GrSingleTextureEffect.h"
#include "gl/GrGLEffect.h"
+class GrGLProgramBuilder;
class GrGLShaderBuilder;
struct SkRect;
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp
index 15e51a2c62..41d75c30ef 100644
--- a/src/gpu/effects/GrYUVtoRGBEffect.cpp
+++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp
@@ -5,12 +5,12 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrYUVtoRGBEffect.h"
#include "GrCoordTransform.h"
#include "GrEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "GrTBackendEffectFactory.h"
namespace {
@@ -44,26 +44,27 @@ public:
: INHERITED(factory) {
}
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect&,
const GrEffectKey&,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) SK_OVERRIDE {
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
const char* yuvMatrix = "yuvMatrix";
- builder->fsCodeAppendf("\tconst mat4 %s = mat4(1.0, 0.0, 1.402, -0.701,\n\t\t\t"
+ fsBuilder->codeAppendf("\tconst mat4 %s = mat4(1.0, 0.0, 1.402, -0.701,\n\t\t\t"
"1.0, -0.344, -0.714, 0.529,\n\t\t\t"
"1.0, 1.772, 0.0, -0.886,\n\t\t\t"
"0.0, 0.0, 0.0, 1.0);\n",
yuvMatrix);
- builder->fsCodeAppendf("\t%s = vec4(\n\t\t", outputColor);
- builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
- builder->fsCodeAppend(".r,\n\t\t");
- builder->fsAppendTextureLookup(samplers[1], coords[0].c_str(), coords[0].type());
- builder->fsCodeAppend(".r,\n\t\t");
- builder->fsAppendTextureLookup(samplers[2], coords[0].c_str(), coords[0].type());
- builder->fsCodeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
+ fsBuilder->codeAppendf("\t%s = vec4(\n\t\t", outputColor);
+ fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
+ fsBuilder->codeAppend(".r,\n\t\t");
+ fsBuilder->appendTextureLookup(samplers[1], coords[0].c_str(), coords[0].type());
+ fsBuilder->codeAppend(".r,\n\t\t");
+ fsBuilder->appendTextureLookup(samplers[2], coords[0].c_str(), coords[0].type());
+ fsBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
}
typedef GrGLEffect INHERITED;
diff --git a/src/gpu/gl/GrGLEffect.h b/src/gpu/gl/GrGLEffect.h
index 18b3002edf..88aa4cdd1c 100644
--- a/src/gpu/gl/GrGLEffect.h
+++ b/src/gpu/gl/GrGLEffect.h
@@ -68,7 +68,7 @@ public:
GrGLEffect. These can be passed to the builder to emit texture
reads in the generated code.
*/
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index d8c751d71d..d49d000fe3 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -24,13 +24,12 @@ GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu,
const GrGLProgramDesc& desc,
const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[]) {
- SkAutoTDelete<GrGLShaderBuilder> builder;
+ SkAutoTDelete<GrGLProgramBuilder> builder;
if (desc.getHeader().fHasVertexCode ||!gpu->shouldUseFixedFunctionTexturing()) {
- builder.reset(SkNEW_ARGS(GrGLFullShaderBuilder, (gpu, desc)));
+ builder.reset(SkNEW_ARGS(GrGLFullProgramBuilder, (gpu, desc)));
} else {
- builder.reset(SkNEW_ARGS(GrGLFragmentOnlyShaderBuilder, (gpu, desc)));
+ builder.reset(SkNEW_ARGS(GrGLFragmentOnlyProgramBuilder, (gpu, desc)));
}
-
if (builder->genProgram(colorStages, coverageStages)) {
SkASSERT(0 != builder->getProgramID());
return SkNEW_ARGS(GrGLProgram, (gpu, desc, *builder));
@@ -40,7 +39,7 @@ GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu,
GrGLProgram::GrGLProgram(GrGpuGL* gpu,
const GrGLProgramDesc& desc,
- const GrGLShaderBuilder& builder)
+ const GrGLProgramBuilder& builder)
: fColor(GrColor_ILLEGAL)
, fCoverage(GrColor_ILLEGAL)
, fDstCopyTexUnit(-1)
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index fb496856b4..7af55f10ee 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -9,10 +9,10 @@
#ifndef GrGLProgram_DEFINED
#define GrGLProgram_DEFINED
+#include "builders/GrGLProgramBuilder.h"
#include "GrDrawState.h"
#include "GrGLContext.h"
#include "GrGLProgramDesc.h"
-#include "GrGLShaderBuilder.h"
#include "GrGLSL.h"
#include "GrGLTexture.h"
#include "GrGLProgramDataManager.h"
@@ -22,7 +22,7 @@
class GrGLEffect;
class GrGLProgramEffects;
-class GrGLShaderBuilder;
+class GrGLProgramBuilder;
/**
* This class manages a GPU program and records per-program information.
@@ -37,7 +37,7 @@ class GrGLProgram : public SkRefCnt {
public:
SK_DECLARE_INST_COUNT(GrGLProgram)
- typedef GrGLShaderBuilder::BuiltinUniformHandles BuiltinUniformHandles;
+ typedef GrGLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
static GrGLProgram* Create(GrGpuGL* gpu,
const GrGLProgramDesc& desc,
@@ -167,7 +167,7 @@ private:
GrGLProgram(GrGpuGL*,
const GrGLProgramDesc&,
- const GrGLShaderBuilder&);
+ const GrGLProgramBuilder&);
// Sets the texture units for samplers.
void initSamplerUniforms();
diff --git a/src/gpu/gl/GrGLProgramDataManager.cpp b/src/gpu/gl/GrGLProgramDataManager.cpp
index c4c51933c7..eed9d1935d 100644
--- a/src/gpu/gl/GrGLProgramDataManager.cpp
+++ b/src/gpu/gl/GrGLProgramDataManager.cpp
@@ -5,7 +5,7 @@
* found in the LICENSE file.
*/
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "gl/GrGLProgram.h"
#include "gl/GrGLUniformHandle.h"
#include "gl/GrGpuGL.h"
@@ -17,13 +17,13 @@
GrGLProgramDataManager::GrGLProgramDataManager(GrGpuGL* gpu,
GrGLProgram*,
- const GrGLShaderBuilder& builder)
+ const GrGLProgramBuilder& builder)
: fGpu(gpu) {
int count = builder.getUniformInfos().count();
fUniforms.push_back_n(count);
for (int i = 0; i < count; i++) {
Uniform& uniform = fUniforms[i];
- const GrGLShaderBuilder::UniformInfo& builderUniform = builder.getUniformInfos()[i];
+ const GrGLProgramBuilder::UniformInfo& builderUniform = builder.getUniformInfos()[i];
SkASSERT(GrGLShaderVar::kNonArray == builderUniform.fVariable.getArrayCount() ||
builderUniform.fVariable.getArrayCount() > 0);
SkDEBUGCODE(
@@ -32,12 +32,12 @@ GrGLProgramDataManager::GrGLProgramDataManager(GrGpuGL* gpu,
);
// TODO: Move the Xoom uniform array in both FS and VS bug workaround here.
- if (GrGLShaderBuilder::kVertex_Visibility & builderUniform.fVisibility) {
+ if (GrGLProgramBuilder::kVertex_Visibility & builderUniform.fVisibility) {
uniform.fVSLocation = builderUniform.fLocation;
} else {
uniform.fVSLocation = kUnusedUniform;
}
- if (GrGLShaderBuilder::kFragment_Visibility & builderUniform.fVisibility) {
+ if (GrGLProgramBuilder::kFragment_Visibility & builderUniform.fVisibility) {
uniform.fFSLocation = builderUniform.fLocation;
} else {
uniform.fFSLocation = kUnusedUniform;
diff --git a/src/gpu/gl/GrGLProgramDataManager.h b/src/gpu/gl/GrGLProgramDataManager.h
index 8ef4a41fbc..3082f6f02b 100644
--- a/src/gpu/gl/GrGLProgramDataManager.h
+++ b/src/gpu/gl/GrGLProgramDataManager.h
@@ -17,7 +17,7 @@
class GrGpuGL;
class SkMatrix;
class GrGLProgram;
-class GrGLShaderBuilder;
+class GrGLProgramBuilder;
/** Manages the resources used by a shader program.
* The resources are objects the program uses to communicate with the
@@ -51,10 +51,10 @@ public:
int fValue;
friend class GrGLProgramDataManager; // For accessing toProgramDataIndex().
- friend class GrGLShaderBuilder; // For accessing toShaderBuilderIndex().
+ friend class GrGLProgramBuilder; // For accessing toShaderBuilderIndex().
};
- GrGLProgramDataManager(GrGpuGL*, GrGLProgram*, const GrGLShaderBuilder&);
+ GrGLProgramDataManager(GrGpuGL*, GrGLProgram*, const GrGLProgramBuilder&);
/** Functions for uploading uniform values. The varities ending in v can be used to upload to an
* array of uniforms. arrayCount must be <= the array count of the uniform.
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index e1a319104d..7cdbcd0efc 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -5,11 +5,11 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrGLProgramDesc.h"
#include "GrBackendEffectFactory.h"
#include "GrDrawEffect.h"
#include "GrEffect.h"
-#include "GrGLShaderBuilder.h"
#include "GrGpuGL.h"
#include "SkChecksum.h"
@@ -212,15 +212,16 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
if (NULL != dstCopy) {
dstCopyTexture = dstCopy->texture();
}
- header->fDstReadKey = GrGLShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps());
+ header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture,
+ gpu->glCaps());
SkASSERT(0 != header->fDstReadKey);
} else {
header->fDstReadKey = 0;
}
if (readFragPosition) {
- header->fFragPosKey = GrGLShaderBuilder::KeyForFragmentPosition(drawState.getRenderTarget(),
- gpu->glCaps());
+ header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition(
+ drawState.getRenderTarget(), gpu->glCaps());
} else {
header->fFragPosKey = 0;
}
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
index cccdee9ce2..e8925d0c5c 100644
--- a/src/gpu/gl/GrGLProgramDesc.h
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -252,9 +252,12 @@ private:
// part of GrGLShaderBuilder that is used by effects so that this header doesn't need to be
// visible to GrGLEffects. Then make public accessors as necessary and remove friends.
friend class GrGLProgram;
- friend class GrGLShaderBuilder;
- friend class GrGLFullShaderBuilder;
- friend class GrGLFragmentOnlyShaderBuilder;
+ friend class GrGLProgramBuilder;
+ friend class GrGLFullProgramBuilder;
+ friend class GrGLFragmentOnlyProgramBuilder;
+ friend class GrGLVertexShaderBuilder;
+ friend class GrGLFragmentShaderBuilder;
+ friend class GrGLGeometryShaderBuilder;
};
#endif
diff --git a/src/gpu/gl/GrGLProgramEffects.cpp b/src/gpu/gl/GrGLProgramEffects.cpp
index 8ea77d05eb..efb64fe640 100644
--- a/src/gpu/gl/GrGLProgramEffects.cpp
+++ b/src/gpu/gl/GrGLProgramEffects.cpp
@@ -5,10 +5,10 @@
* found in the LICENSE file.
*/
+#include "gl/builders/GrGLProgramBuilder.h"
#include "GrGLProgramEffects.h"
#include "GrDrawEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLVertexEffect.h"
#include "gl/GrGpuGL.h"
@@ -204,7 +204,7 @@ GrGLProgramEffects::~GrGLProgramEffects() {
}
}
-void GrGLProgramEffects::emitSamplers(GrGLShaderBuilder* builder,
+void GrGLProgramEffects::emitSamplers(GrGLProgramBuilder* builder,
const GrEffect* effect,
TextureSamplerArray* outSamplers) {
SkTArray<Sampler, true>& samplers = fSamplers.push_back();
@@ -213,7 +213,7 @@ void GrGLProgramEffects::emitSamplers(GrGLShaderBuilder* builder,
SkString name;
for (int t = 0; t < numTextures; ++t) {
name.printf("Sampler%d", t);
- samplers[t].fUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ samplers[t].fUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kSampler2D_GrSLType,
name.c_str());
SkNEW_APPEND_TO_TARRAY(outSamplers, TextureSampler,
@@ -250,7 +250,7 @@ void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrEffect* effect, int
////////////////////////////////////////////////////////////////////////////////
-void GrGLVertexProgramEffects::emitEffect(GrGLFullShaderBuilder* builder,
+void GrGLVertexProgramEffects::emitEffect(GrGLFullProgramBuilder* builder,
const GrEffectStage& stage,
const GrEffectKey& key,
const char* outColor,
@@ -261,7 +261,9 @@ void GrGLVertexProgramEffects::emitEffect(GrGLFullShaderBuilder* builder,
SkSTArray<2, TransformedCoords> coords(effect->numTransforms());
SkSTArray<4, TextureSampler> samplers(effect->numTextures());
- this->emitAttributes(builder, stage);
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ vsBuilder->emitAttributes(stage);
this->emitTransforms(builder, drawEffect, &coords);
this->emitSamplers(builder, effect, &samplers);
@@ -271,8 +273,8 @@ void GrGLVertexProgramEffects::emitEffect(GrGLFullShaderBuilder* builder,
// Enclose custom code in a block to avoid namespace conflicts
SkString openBrace;
openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
- builder->vsCodeAppend(openBrace.c_str());
- builder->fsCodeAppend(openBrace.c_str());
+ fsBuilder->codeAppend(openBrace.c_str());
+ vsBuilder->codeAppend(openBrace.c_str());
if (glEffect->isVertexEffect()) {
GrGLVertexEffect* vertexEffect = static_cast<GrGLVertexEffect*>(glEffect);
@@ -281,25 +283,11 @@ void GrGLVertexProgramEffects::emitEffect(GrGLFullShaderBuilder* builder,
glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);
}
- builder->vsCodeAppend("\t}\n");
- builder->fsCodeAppend("\t}\n");
+ vsBuilder->codeAppend("\t}\n");
+ fsBuilder->codeAppend("\t}\n");
}
-void GrGLVertexProgramEffects::emitAttributes(GrGLFullShaderBuilder* builder,
- const GrEffectStage& stage) {
- int numAttributes = stage.getVertexAttribIndexCount();
- const int* attributeIndices = stage.getVertexAttribIndices();
- for (int a = 0; a < numAttributes; ++a) {
- // TODO: Make addAttribute mangle the name.
- SkString attributeName("aAttr");
- attributeName.appendS32(attributeIndices[a]);
- builder->addEffectAttribute(attributeIndices[a],
- stage.getEffect()->vertexAttribType(a),
- attributeName);
- }
-}
-
-void GrGLVertexProgramEffects::emitTransforms(GrGLFullShaderBuilder* builder,
+void GrGLVertexProgramEffects::emitTransforms(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
TransformedCoordsArray* outCoords) {
SkTArray<Transform, true>& transforms = fTransforms.push_back();
@@ -327,7 +315,7 @@ void GrGLVertexProgramEffects::emitTransforms(GrGLFullShaderBuilder* builder,
suffixedUniName.appendf("_%i", t);
uniName = suffixedUniName.c_str();
}
- transforms[t].fHandle = builder->addUniform(GrGLShaderBuilder::kVertex_Visibility,
+ transforms[t].fHandle = builder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
kMat33f_GrSLType,
uniName,
&uniName);
@@ -341,18 +329,19 @@ void GrGLVertexProgramEffects::emitTransforms(GrGLFullShaderBuilder* builder,
}
const char* vsVaryingName;
const char* fsVaryingName;
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
const GrGLShaderVar& coords = kPosition_GrCoordSet == get_source_coords(totalKey, t) ?
- builder->positionAttribute() :
- builder->localCoordsAttribute();
+ vsBuilder->positionAttribute() :
+ vsBuilder->localCoordsAttribute();
// varying = matrix * coords (logically)
SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
if (kVec2f_GrSLType == varyingType) {
- builder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
+ vsBuilder->codeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
vsVaryingName, uniName, coords.c_str());
} else {
- builder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
+ vsBuilder->codeAppendf("\t%s = %s * vec3(%s, 1);\n",
vsVaryingName, uniName, coords.c_str());
}
SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords,
@@ -390,13 +379,13 @@ void GrGLVertexProgramEffects::setTransformData(const GrGLProgramDataManager& pr
}
}
-GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder* builder,
+GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullProgramBuilder* builder,
int reserveCount)
: fBuilder(builder)
, fProgramEffects(SkNEW_ARGS(GrGLVertexProgramEffects,
- (reserveCount, fBuilder->hasExplicitLocalCoords()))) {
+ (reserveCount,
+ fBuilder->getVertexShaderBuilder()->hasExplicitLocalCoords()))) {
}
-
void GrGLVertexProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
const GrEffectKey& key,
const char* outColor,
@@ -408,7 +397,7 @@ void GrGLVertexProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
////////////////////////////////////////////////////////////////////////////////
-void GrGLPathTexGenProgramEffects::emitEffect(GrGLFragmentOnlyShaderBuilder* builder,
+void GrGLPathTexGenProgramEffects::emitEffect(GrGLFragmentOnlyProgramBuilder* builder,
const GrEffectStage& stage,
const GrEffectKey& key,
const char* outColor,
@@ -426,18 +415,19 @@ void GrGLPathTexGenProgramEffects::emitEffect(GrGLFragmentOnlyShaderBuilder* bui
GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
fGLEffects.push_back(glEffect);
+ GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
// Enclose custom code in a block to avoid namespace conflicts
SkString openBrace;
openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
- builder->fsCodeAppend(openBrace.c_str());
+ fsBuilder->codeAppend(openBrace.c_str());
SkASSERT(!glEffect->isVertexEffect());
glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);
- builder->fsCodeAppend("\t}\n");
+ fsBuilder->codeAppend("\t}\n");
}
-void GrGLPathTexGenProgramEffects::setupPathTexGen(GrGLFragmentOnlyShaderBuilder* builder,
+void GrGLPathTexGenProgramEffects::setupPathTexGen(GrGLFragmentOnlyProgramBuilder* builder,
const GrDrawEffect& drawEffect,
TransformedCoordsArray* outCoords) {
int numTransforms = drawEffect.effect()->numTransforms();
@@ -499,12 +489,11 @@ void GrGLPathTexGenProgramEffects::setPathTexGenState(GrGpuGL* gpu,
}
GrGLPathTexGenProgramEffectsBuilder::GrGLPathTexGenProgramEffectsBuilder(
- GrGLFragmentOnlyShaderBuilder* builder,
+ GrGLFragmentOnlyProgramBuilder* builder,
int reserveCount)
: fBuilder(builder)
, fProgramEffects(SkNEW_ARGS(GrGLPathTexGenProgramEffects, (reserveCount))) {
}
-
void GrGLPathTexGenProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
const GrEffectKey& key,
const char* outColor,
@@ -513,3 +502,4 @@ void GrGLPathTexGenProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
SkASSERT(NULL != fProgramEffects.get());
fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex);
}
+
diff --git a/src/gpu/gl/GrGLProgramEffects.h b/src/gpu/gl/GrGLProgramEffects.h
index 7ae925b69b..e4d84a013b 100644
--- a/src/gpu/gl/GrGLProgramEffects.h
+++ b/src/gpu/gl/GrGLProgramEffects.h
@@ -16,9 +16,9 @@
class GrEffect;
class GrEffectStage;
class GrGLVertexProgramEffectsBuilder;
-class GrGLShaderBuilder;
-class GrGLFullShaderBuilder;
-class GrGLFragmentOnlyShaderBuilder;
+class GrGLProgramBuilder;
+class GrGLFullProgramBuilder;
+class GrGLFragmentOnlyProgramBuilder;
/**
* This class encapsulates an array of GrGLEffects and their supporting data (coord transforms
@@ -54,6 +54,8 @@ public:
const GrGLProgramDataManager&,
const GrEffectStage* effectStages[]) = 0;
+ void addEffect(GrGLEffect* effect) { fGLEffects.push_back(effect); }
+
/**
* Passed to GrGLEffects so they can add transformed coordinates to their shader code.
*/
@@ -100,6 +102,7 @@ public:
typedef SkTArray<TextureSampler> TextureSamplerArray;
protected:
+
/**
* Helpers for GenEffectMetaKey.
*/
@@ -117,7 +120,7 @@ protected:
* appends the necessary data to the TextureSamplerArray* object so effects can add texture
* lookups to their code. This method is only meant to be called during the construction phase.
*/
- void emitSamplers(GrGLShaderBuilder*, const GrEffect*, TextureSamplerArray*);
+ void emitSamplers(GrGLProgramBuilder*, const GrEffect*, TextureSamplerArray*);
/**
* Helper for setData(). Binds all the textures for an effect.
@@ -134,6 +137,7 @@ protected:
SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
private:
+ friend class GrGLFragmentO;
typedef SkRefCnt INHERITED;
};
@@ -143,7 +147,6 @@ private:
class GrGLProgramEffectsBuilder {
public:
virtual ~GrGLProgramEffectsBuilder() { }
-
/**
* Emits the effect's shader code, and stores the necessary uniforms internally.
*/
@@ -166,19 +169,17 @@ public:
const GrEffectStage* effectStages[]) SK_OVERRIDE;
private:
- friend class GrGLVertexProgramEffectsBuilder;
+ friend class GrGLFullProgramBuilder;
GrGLVertexProgramEffects(int reserveCount, bool explicitLocalCoords)
: INHERITED(reserveCount)
, fTransforms(reserveCount)
, fHasExplicitLocalCoords(explicitLocalCoords) {
}
-
/**
- * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called
- * during the construction phase.
+ * This method is meant to only be called during the construction phase.
*/
- void emitEffect(GrGLFullShaderBuilder*,
+ void emitEffect(GrGLFullProgramBuilder*,
const GrEffectStage&,
const GrEffectKey&,
const char* outColor,
@@ -188,7 +189,7 @@ private:
/**
* Helper for emitEffect(). Emits any attributes an effect may have.
*/
- void emitAttributes(GrGLFullShaderBuilder*, const GrEffectStage&);
+ void emitAttributes(GrGLFullProgramBuilder*, const GrEffectStage&);
/**
* Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
@@ -197,7 +198,7 @@ private:
* of the varyings in the VS and FS as well their types are appended to the
* TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
*/
- void emitTransforms(GrGLFullShaderBuilder*,
+ void emitTransforms(GrGLFullProgramBuilder*,
const GrDrawEffect&,
TransformedCoordsArray*);
@@ -215,6 +216,8 @@ private:
SkTArray<SkSTArray<2, Transform, true> > fTransforms;
bool fHasExplicitLocalCoords;
+ friend class GrGLVertexProgramEffectsBuilder;
+
typedef GrGLProgramEffects INHERITED;
};
@@ -223,25 +226,21 @@ private:
*/
class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
public:
- GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder*, int reserveCount);
+ GrGLVertexProgramEffectsBuilder(GrGLFullProgramBuilder*, int reserveCount);
virtual ~GrGLVertexProgramEffectsBuilder() { }
-
virtual void emitEffect(const GrEffectStage&,
const GrEffectKey&,
const char* outColor,
const char* inColor,
int stageIndex) SK_OVERRIDE;
-
/**
* Finalizes the building process and returns the effect array. After this call, the builder
* becomes invalid.
*/
GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
-
private:
- GrGLFullShaderBuilder* fBuilder;
+ GrGLFullProgramBuilder* fBuilder;
SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
-
typedef GrGLProgramEffectsBuilder INHERITED;
};
@@ -258,7 +257,7 @@ public:
const GrEffectStage* effectStages[]) SK_OVERRIDE;
private:
- friend class GrGLPathTexGenProgramEffectsBuilder;
+ friend class GrGLFragmentOnlyProgramBuilder;
GrGLPathTexGenProgramEffects(int reserveCount)
: INHERITED(reserveCount)
@@ -266,10 +265,9 @@ private:
}
/**
- * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called
- * during the construction phase.
+ * This method is meant to only be called during the construction phase.
*/
- void emitEffect(GrGLFragmentOnlyShaderBuilder*,
+ void emitEffect(GrGLFragmentOnlyProgramBuilder*,
const GrEffectStage&,
const GrEffectKey&,
const char* outColor,
@@ -284,7 +282,7 @@ private:
* types are appended to the TransformedCoordsArray* object, which is in turn passed to the
* effect's emitCode() function.
*/
- void setupPathTexGen(GrGLFragmentOnlyShaderBuilder*,
+ void setupPathTexGen(GrGLFragmentOnlyProgramBuilder*,
const GrDrawEffect&,
TransformedCoordsArray*);
@@ -302,6 +300,7 @@ private:
SkTArray<Transforms> fTransforms;
+ friend class GrGLPathTexGenProgramEffectsBuilder;
typedef GrGLProgramEffects INHERITED;
};
@@ -310,26 +309,23 @@ private:
*/
class GrGLPathTexGenProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
public:
- GrGLPathTexGenProgramEffectsBuilder(GrGLFragmentOnlyShaderBuilder*, int reserveCount);
+ GrGLPathTexGenProgramEffectsBuilder(GrGLFragmentOnlyProgramBuilder*, int reserveCount);
virtual ~GrGLPathTexGenProgramEffectsBuilder() { }
-
virtual void emitEffect(const GrEffectStage&,
const GrEffectKey&,
const char* outColor,
const char* inColor,
int stageIndex) SK_OVERRIDE;
-
/**
* Finalizes the building process and returns the effect array. After this call, the builder
* becomes invalid.
*/
GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
-
private:
- GrGLFragmentOnlyShaderBuilder* fBuilder;
+ GrGLFragmentOnlyProgramBuilder* fBuilder;
SkAutoTDelete<GrGLPathTexGenProgramEffects> fProgramEffects;
-
typedef GrGLProgramEffectsBuilder INHERITED;
};
+
#endif
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
deleted file mode 100644
index 9fffd26145..0000000000
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ /dev/null
@@ -1,1071 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "gl/GrGLShaderBuilder.h"
-#include "gl/GrGLProgram.h"
-#include "gl/GrGLSLPrettyPrint.h"
-#include "gl/GrGLUniformHandle.h"
-#include "GrCoordTransform.h"
-#include "GrDrawEffect.h"
-#include "GrGpuGL.h"
-#include "GrTexture.h"
-#include "SkRTConf.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)
-
-// number of each input/output type in a single allocation block
-static const int kVarsPerBlock = 8;
-
-// except FS outputs where we expect 2 at most.
-static const int kMaxFSOutputs = 2;
-
-// ES2 FS only guarantees mediump and lowp support
-static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
-
-typedef GrGLProgramDataManager::UniformHandle UniformHandle;
-
-SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
- "Print the source code for all shaders generated.");
-
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-inline const char* color_attribute_name() { return "aColor"; }
-inline const char* coverage_attribute_name() { return "aCoverage"; }
-inline const char* declared_color_output_name() { return "fsColorOut"; }
-inline const char* dual_source_output_name() { return "dualSourceOut"; }
-inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) {
- if (kVec2f_GrSLType == type) {
- return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D";
- } else {
- SkASSERT(kVec3f_GrSLType == type);
- return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj";
- }
-}
-
-void append_texture_lookup(SkString* out,
- GrGpuGL* gpu,
- const char* samplerName,
- const char* coordName,
- uint32_t configComponentMask,
- const char* swizzle,
- GrSLType varyingType = kVec2f_GrSLType) {
- SkASSERT(NULL != coordName);
-
- out->appendf("%s(%s, %s)",
- sample_function_name(varyingType, gpu->glslGeneration()),
- samplerName,
- coordName);
-
- char mangledSwizzle[5];
-
- // The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle
- // is available.
- if (!gpu->glCaps().textureSwizzleSupport() &&
- (kA_GrColorComponentFlag == configComponentMask)) {
- char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a';
- int i;
- for (i = 0; '\0' != swizzle[i]; ++i) {
- mangledSwizzle[i] = alphaChar;
- }
- mangledSwizzle[i] ='\0';
- swizzle = mangledSwizzle;
- }
- // For shader prettiness we omit the swizzle rather than appending ".rgba".
- if (memcmp(swizzle, "rgba", 4)) {
- out->appendf(".%s", swizzle);
- }
-}
-
-}
-
-static const char kDstCopyColorName[] = "_dstColor";
-
-///////////////////////////////////////////////////////////////////////////////
-
-bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[],
- const GrEffectStage* coverageStages[]) {
- const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
-
- ///////////////////////////////////////////////////////////////////////////
- // emit code to read the dst copy texture, if necessary
- if (kNoDstRead_DstReadKey != header.fDstReadKey && !fGpu->glCaps().fbFetchSupport()) {
- 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;
- }
- fUniformHandles.fDstCopySamplerUni =
- this->addUniform(kFragment_Visibility, kSampler2D_GrSLType, "DstCopySampler",
- &dstCopySamplerName);
- fUniformHandles.fDstCopyTopLeftUni =
- this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyUpperLeft",
- &dstCopyTopLeftName);
- 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",
- fragPos, dstCopyTopLeftName, dstCopyCoordScaleName);
- if (!topDown) {
- this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n");
- }
- this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName);
- append_texture_lookup(&fFSCode,
- fGpu,
- 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;
- fUniformHandles.fColorUni =
- this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Color",
- &name);
- inputColor = GrGLSLExpr4(name);
- }
-
- if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
- const char* name;
- fUniformHandles.fCoverageUni =
- this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Coverage",
- &name);
- inputCoverage = GrGLSLExpr4(name);
- } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) {
- inputCoverage = GrGLSLExpr4(1);
- }
-
- if (k110_GrGLSLGeneration != fGpu->glslGeneration()) {
- fFSOutputs.push_back().set(kVec4f_GrSLType,
- GrGLShaderVar::kOut_TypeModifier,
- declared_color_output_name());
- fHasCustomColorOutput = true;
- }
-
- this->emitCodeBeforeEffects(&inputColor, &inputCoverage);
-
- ///////////////////////////////////////////////////////////////////////////
- // emit the per-effect code for both color and coverage effects
-
- GrGLProgramDesc::EffectKeyProvider colorKeyProvider(
- &this->desc(), GrGLProgramDesc::EffectKeyProvider::kColor_EffectType);
- fColorEffects.reset(this->createAndEmitEffects(colorStages,
- this->desc().numColorEffects(),
- colorKeyProvider,
- &inputColor));
-
- GrGLProgramDesc::EffectKeyProvider coverageKeyProvider(
- &this->desc(), GrGLProgramDesc::EffectKeyProvider::kCoverage_EffectType);
- fCoverageEffects.reset(this->createAndEmitEffects(coverageStages,
- this->desc().numCoverageEffects(),
- coverageKeyProvider,
- &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,
- const GrGLProgramDesc& desc)
- : fHasVertexShader(false)
- , fTexCoordSetCnt(0)
- , fProgramID(0)
- , fDesc(desc)
- , fGpu(gpu)
- , 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) {
- switch (feature) {
- case kStandardDerivatives_GLSLFeature:
- if (!fGpu->glCaps().shaderDerivativeSupport()) {
- return false;
- }
- if (kGLES_GrGLStandard == fGpu->glStandard()) {
- this->addFSFeature(1 << kStandardDerivatives_GLSLFeature,
- "GL_OES_standard_derivatives");
- }
- return true;
- default:
- SkFAIL("Unexpected GLSLFeature requested.");
- return false;
- }
-}
-
-void GrGLShaderBuilder::addFSFeature(uint32_t featureBit, const char* extensionName) {
- if (!(featureBit & fFSFeaturesAddedMask)) {
- fFSExtensions.appendf("#extension %s: require\n", extensionName);
- fFSFeaturesAddedMask |= featureBit;
- }
-}
-
-void GrGLShaderBuilder::nameVariable(SkString* out, char prefix, const char* name) {
- if ('\0' == prefix) {
- *out = name;
- } else {
- out->printf("%c%s", prefix, name);
- }
- if (fCodeStage.inStageCode()) {
- if (out->endsWith('_')) {
- // Names containing "__" are reserved.
- out->append("x");
- }
- out->appendf("_Stage%d", fCodeStage.stageIndex());
- }
-}
-
-const char* GrGLShaderBuilder::dstColor() {
- if (fCodeStage.inStageCode()) {
- const GrEffect* effect = fCodeStage.effectStage()->getEffect();
- if (!effect->willReadDstColor()) {
- SkDEBUGFAIL("GrGLEffect asked for dst color but its generating GrEffect "
- "did not request access.");
- return "";
- }
- }
-
- if (fGpu->glCaps().fbFetchSupport()) {
- this->addFSFeature(1 << (kLastGLSLPrivateFeature + 1),
- fGpu->glCaps().fbFetchExtensionString());
- return fGpu->glCaps().fbFetchColorName();
- } else if (fUniformHandles.fDstCopySamplerUni.isValid()) {
- return kDstCopyColorName;
- } else {
- return "";
- }
-}
-
-void GrGLShaderBuilder::appendTextureLookup(SkString* out,
- const GrGLShaderBuilder::TextureSampler& sampler,
- const char* coordName,
- GrSLType varyingType) const {
- append_texture_lookup(out,
- fGpu,
- this->getUniformCStr(sampler.samplerUniform()),
- coordName,
- sampler.configComponentMask(),
- sampler.swizzle(),
- varyingType);
-}
-
-void GrGLShaderBuilder::fsAppendTextureLookup(const GrGLShaderBuilder::TextureSampler& sampler,
- const char* coordName,
- GrSLType varyingType) {
- this->appendTextureLookup(&fFSCode, sampler, coordName, varyingType);
-}
-
-void GrGLShaderBuilder::fsAppendTextureLookupAndModulate(
- const char* modulation,
- const GrGLShaderBuilder::TextureSampler& sampler,
- const char* coordName,
- GrSLType varyingType) {
- SkString lookup;
- this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
- fFSCode.append((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str());
-}
-
-GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture* dstCopy,
- const GrGLCaps& caps) {
- uint32_t key = kYesDstRead_DstReadKeyBit;
- if (caps.fbFetchSupport()) {
- return key;
- }
- SkASSERT(NULL != dstCopy);
- if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->config())) {
- // The fact that the config is alpha-only must be considered when generating code.
- key |= kUseAlphaConfig_DstReadKeyBit;
- }
- if (kTopLeft_GrSurfaceOrigin == dstCopy->origin()) {
- key |= kTopLeftOrigin_DstReadKeyBit;
- }
- SkASSERT(static_cast<DstReadKey>(key) == key);
- return static_cast<DstReadKey>(key);
-}
-
-GrGLShaderBuilder::FragPosKey GrGLShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst,
- const GrGLCaps&) {
- if (kTopLeft_GrSurfaceOrigin == dst->origin()) {
- return kTopLeftFragPosRead_FragPosKey;
- } else {
- return kBottomLeftFragPosRead_FragPosKey;
- }
-}
-
-
-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;
- }
-}
-
-GrGLProgramDataManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t visibility,
- GrSLType type,
- const char* name,
- int count,
- const char** outName) {
- SkASSERT(name && strlen(name));
- SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFragment_Visibility);
- SkASSERT(0 == (~kVisibilityMask & visibility));
- SkASSERT(0 != visibility);
-
- UniformInfo& uni = fUniforms.push_back();
- uni.fVariable.setType(type);
- uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
- this->nameVariable(uni.fVariable.accessName(), 'u', name);
- uni.fVariable.setArrayCount(count);
- uni.fVisibility = visibility;
-
- // If it is visible in both the VS and FS, the precision must match.
- // We declare a default FS precision, but not a default VS. So set the var
- // to use the default FS precision.
- if ((kVertex_Visibility | kFragment_Visibility) == visibility) {
- // the fragment and vertex precisions must match
- uni.fVariable.setPrecision(kDefaultFragmentPrecision);
- }
-
- if (NULL != outName) {
- *outName = uni.fVariable.c_str();
- }
- return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fUniforms.count() - 1);
-}
-
-SkString GrGLShaderBuilder::ensureFSCoords2D(const TransformedCoordsArray& coords, int index) {
- if (kVec3f_GrSLType != coords[index].type()) {
- SkASSERT(kVec2f_GrSLType == coords[index].type());
- return coords[index].getName();
- }
-
- SkString coords2D("coords2D");
- if (0 != index) {
- coords2D.appendf("_%i", index);
- }
- this->fsCodeAppendf("\tvec2 %s = %s.xy / %s.z;",
- coords2D.c_str(), coords[index].c_str(), coords[index].c_str());
- return coords2D;
-}
-
-const char* GrGLShaderBuilder::fragmentPosition() {
- if (fCodeStage.inStageCode()) {
- const GrEffect* effect = fCodeStage.effectStage()->getEffect();
- if (!effect->willReadFragmentPosition()) {
- 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) {
- fSetupFragPosition = true;
- return "gl_FragCoord";
- } else if (fGpu->glCaps().fragCoordConventionsSupport()) {
- if (!fSetupFragPosition) {
- if (fGpu->glslGeneration() < k150_GrGLSLGeneration) {
- this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature,
- "GL_ARB_fragment_coord_conventions");
- }
- fFSInputs.push_back().set(kVec4f_GrSLType,
- GrGLShaderVar::kIn_TypeModifier,
- "gl_FragCoord",
- GrGLShaderVar::kDefault_Precision,
- GrGLShaderVar::kUpperLeft_Origin);
- fSetupFragPosition = true;
- }
- return "gl_FragCoord";
- } else {
- static const char* kCoordName = "fragCoordYDown";
- if (!fSetupFragPosition) {
- // temporarily change the stage index because we're inserting non-stage code.
- CodeStage::AutoStageRestore csar(&fCodeStage, NULL);
-
- SkASSERT(!fUniformHandles.fRTHeightUni.isValid());
- const char* rtHeightName;
-
- fUniformHandles.fRTHeightUni =
- this->addUniform(kFragment_Visibility, kFloat_GrSLType, "RTHeight", &rtHeightName);
-
- // Using glFragCoord.zw for the last two components tickles an Adreno driver bug that
- // causes programs to fail to link. Making this function return a vec2() didn't fix the
- // problem but using 1.0 for the last two components does.
- this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, 1.0, "
- "1.0);\n", kCoordName, rtHeightName);
- fSetupFragPosition = true;
- }
- SkASSERT(fUniformHandles.fRTHeightUni.isValid());
- return kCoordName;
- }
-}
-
-void GrGLShaderBuilder::fsEmitFunction(GrSLType returnType,
- const char* name,
- int argCnt,
- const GrGLShaderVar* args,
- const char* body,
- SkString* outName) {
- fFSFunctions.append(GrGLSLTypeString(returnType));
- this->nameVariable(outName, '\0', name);
- fFSFunctions.appendf(" %s", outName->c_str());
- fFSFunctions.append("(");
- for (int i = 0; i < argCnt; ++i) {
- args[i].appendDecl(this->ctxInfo(), &fFSFunctions);
- if (i < argCnt - 1) {
- fFSFunctions.append(", ");
- }
- }
- fFSFunctions.append(") {\n");
- fFSFunctions.append(body);
- fFSFunctions.append("}\n\n");
-}
-
-namespace {
-
-inline void append_default_precision_qualifier(GrGLShaderVar::Precision p,
- GrGLStandard standard,
- SkString* str) {
- // Desktop GLSL has added precision qualifiers but they don't do anything.
- if (kGLES_GrGLStandard == standard) {
- switch (p) {
- case GrGLShaderVar::kHigh_Precision:
- str->append("precision highp float;\n");
- break;
- case GrGLShaderVar::kMedium_Precision:
- str->append("precision mediump float;\n");
- break;
- case GrGLShaderVar::kLow_Precision:
- str->append("precision lowp float;\n");
- break;
- case GrGLShaderVar::kDefault_Precision:
- SkFAIL("Default precision now allowed.");
- default:
- SkFAIL("Unknown precision value.");
- }
- }
-}
-}
-
-void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const {
- for (int i = 0; i < vars.count(); ++i) {
- vars[i].appendDecl(this->ctxInfo(), out);
- out->append(";\n");
- }
-}
-
-void GrGLShaderBuilder::appendUniformDecls(ShaderVisibility visibility,
- SkString* out) const {
- for (int i = 0; i < fUniforms.count(); ++i) {
- if (fUniforms[i].fVisibility & visibility) {
- fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out);
- out->append(";\n");
- }
- }
-}
-
-void GrGLShaderBuilder::createAndEmitEffects(GrGLProgramEffectsBuilder* programEffectsBuilder,
- const GrEffectStage* effectStages[],
- int effectCnt,
- const GrGLProgramDesc::EffectKeyProvider& keyProvider,
- GrGLSLExpr4* fsInOutColor) {
- bool effectEmitted = false;
-
- GrGLSLExpr4 inColor = *fsInOutColor;
- GrGLSLExpr4 outColor;
-
- for (int e = 0; e < effectCnt; ++e) {
- SkASSERT(NULL != effectStages[e] && NULL != effectStages[e]->getEffect());
- const GrEffectStage& stage = *effectStages[e];
-
- CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
-
- if (inColor.isZeros()) {
- SkString inColorName;
-
- // Effects have no way to communicate zeros, they treat an empty string as ones.
- this->nameVariable(&inColorName, '\0', "input");
- this->fsCodeAppendf("\tvec4 %s = %s;\n", inColorName.c_str(), inColor.c_str());
- inColor = inColorName;
- }
-
- // create var to hold stage result
- SkString outColorName;
- this->nameVariable(&outColorName, '\0', "output");
- this->fsCodeAppendf("\tvec4 %s;\n", outColorName.c_str());
- outColor = outColorName;
-
-
- programEffectsBuilder->emitEffect(stage,
- keyProvider.get(e),
- outColor.c_str(),
- inColor.isOnes() ? NULL : inColor.c_str(),
- fCodeStage.stageIndex());
-
- inColor = outColor;
- effectEmitted = true;
- }
-
- if (effectEmitted) {
- *fsInOutColor = outColor;
- }
-}
-
-const char* GrGLShaderBuilder::getColorOutputName() const {
- return fHasCustomColorOutput ? declared_color_output_name() : "gl_FragColor";
-}
-
-const char* GrGLShaderBuilder::enableSecondaryOutput() {
- if (!fHasSecondaryOutput) {
- fFSOutputs.push_back().set(kVec4f_GrSLType,
- GrGLShaderVar::kOut_TypeModifier,
- dual_source_output_name());
- fHasSecondaryOutput = true;
- }
- return dual_source_output_name();
-}
-
-bool GrGLShaderBuilder::finish() {
- SkASSERT(0 == fProgramID);
- GL_CALL_RET(fProgramID, CreateProgram());
- if (!fProgramID) {
- return false;
- }
-
- SkTDArray<GrGLuint> shadersToDelete;
-
- if (!this->compileAndAttachShaders(fProgramID, &shadersToDelete)) {
- GL_CALL(DeleteProgram(fProgramID));
- return false;
- }
-
- this->bindProgramLocations(fProgramID);
-
- GL_CALL(LinkProgram(fProgramID));
-
- // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
- bool checkLinked = !fGpu->ctxInfo().isChromium();
-#ifdef SK_DEBUG
- checkLinked = true;
-#endif
- if (checkLinked) {
- GrGLint linked = GR_GL_INIT_ZERO;
- GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked));
- if (!linked) {
- GrGLint infoLen = GR_GL_INIT_ZERO;
- GL_CALL(GetProgramiv(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(fProgramID,
- infoLen+1,
- &length,
- (char*)log.get()));
- GrPrintf((char*)log.get());
- }
- SkDEBUGFAIL("Error linking program");
- GL_CALL(DeleteProgram(fProgramID));
- fProgramID = 0;
- return false;
- }
- }
-
- this->resolveProgramLocations(fProgramID);
-
- for (int i = 0; i < shadersToDelete.count(); ++i) {
- GL_CALL(DeleteShader(shadersToDelete[i]));
- }
-
- return true;
-}
-
-// 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 0;
- }
-
-#ifdef SK_DEBUG
- SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, false);
- const GrGLchar* sourceStr = prettySource.c_str();
- GrGLint sourceLength = static_cast<GrGLint>(prettySource.size());
-#else
- GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size());
- const GrGLchar* sourceStr = shaderSrc.c_str();
-#endif
- GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
- GR_GL_CALL(gli, CompileShader(shaderId));
-
- // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds.
- bool checkCompiled = !glCtx.isChromium();
-#ifdef SK_DEBUG
- checkCompiled = true;
-#endif
- if (checkCompiled) {
- GrGLint compiled = GR_GL_INIT_ZERO;
- GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));
-
- if (!compiled) {
- GrGLint infoLen = GR_GL_INIT_ZERO;
- GR_GL_CALL(gli, GetShaderiv(shaderId, 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 Chromium cmd
- // buffer param validation.
- GrGLsizei length = GR_GL_INIT_ZERO;
- GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1,
- &length, (char*)log.get()));
- GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str());
- GrPrintf("\n%s", log.get());
- }
- SkDEBUGFAIL("Shader compilation failed!");
- GR_GL_CALL(gli, DeleteShader(shaderId));
- return 0;
- }
- }
-
- TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader",
- TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(shaderSrc.c_str()));
- if (c_PrintShaders) {
- GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str());
- 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));
-
- return shaderId;
-}
-
-bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const {
- SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
- fragShaderSrc.append(fFSExtensions);
- append_default_precision_qualifier(kDefaultFragmentPrecision,
- fGpu->glStandard(),
- &fragShaderSrc);
- this->appendUniformDecls(kFragment_Visibility, &fragShaderSrc);
- this->appendDecls(fFSInputs, &fragShaderSrc);
- // We shouldn't have declared outputs on 1.10
- SkASSERT(k110_GrGLSLGeneration != fGpu->glslGeneration() || fFSOutputs.empty());
- this->appendDecls(fFSOutputs, &fragShaderSrc);
- fragShaderSrc.append(fFSFunctions);
- fragShaderSrc.append("void main() {\n");
- fragShaderSrc.append(fFSCode);
- fragShaderSrc.append("}\n");
-
- GrGLuint fragShaderId = attach_shader(fGpu->glContext(), programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc);
- if (!fragShaderId) {
- return false;
- }
-
- *shaderIds->append() = fragShaderId;
-
- return true;
-}
-
-void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) {
- if (fHasCustomColorOutput) {
- GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name()));
- }
- if (fHasSecondaryOutput) {
- GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_name()));
- }
- // skbug.com/2056
- bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
- if (usingBindUniform) {
- int count = fUniforms.count();
- for (int i = 0; i < count; ++i) {
- GL_CALL(BindUniformLocation(programId, i, fUniforms[i].fVariable.c_str()));
- fUniforms[i].fLocation = i;
- }
- }
-}
-
-void GrGLShaderBuilder::resolveProgramLocations(GrGLuint programId) {
- bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
- if (!usingBindUniform) {
- int count = fUniforms.count();
- for (int i = 0; i < count; ++i) {
- GrGLint location;
- GL_CALL_RET(location,
- GetUniformLocation(programId, fUniforms[i].fVariable.c_str()));
- fUniforms[i].fLocation = location;
- }
- }
-}
-
-const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const {
- return fGpu->ctxInfo();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu,
- const GrGLProgramDesc& desc)
- : INHERITED(gpu, desc)
- , fVSAttrs(kVarsPerBlock)
- , fVSOutputs(kVarsPerBlock)
- , fGSInputs(kVarsPerBlock)
- , fGSOutputs(kVarsPerBlock) {
-}
-
-void GrGLFullShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) {
- const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
-
- fHasVertexShader = true;
-
- fPositionVar = &fVSAttrs.push_back();
- fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
- if (-1 != header.fLocalCoordAttributeIndex) {
- fLocalCoordsVar = &fVSAttrs.push_back();
- fLocalCoordsVar->set(kVec2f_GrSLType,
- GrGLShaderVar::kAttribute_TypeModifier,
- "aLocalCoords");
- } else {
- fLocalCoordsVar = fPositionVar;
- }
-
- const char* viewMName;
- fUniformHandles.fViewMatrixUni =
- this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kMat33f_GrSLType, "ViewM",
- &viewMName);
-
- // 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
- if (header.fEmitsPointSize
-#if GR_GL_EXPERIMENTAL_GS
- && !header.fExperimentalGS
-#endif
- ) {
- this->vsCodeAppend("\tgl_PointSize = 1.0;\n");
- }
-
- if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) {
- this->addAttribute(kVec4f_GrSLType, color_attribute_name());
- const char *vsName, *fsName;
- this->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
- this->vsCodeAppendf("\t%s = %s;\n", vsName, color_attribute_name());
- *color = fsName;
- }
-
- if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
- this->addAttribute(kVec4f_GrSLType, coverage_attribute_name());
- const char *vsName, *fsName;
- this->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
- this->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name());
- *coverage = fsName;
- }
-}
-
-void GrGLFullShaderBuilder::emitCodeAfterEffects() {
- const char* rtAdjustName;
- 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];
- // if attribute already added, don't add it again
- if (attr.getName().equals(name)) {
- SkASSERT(attr.getType() == type);
- return false;
- }
- }
- fVSAttrs.push_back().set(type,
- GrGLShaderVar::kAttribute_TypeModifier,
- name);
- return true;
-}
-
-bool GrGLFullShaderBuilder::addEffectAttribute(int attributeIndex,
- GrSLType type,
- const SkString& name) {
- if (!this->addAttribute(type, name.c_str())) {
- return false;
- }
-
- fEffectAttributes.push_back().set(attributeIndex, name);
- return true;
-}
-
-void GrGLFullShaderBuilder::addVarying(GrSLType type,
- const char* name,
- const char** vsOutName,
- const char** fsInName) {
- fVSOutputs.push_back();
- fVSOutputs.back().setType(type);
- fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
- this->nameVariable(fVSOutputs.back().accessName(), 'v', name);
-
- if (vsOutName) {
- *vsOutName = fVSOutputs.back().getName().c_str();
- }
- // input to FS comes either from VS or GS
- const SkString* fsName;
-#if GR_GL_EXPERIMENTAL_GS
- 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();
- fGSInputs.back().setType(type);
- fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier);
- fGSInputs.back().setUnsizedArray();
- *fGSInputs.back().accessName() = fVSOutputs.back().getName();
- fGSOutputs.push_back();
- fGSOutputs.back().setType(type);
- fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
- this->nameVariable(fGSOutputs.back().accessName(), 'g', name);
- fsName = fGSOutputs.back().accessName();
- } else
-#endif
- {
- fsName = fVSOutputs.back().accessName();
- }
- this->fsInputAppend().set(type, GrGLShaderVar::kVaryingIn_TypeModifier, *fsName);
- if (fsInName) {
- *fsInName = fsName->c_str();
- }
-}
-
-const SkString* GrGLFullShaderBuilder::getEffectAttributeName(int attributeIndex) const {
- const AttributePair* attribEnd = fEffectAttributes.end();
- for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attribEnd; ++attrib) {
- if (attrib->fIndex == attributeIndex) {
- return &attrib->fName;
- }
- }
-
- return NULL;
-}
-
-GrGLProgramEffects* GrGLFullShaderBuilder::createAndEmitEffects(
- const GrEffectStage* effectStages[],
- int effectCnt,
- const GrGLProgramDesc::EffectKeyProvider& keyProvider,
- GrGLSLExpr4* inOutFSColor) {
-
- GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt);
- this->INHERITED::createAndEmitEffects(&programEffectsBuilder,
- effectStages,
- effectCnt,
- keyProvider,
- inOutFSColor);
- return programEffectsBuilder.finish();
-}
-
-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);
- this->appendDecls(fVSAttrs, &vertShaderSrc);
- this->appendDecls(fVSOutputs, &vertShaderSrc);
- vertShaderSrc.append("void main() {\n");
- vertShaderSrc.append(fVSCode);
- vertShaderSrc.append("}\n");
- GrGLuint vertShaderId = attach_shader(glCtx, programId, GR_GL_VERTEX_SHADER, vertShaderSrc);
- if (!vertShaderId) {
- return false;
- }
- *shaderIds->append() = vertShaderId;
-
-#if GR_GL_EXPERIMENTAL_GS
- if (this->desc().getHeader().fExperimentalGS) {
- SkASSERT(this->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration);
- SkString geomShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
- geomShaderSrc.append("layout(triangles) in;\n"
- "layout(triangle_strip, max_vertices = 6) out;\n");
- this->appendDecls(fGSInputs, &geomShaderSrc);
- this->appendDecls(fGSOutputs, &geomShaderSrc);
- 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 (this->desc().getHeader().fEmitsPointSize) {
- geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n");
- }
- SkASSERT(fGSInputs.count() == fGSOutputs.count());
- for (int i = 0; i < fGSInputs.count(); ++i) {
- geomShaderSrc.appendf("\t\t%s = %s[i];\n",
- fGSOutputs[i].getName().c_str(),
- fGSInputs[i].getName().c_str());
- }
- geomShaderSrc.append("\t\tEmitVertex();\n"
- "\t}\n"
- "\tEndPrimitive();\n");
- geomShaderSrc.append("}\n");
- GrGLuint geomShaderId = attach_shader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc);
- if (!geomShaderId) {
- return false;
- }
- *shaderIds->append() = geomShaderId;
- }
-#endif
-
- return this->INHERITED::compileAndAttachShaders(programId, shaderIds);
-}
-
-void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) {
- this->INHERITED::bindProgramLocations(programId);
-
- const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
-
- // Bind the attrib locations to same values for all shaders
- SkASSERT(-1 != header.fPositionAttributeIndex);
- GL_CALL(BindAttribLocation(programId,
- header.fPositionAttributeIndex,
- fPositionVar->c_str()));
- if (-1 != header.fLocalCoordAttributeIndex) {
- GL_CALL(BindAttribLocation(programId,
- header.fLocalCoordAttributeIndex,
- fLocalCoordsVar->c_str()));
- }
- if (-1 != header.fColorAttributeIndex) {
- GL_CALL(BindAttribLocation(programId,
- header.fColorAttributeIndex,
- color_attribute_name()));
- }
- if (-1 != header.fCoverageAttributeIndex) {
- GL_CALL(BindAttribLocation(programId,
- header.fCoverageAttributeIndex,
- coverage_attribute_name()));
- }
-
- const AttributePair* attribEnd = fEffectAttributes.end();
- for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attribEnd; ++attrib) {
- GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_str()));
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu,
- const GrGLProgramDesc& desc)
- : INHERITED(gpu, desc) {
- SkASSERT(!desc.getHeader().fHasVertexCode);
- 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 = fTexCoordSetCnt;
- fTexCoordSetCnt += count;
- SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fTexCoordSetCnt);
- return firstFreeCoordSet;
-}
-
-GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects(
- const GrEffectStage* effectStages[],
- int effectCnt,
- const GrGLProgramDesc::EffectKeyProvider& keyProvider,
- GrGLSLExpr4* inOutFSColor) {
-
- GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this,
- effectCnt);
- this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder,
- effectStages,
- effectCnt,
- keyProvider,
- inOutFSColor);
- return pathTexGenEffectsBuilder.finish();
-}
diff --git a/src/gpu/gl/GrGLVertexEffect.h b/src/gpu/gl/GrGLVertexEffect.h
index eba1fbe795..2e82fbc4d7 100644
--- a/src/gpu/gl/GrGLVertexEffect.h
+++ b/src/gpu/gl/GrGLVertexEffect.h
@@ -24,27 +24,27 @@ public:
* This is similar to emitCode() in the base class, except it takes a full shader builder.
* This allows the effect subclass to emit vertex code.
*/
- virtual void emitCode(GrGLFullShaderBuilder* builder,
+ virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) = 0;
-
/**
* Provide a default override for base class's emitCode() function.
*/
- virtual void emitCode(GrGLShaderBuilder* builder,
+ virtual void emitCode(GrGLProgramBuilder* builder,
const GrDrawEffect& drawEffect,
const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) SK_OVERRIDE {
- SkFAIL("GrGLVertexEffect requires GrGLFullShaderBuilder* overload for emitCode().");
+ SkFAIL("GrGLVertexEffect requires GrGLFullProgramBuilder* overload for emitCode().");
}
+
private:
typedef GrGLEffect INHERITED;
};
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 418f591301..3c22d17b64 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -8,7 +8,6 @@
#include "GrGpuGL.h"
#include "GrGLStencilBuffer.h"
-#include "GrGLShaderBuilder.h"
#include "GrTemplates.h"
#include "GrTypes.h"
#include "SkStrokeRec.h"
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
new file mode 100644
index 0000000000..d216a18c25
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLFragmentShaderBuilder.h"
+#include "GrGLShaderStringBuilder.h"
+#include "GrGLProgramBuilder.h"
+#include "../GrGpuGL.h"
+
+namespace {
+#define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
+#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X)
+// ES2 FS only guarantees mediump and lowp support
+static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
+static const char kDstCopyColorName[] = "_dstColor";
+inline const char* declared_color_output_name() { return "fsColorOut"; }
+inline const char* dual_source_output_name() { return "dualSourceOut"; }
+inline void append_default_precision_qualifier(GrGLShaderVar::Precision p,
+ GrGLStandard standard,
+ SkString* str) {
+ // Desktop GLSL has added precision qualifiers but they don't do anything.
+ if (kGLES_GrGLStandard == standard) {
+ switch (p) {
+ case GrGLShaderVar::kHigh_Precision:
+ str->append("precision highp float;\n");
+ break;
+ case GrGLShaderVar::kMedium_Precision:
+ str->append("precision mediump float;\n");
+ break;
+ case GrGLShaderVar::kLow_Precision:
+ str->append("precision lowp float;\n");
+ break;
+ case GrGLShaderVar::kDefault_Precision:
+ SkFAIL("Default precision now allowed.");
+ default:
+ SkFAIL("Unknown precision value.");
+ }
+ }
+}
+}
+
+GrGLFragmentShaderBuilder::DstReadKey GrGLFragmentShaderBuilder::KeyForDstRead(
+ const GrTexture* dstCopy, const GrGLCaps& caps) {
+ uint32_t key = kYesDstRead_DstReadKeyBit;
+ if (caps.fbFetchSupport()) {
+ return key;
+ }
+ SkASSERT(NULL != dstCopy);
+ if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->config())) {
+ // The fact that the config is alpha-only must be considered when generating code.
+ key |= kUseAlphaConfig_DstReadKeyBit;
+ }
+ if (kTopLeft_GrSurfaceOrigin == dstCopy->origin()) {
+ key |= kTopLeftOrigin_DstReadKeyBit;
+ }
+ SkASSERT(static_cast<DstReadKey>(key) == key);
+ return static_cast<DstReadKey>(key);
+}
+
+GrGLFragmentShaderBuilder::FragPosKey GrGLFragmentShaderBuilder::KeyForFragmentPosition(
+ const GrRenderTarget* dst, const GrGLCaps&) {
+ if (kTopLeft_GrSurfaceOrigin == dst->origin()) {
+ return kTopLeftFragPosRead_FragPosKey;
+ } else {
+ return kBottomLeftFragPosRead_FragPosKey;
+ }
+}
+
+GrGLFragmentShaderBuilder::GrGLFragmentShaderBuilder(GrGLProgramBuilder* program,
+ const GrGLProgramDesc& desc)
+ : INHERITED(program)
+ , fHasCustomColorOutput(false)
+ , fHasSecondaryOutput(false)
+ , fSetupFragPosition(false)
+ , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey){
+}
+
+const char* GrGLFragmentShaderBuilder::dstColor() {
+ if (fProgramBuilder->fCodeStage.inStageCode()) {
+ const GrEffect* effect = fProgramBuilder->fCodeStage.effectStage()->getEffect();
+ if (!effect->willReadDstColor()) {
+ SkDEBUGFAIL("GrGLEffect asked for dst color but its generating GrEffect "
+ "did not request access.");
+ return "";
+ }
+ }
+
+ GrGpuGL* gpu = fProgramBuilder->gpu();
+ if (gpu->glCaps().fbFetchSupport()) {
+ this->addFeature(1 << (GrGLFragmentShaderBuilder::kLastGLSLPrivateFeature + 1),
+ gpu->glCaps().fbFetchExtensionString());
+ return gpu->glCaps().fbFetchColorName();
+ } else if (fProgramBuilder->fUniformHandles.fDstCopySamplerUni.isValid()) {
+ return kDstCopyColorName;
+ } else {
+ return "";
+ }
+}
+
+bool GrGLFragmentShaderBuilder::enableFeature(GLSLFeature feature) {
+ switch (feature) {
+ case kStandardDerivatives_GLSLFeature: {
+ GrGpuGL* gpu = fProgramBuilder->gpu();
+ if (!gpu->glCaps().shaderDerivativeSupport()) {
+ return false;
+ }
+ if (kGLES_GrGLStandard == gpu->glStandard()) {
+ this->addFeature(1 << kStandardDerivatives_GLSLFeature,
+ "GL_OES_standard_derivatives");
+ }
+ return true;
+ }
+ default:
+ SkFAIL("Unexpected GLSLFeature requested.");
+ return false;
+ }
+}
+
+SkString GrGLFragmentShaderBuilder::ensureFSCoords2D(const TransformedCoordsArray& coords, int index) {
+ if (kVec3f_GrSLType != coords[index].type()) {
+ SkASSERT(kVec2f_GrSLType == coords[index].type());
+ return coords[index].getName();
+ }
+
+ SkString coords2D("coords2D");
+ if (0 != index) {
+ coords2D.appendf("_%i", index);
+ }
+ this->codeAppendf("\tvec2 %s = %s.xy / %s.z;",
+ coords2D.c_str(), coords[index].c_str(), coords[index].c_str());
+ return coords2D;
+}
+
+const char* GrGLFragmentShaderBuilder::fragmentPosition() {
+ GrGLProgramBuilder::CodeStage* cs = &fProgramBuilder->fCodeStage;
+ if (cs->inStageCode()) {
+ const GrEffect* effect = cs->effectStage()->getEffect();
+ if (!effect->willReadFragmentPosition()) {
+ SkDEBUGFAIL("GrGLEffect asked for frag position but its generating GrEffect "
+ "did not request access.");
+ return "";
+ }
+ }
+
+ GrGpuGL* gpu = fProgramBuilder->gpu();
+ // 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) {
+ fSetupFragPosition = true;
+ return "gl_FragCoord";
+ } else if (gpu->glCaps().fragCoordConventionsSupport()) {
+ if (!fSetupFragPosition) {
+ if (gpu->glslGeneration() < k150_GrGLSLGeneration) {
+ this->addFeature(1 << kFragCoordConventions_GLSLPrivateFeature,
+ "GL_ARB_fragment_coord_conventions");
+ }
+ fInputs.push_back().set(kVec4f_GrSLType,
+ GrGLShaderVar::kIn_TypeModifier,
+ "gl_FragCoord",
+ GrGLShaderVar::kDefault_Precision,
+ GrGLShaderVar::kUpperLeft_Origin);
+ fSetupFragPosition = true;
+ }
+ return "gl_FragCoord";
+ } else {
+ static const char* kCoordName = "fragCoordYDown";
+ if (!fSetupFragPosition) {
+ // temporarily change the stage index because we're inserting non-stage code.
+ GrGLProgramBuilder::CodeStage::AutoStageRestore csar(cs, NULL);
+
+ SkASSERT(!fProgramBuilder->fUniformHandles.fRTHeightUni.isValid());
+ const char* rtHeightName;
+
+ fProgramBuilder->fUniformHandles.fRTHeightUni =
+ fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kFloat_GrSLType,
+ "RTHeight",
+ &rtHeightName);
+
+ // Using glFragCoord.zw for the last two components tickles an Adreno driver bug that
+ // causes programs to fail to link. Making this function return a vec2() didn't fix the
+ // problem but using 1.0 for the last two components does.
+ this->codePrependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, 1.0, "
+ "1.0);\n", kCoordName, rtHeightName);
+ fSetupFragPosition = true;
+ }
+ SkASSERT(fProgramBuilder->fUniformHandles.fRTHeightUni.isValid());
+ return kCoordName;
+ }
+}
+
+void GrGLFragmentShaderBuilder::addVarying(GrSLType type,
+ const char* name,
+ const char** fsInName) {
+ fInputs.push_back().set(type, GrGLShaderVar::kVaryingIn_TypeModifier, name);
+ if (fsInName) {
+ *fsInName = name;
+ }
+}
+
+void GrGLFragmentShaderBuilder::bindProgramLocations(GrGLuint programId) {
+ GrGpuGL* gpu = fProgramBuilder->gpu();
+ if (fHasCustomColorOutput) {
+ GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name()));
+ }
+ if (fHasSecondaryOutput) {
+ GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_name()));
+ }
+}
+
+bool GrGLFragmentShaderBuilder::compileAndAttachShaders(GrGLuint programId,
+ SkTDArray<GrGLuint>* shaderIds) const {
+ GrGpuGL* gpu = fProgramBuilder->gpu();
+ SkString fragShaderSrc(GrGetGLSLVersionDecl(gpu->ctxInfo()));
+ fragShaderSrc.append(fExtensions);
+ append_default_precision_qualifier(kDefaultFragmentPrecision,
+ gpu->glStandard(),
+ &fragShaderSrc);
+ fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kFragment_Visibility, &fragShaderSrc);
+ fProgramBuilder->appendDecls(fInputs, &fragShaderSrc);
+ // We shouldn't have declared outputs on 1.10
+ SkASSERT(k110_GrGLSLGeneration != gpu->glslGeneration() || fOutputs.empty());
+ fProgramBuilder->appendDecls(fOutputs, &fragShaderSrc);
+ fragShaderSrc.append(fFunctions);
+ fragShaderSrc.append("void main() {\n");
+ fragShaderSrc.append(fCode);
+ fragShaderSrc.append("}\n");
+
+ GrGLuint fragShaderId = GrGLCompileAndAttachShader(gpu->glContext(),
+ programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc);
+ if (!fragShaderId) {
+ return false;
+ }
+
+ *shaderIds->append() = fragShaderId;
+
+ return true;
+}
+
+void GrGLFragmentShaderBuilder::emitCodeBeforeEffects() {
+ const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->desc().getHeader();
+ GrGpuGL* gpu = fProgramBuilder->gpu();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // emit code to read the dst copy texture, if necessary
+ if (kNoDstRead_DstReadKey != header.fDstReadKey && !gpu->glCaps().fbFetchSupport()) {
+ 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;
+ }
+ fProgramBuilder->fUniformHandles.fDstCopySamplerUni =
+ fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kSampler2D_GrSLType,
+ "DstCopySampler",
+ &dstCopySamplerName);
+ fProgramBuilder->fUniformHandles.fDstCopyTopLeftUni =
+ fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kVec2f_GrSLType,
+ "DstCopyUpperLeft",
+ &dstCopyTopLeftName);
+ fProgramBuilder->fUniformHandles.fDstCopyScaleUni =
+ fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kVec2f_GrSLType,
+ "DstCopyCoordScale",
+ &dstCopyCoordScaleName);
+ const char* fragPos = fragmentPosition();
+
+ this->codeAppend("// Read color from copy of the destination.\n");
+ this->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
+ fragPos, dstCopyTopLeftName, dstCopyCoordScaleName);
+ if (!topDown) {
+ this->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
+ }
+ this->codeAppendf("vec4 %s = ", kDstCopyColorName);
+ this->appendTextureLookup(dstCopySamplerName,
+ "_dstTexCoord",
+ configMask,
+ "rgba");
+ this->codeAppend(";");
+ }
+
+ if (k110_GrGLSLGeneration != gpu->glslGeneration()) {
+ fOutputs.push_back().set(kVec4f_GrSLType,
+ GrGLShaderVar::kOut_TypeModifier,
+ declared_color_output_name());
+ fHasCustomColorOutput = true;
+ }
+}
+
+void GrGLFragmentShaderBuilder::emitCodeAfterEffects(const GrGLSLExpr4& inputColor, const GrGLSLExpr4& inputCoverage) {
+ const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->desc().getHeader();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // 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.
+ codeAppendf("\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(dstColor());
+
+ fragColor = fragColor + dstContribution;
+ }
+ codeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str());
+}
+
+const char* GrGLFragmentShaderBuilder::enableSecondaryOutput() {
+ if (!fHasSecondaryOutput) {
+ fOutputs.push_back().set(kVec4f_GrSLType,
+ GrGLShaderVar::kOut_TypeModifier,
+ dual_source_output_name());
+ fHasSecondaryOutput = true;
+ }
+ return dual_source_output_name();
+}
+
+const char* GrGLFragmentShaderBuilder::getColorOutputName() const {
+ return fHasCustomColorOutput ? declared_color_output_name() : "gl_FragColor";
+}
+
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
new file mode 100644
index 0000000000..0f700bd94d
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLFragmentShaderBuilder_DEFINED
+#define GrGLFragmentShaderBuilder_DEFINED
+#include "GrGLShaderBuilder.h"
+
+class GrGLProgramBuilder;
+
+class GrGLFragmentShaderBuilder : public GrGLShaderBuilder {
+public:
+ typedef uint8_t DstReadKey;
+ typedef uint8_t FragPosKey;
+
+ /** Returns a key for adding code to read the copy-of-dst color in service of effects that
+ require reading the dst. It must not return 0 because 0 indicates that there is no dst
+ copy read at all (in which case this function should not be called). */
+ static DstReadKey KeyForDstRead(const GrTexture* dstCopy, 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&);
+
+ GrGLFragmentShaderBuilder(GrGLProgramBuilder* program, const GrGLProgramDesc& desc);
+
+ /** Returns the variable name that holds the color of the destination pixel. This may be NULL if
+ no effect advertised that it will read the destination. */
+ const char* dstColor();
+
+ /**
+ * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
+ * if code is added that uses one of these features without calling enableFeature()
+ */
+ enum GLSLFeature {
+ kStandardDerivatives_GLSLFeature = 0,
+ kLastGLSLFeature = kStandardDerivatives_GLSLFeature
+ };
+
+ /**
+ * If the feature is supported then true is returned and any necessary #extension declarations
+ * are added to the shaders. If the feature is not supported then false will be returned.
+ */
+ bool enableFeature(GLSLFeature);
+
+ /**
+ * This returns a variable name to access the 2D, perspective correct version of the coords in
+ * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
+ * perspective divide into the fragment shader (xy / z) to convert them to 2D.
+ */
+ SkString ensureFSCoords2D(const TransformedCoordsArray& coords, int index);
+
+
+ /** Returns a variable name that represents the position of the fragment in the FS. The position
+ is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
+ const char* fragmentPosition();
+
+private:
+ /*
+ * An internal call for GrGLFullProgramBuilder to use to add varyings to the vertex shader
+ */
+ void addVarying(GrSLType type,
+ const char* name,
+ const char** fsInName);
+
+ /*
+ * Private functions used by GrGLProgramBuilder for compilation
+ */
+ void bindProgramLocations(GrGLuint programId);
+ bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
+ void emitCodeBeforeEffects();
+ void emitCodeAfterEffects(const GrGLSLExpr4& inputColor, const GrGLSLExpr4& inputCoverage);
+
+ /** Enables using the secondary color output and returns the name of the var in which it is
+ to be stored */
+ const char* enableSecondaryOutput();
+
+ /** Gets the name of the primary color output. */
+ const char* getColorOutputName() const;
+
+ /**
+ * Features that should only be enabled by GrGLFragmentShaderBuilder itself.
+ */
+ enum GLSLPrivateFeature {
+ kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
+ kLastGLSLPrivateFeature = kFragCoordConventions_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.
+ };
+
+ enum {
+ kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed.
+ kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to top-left.
+ kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left.
+ };
+
+ bool fHasCustomColorOutput;
+ bool fHasSecondaryOutput;
+ bool fSetupFragPosition;
+ bool fTopLeftFragPosRead;
+
+ friend class GrGLProgramBuilder;
+ friend class GrGLFullProgramBuilder;
+
+ typedef GrGLShaderBuilder INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp
new file mode 100644
index 0000000000..6cdf2f93e0
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLGeometryShaderBuilder.h"
+#include "GrGLShaderStringBuilder.h"
+#include "GrGLProgramBuilder.h"
+#include "../GrGpuGL.h"
+
+GrGLGeometryShaderBuilder::GrGLGeometryShaderBuilder(GrGLFullProgramBuilder* program)
+ : INHERITED(program) {
+
+}
+
+void GrGLGeometryShaderBuilder::addVarying(GrSLType type,
+ const char* name,
+ const char** gsOutName) {
+ // if we have a GS take each varying in as an array
+ // and output as non-array.
+ fInputs.push_back();
+ fInputs.back().setType(type);
+ fInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier);
+ fInputs.back().setUnsizedArray();
+ *fInputs.back().accessName() = name;
+ fOutputs.push_back();
+ fOutputs.back().setType(type);
+ fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
+ fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'g', name);
+ if (gsOutName) {
+ *gsOutName = fOutputs.back().getName().c_str();
+ }
+}
+
+
+bool GrGLGeometryShaderBuilder::compileAndAttachShaders(GrGLuint programId,
+ SkTDArray<GrGLuint>* shaderIds) const {
+ const GrGLContext& glCtx = fProgramBuilder->gpu()->glContext();
+ SkASSERT(fProgramBuilder->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration);
+ SkString geomShaderSrc(GrGetGLSLVersionDecl(fProgramBuilder->ctxInfo()));
+ geomShaderSrc.append("layout(triangles) in;\n"
+ "layout(triangle_strip, max_vertices = 6) out;\n");
+ fProgramBuilder->appendDecls(fInputs, &geomShaderSrc);
+ fProgramBuilder->appendDecls(fOutputs, &geomShaderSrc);
+ 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 (fProgramBuilder->desc().getHeader().fEmitsPointSize) {
+ geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n");
+ }
+ SkASSERT(fInputs.count() == fOutputs.count());
+ for (int i = 0; i < fInputs.count(); ++i) {
+ geomShaderSrc.appendf("\t\t%s = %s[i];\n",
+ fOutputs[i].getName().c_str(),
+ fInputs[i].getName().c_str());
+ }
+ geomShaderSrc.append("\t\tEmitVertex();\n"
+ "\t}\n"
+ "\tEndPrimitive();\n");
+ geomShaderSrc.append("}\n");
+ GrGLuint geomShaderId =
+ GrGLCompileAndAttachShader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc);
+ if (!geomShaderId) {
+ return false;
+ }
+ *shaderIds->append() = geomShaderId;
+ return true;
+}
diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h
new file mode 100644
index 0000000000..833d31774f
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLGeometryShaderBuilder_DEFINED
+#define GrGLGeometryShaderBuilder_DEFINED
+
+#include "GrGLShaderBuilder.h"
+
+class GrGLProgramBuilder;
+
+class GrGLGeometryShaderBuilder : public GrGLFullShaderBuilder {
+public:
+ GrGLGeometryShaderBuilder(GrGLFullProgramBuilder* program);
+private:
+ /*
+ * an internal call for GrGLFullProgramBuilder to add varyings
+ */
+ void addVarying(GrSLType type,
+ const char* name,
+ const char** gsOutName);
+
+ bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
+
+ friend class GrGLFullProgramBuilder;
+ typedef GrGLFullShaderBuilder INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
new file mode 100644
index 0000000000..f4ee32b48d
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -0,0 +1,409 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gl/GrGLProgram.h"
+#include "gl/GrGLSLPrettyPrint.h"
+#include "gl/GrGLUniformHandle.h"
+#include "GrCoordTransform.h"
+#include "GrDrawEffect.h"
+#include "../GrGpuGL.h"
+#include "GrGLFragmentShaderBuilder.h"
+#include "GrGLProgramBuilder.h"
+#include "GrTexture.h"
+#include "GrGLVertexShaderBuilder.h"
+#include "SkRTConf.h"
+#include "SkTraceEvent.h"
+
+namespace {
+#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)
+
+// number of each input/output type in a single allocation block
+static const int kVarsPerBlock = 8;
+
+// ES2 FS only guarantees mediump and lowp support
+static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool GrGLProgramBuilder::genProgram(const GrEffectStage* colorStages[],
+ const GrEffectStage* coverageStages[]) {
+ const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
+
+ fFS.emitCodeBeforeEffects();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // 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;
+ fUniformHandles.fColorUni =
+ this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kVec4f_GrSLType,
+ "Color",
+ &name);
+ inputColor = GrGLSLExpr4(name);
+ }
+
+ if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
+ const char* name;
+ fUniformHandles.fCoverageUni =
+ this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kVec4f_GrSLType,
+ "Coverage",
+ &name);
+ inputCoverage = GrGLSLExpr4(name);
+ } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) {
+ inputCoverage = GrGLSLExpr4(1);
+ }
+
+ this->emitCodeBeforeEffects(&inputColor, &inputCoverage);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // emit the per-effect code for both color and coverage effects
+
+ GrGLProgramDesc::EffectKeyProvider colorKeyProvider(
+ &this->desc(), GrGLProgramDesc::EffectKeyProvider::kColor_EffectType);
+ fColorEffects.reset(this->createAndEmitEffects(colorStages,
+ this->desc().numColorEffects(),
+ colorKeyProvider,
+ &inputColor));
+
+ GrGLProgramDesc::EffectKeyProvider coverageKeyProvider(
+ &this->desc(), GrGLProgramDesc::EffectKeyProvider::kCoverage_EffectType);
+ fCoverageEffects.reset(this->createAndEmitEffects(coverageStages,
+ this->desc().numCoverageEffects(),
+ coverageKeyProvider,
+ &inputCoverage));
+
+ this->emitCodeAfterEffects();
+
+ fFS.emitCodeAfterEffects(inputColor, inputCoverage);
+
+ if (!this->finish()) {
+ return false;
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
+ const GrGLProgramDesc& desc)
+ : fFragOnly(!desc.getHeader().fHasVertexCode && gpu->shouldUseFixedFunctionTexturing())
+ , fTexCoordSetCnt(0)
+ , fProgramID(0)
+ , fFS(this, desc)
+ , fDesc(desc)
+ , fGpu(gpu)
+ , fUniforms(kVarsPerBlock) {
+}
+
+void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) {
+ if ('\0' == prefix) {
+ *out = name;
+ } else {
+ out->printf("%c%s", prefix, name);
+ }
+ if (fCodeStage.inStageCode()) {
+ if (out->endsWith('_')) {
+ // Names containing "__" are reserved.
+ out->append("x");
+ }
+ out->appendf("_Stage%d", fCodeStage.stageIndex());
+ }
+}
+
+GrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(uint32_t visibility,
+ GrSLType type,
+ const char* name,
+ int count,
+ const char** outName) {
+ SkASSERT(name && strlen(name));
+ SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFragment_Visibility);
+ SkASSERT(0 == (~kVisibilityMask & visibility));
+ SkASSERT(0 != visibility);
+
+ UniformInfo& uni = fUniforms.push_back();
+ uni.fVariable.setType(type);
+ uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
+ this->nameVariable(uni.fVariable.accessName(), 'u', name);
+ uni.fVariable.setArrayCount(count);
+ uni.fVisibility = visibility;
+
+ // If it is visible in both the VS and FS, the precision must match.
+ // We declare a default FS precision, but not a default VS. So set the var
+ // to use the default FS precision.
+ if ((kVertex_Visibility | kFragment_Visibility) == visibility) {
+ // the fragment and vertex precisions must match
+ uni.fVariable.setPrecision(kDefaultFragmentPrecision);
+ }
+
+ if (NULL != outName) {
+ *outName = uni.fVariable.c_str();
+ }
+ return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fUniforms.count() - 1);
+}
+
+void GrGLProgramBuilder::appendDecls(const VarArray& vars, SkString* out) const {
+ for (int i = 0; i < vars.count(); ++i) {
+ vars[i].appendDecl(this->ctxInfo(), out);
+ out->append(";\n");
+ }
+}
+
+void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility,
+ SkString* out) const {
+ for (int i = 0; i < fUniforms.count(); ++i) {
+ if (fUniforms[i].fVisibility & visibility) {
+ fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out);
+ out->append(";\n");
+ }
+ }
+}
+
+void GrGLProgramBuilder::createAndEmitEffects(GrGLProgramEffectsBuilder* programEffectsBuilder,
+ const GrEffectStage* effectStages[],
+ int effectCnt,
+ const GrGLProgramDesc::EffectKeyProvider& keyProvider,
+ GrGLSLExpr4* fsInOutColor) {
+ bool effectEmitted = false;
+
+ GrGLSLExpr4 inColor = *fsInOutColor;
+ GrGLSLExpr4 outColor;
+
+ for (int e = 0; e < effectCnt; ++e) {
+ SkASSERT(NULL != effectStages[e] && NULL != effectStages[e]->getEffect());
+ const GrEffectStage& stage = *effectStages[e];
+
+ CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
+
+ if (inColor.isZeros()) {
+ SkString inColorName;
+
+ // Effects have no way to communicate zeros, they treat an empty string as ones.
+ this->nameVariable(&inColorName, '\0', "input");
+ fFS.codeAppendf("\tvec4 %s = %s;\n", inColorName.c_str(), inColor.c_str());
+ inColor = inColorName;
+ }
+
+ // create var to hold stage result
+ SkString outColorName;
+ this->nameVariable(&outColorName, '\0', "output");
+ fFS.codeAppendf("\tvec4 %s;\n", outColorName.c_str());
+ outColor = outColorName;
+
+
+ programEffectsBuilder->emitEffect(stage,
+ keyProvider.get(e),
+ outColor.c_str(),
+ inColor.isOnes() ? NULL : inColor.c_str(),
+ fCodeStage.stageIndex());
+
+ inColor = outColor;
+ effectEmitted = true;
+ }
+
+ if (effectEmitted) {
+ *fsInOutColor = outColor;
+ }
+}
+
+bool GrGLProgramBuilder::finish() {
+ SkASSERT(0 == fProgramID);
+ GL_CALL_RET(fProgramID, CreateProgram());
+ if (!fProgramID) {
+ return false;
+ }
+
+ SkTDArray<GrGLuint> shadersToDelete;
+
+ if (!this->compileAndAttachShaders(fProgramID, &shadersToDelete)) {
+ GL_CALL(DeleteProgram(fProgramID));
+ return false;
+ }
+
+ this->bindProgramLocations(fProgramID);
+
+ GL_CALL(LinkProgram(fProgramID));
+
+ // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
+ bool checkLinked = !fGpu->ctxInfo().isChromium();
+#ifdef SK_DEBUG
+ checkLinked = true;
+#endif
+ if (checkLinked) {
+ GrGLint linked = GR_GL_INIT_ZERO;
+ GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked));
+ if (!linked) {
+ GrGLint infoLen = GR_GL_INIT_ZERO;
+ GL_CALL(GetProgramiv(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(fProgramID,
+ infoLen+1,
+ &length,
+ (char*)log.get()));
+ GrPrintf((char*)log.get());
+ }
+ SkDEBUGFAIL("Error linking program");
+ GL_CALL(DeleteProgram(fProgramID));
+ fProgramID = 0;
+ return false;
+ }
+ }
+
+ this->resolveProgramLocations(fProgramID);
+
+ for (int i = 0; i < shadersToDelete.count(); ++i) {
+ GL_CALL(DeleteShader(shadersToDelete[i]));
+ }
+
+ return true;
+}
+
+bool GrGLProgramBuilder::compileAndAttachShaders(GrGLuint programId,
+ SkTDArray<GrGLuint>* shaderIds) const {
+ return fFS.compileAndAttachShaders(programId, shaderIds);
+}
+
+void GrGLProgramBuilder::bindProgramLocations(GrGLuint programId) {
+ fFS.bindProgramLocations(programId);
+
+ // skbug.com/2056
+ bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
+ if (usingBindUniform) {
+ int count = fUniforms.count();
+ for (int i = 0; i < count; ++i) {
+ GL_CALL(BindUniformLocation(programId, i, fUniforms[i].fVariable.c_str()));
+ fUniforms[i].fLocation = i;
+ }
+ }
+}
+
+void GrGLProgramBuilder::resolveProgramLocations(GrGLuint programId) {
+ bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
+ if (!usingBindUniform) {
+ int count = fUniforms.count();
+ for (int i = 0; i < count; ++i) {
+ GrGLint location;
+ GL_CALL_RET(location,
+ GetUniformLocation(programId, fUniforms[i].fVariable.c_str()));
+ fUniforms[i].fLocation = location;
+ }
+ }
+}
+
+const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
+ return fGpu->ctxInfo();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrGLFullProgramBuilder::GrGLFullProgramBuilder(GrGpuGL* gpu,
+ const GrGLProgramDesc& desc)
+ : INHERITED(gpu, desc)
+ , fGS(this)
+ , fVS(this) {
+}
+
+void GrGLFullProgramBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) {
+ fVS.emitCodeBeforeEffects(color, coverage);
+}
+
+void GrGLFullProgramBuilder::emitCodeAfterEffects() {
+ fVS.emitCodeAfterEffects();
+}
+
+void GrGLFullProgramBuilder::addVarying(GrSLType type,
+ const char* name,
+ const char** vsOutName,
+ const char** fsInName) {
+ fVS.addVarying(type, name, vsOutName);
+
+ SkString* fsInputName = fVS.fOutputs.back().accessName();
+
+#if GR_GL_EXPERIMENTAL_GS
+ if (desc().getHeader().fExperimentalGS) {
+ // TODO let the caller use these names
+ fGS.addVarying(type, fsInputName->c_str(), NULL);
+ fsInputName = fGS.fOutputs.back().accessName();
+ }
+#endif
+ fFS.addVarying(type, fsInputName->c_str(), fsInName);
+}
+
+GrGLProgramEffects* GrGLFullProgramBuilder::createAndEmitEffects(
+ const GrEffectStage* effectStages[],
+ int effectCnt,
+ const GrGLProgramDesc::EffectKeyProvider& keyProvider,
+ GrGLSLExpr4* inOutFSColor) {
+
+ GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt);
+ this->INHERITED::createAndEmitEffects(&programEffectsBuilder,
+ effectStages,
+ effectCnt,
+ keyProvider,
+ inOutFSColor);
+ return programEffectsBuilder.finish();
+}
+
+bool GrGLFullProgramBuilder::compileAndAttachShaders(GrGLuint programId,
+ SkTDArray<GrGLuint>* shaderIds) const {
+ return INHERITED::compileAndAttachShaders(programId, shaderIds)
+ && fVS.compileAndAttachShaders(programId, shaderIds)
+#if GR_GL_EXPERIMENTAL_GS
+ && (!desc().getHeader().fExperimentalGS
+ || fGS.compileAndAttachShaders(programId, shaderIds))
+#endif
+ ;
+}
+
+void GrGLFullProgramBuilder::bindProgramLocations(GrGLuint programId) {
+ fVS.bindProgramLocations(programId);
+ INHERITED::bindProgramLocations(programId);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrGLFragmentOnlyProgramBuilder::GrGLFragmentOnlyProgramBuilder(GrGpuGL* gpu,
+ const GrGLProgramDesc& desc)
+ : INHERITED(gpu, desc) {
+ SkASSERT(!desc.getHeader().fHasVertexCode);
+ SkASSERT(gpu->glCaps().pathRenderingSupport());
+ SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput);
+ SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput);
+}
+
+int GrGLFragmentOnlyProgramBuilder::addTexCoordSets(int count) {
+ int firstFreeCoordSet = fTexCoordSetCnt;
+ fTexCoordSetCnt += count;
+ SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fTexCoordSetCnt);
+ return firstFreeCoordSet;
+}
+
+GrGLProgramEffects* GrGLFragmentOnlyProgramBuilder::createAndEmitEffects(
+ const GrEffectStage* effectStages[], int effectCnt,
+ const GrGLProgramDesc::EffectKeyProvider& keyProvider, GrGLSLExpr4* inOutFSColor) {
+
+ GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this,
+ effectCnt);
+ this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder,
+ effectStages,
+ effectCnt,
+ keyProvider,
+ inOutFSColor);
+ return pathTexGenEffectsBuilder.finish();
+}
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index 2a14a1f625..09f7eba511 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -1,17 +1,20 @@
/*
- * Copyright 2012 Google Inc.
+ * Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
-#ifndef GrGLShaderBuilder_DEFINED
-#define GrGLShaderBuilder_DEFINED
+#ifndef GrGLProgramBuilder_DEFINED
+#define GrGLProgramBuilder_DEFINED
#include "GrAllocator.h"
#include "GrBackendEffectFactory.h"
#include "GrColor.h"
#include "GrEffect.h"
+#include "GrGLFragmentShaderBuilder.h"
+#include "GrGLGeometryShaderBuilder.h"
+#include "GrGLVertexShaderBuilder.h"
#include "SkTypes.h"
#include "gl/GrGLProgramDesc.h"
#include "gl/GrGLProgramEffects.h"
@@ -28,12 +31,8 @@ class GrGLProgramDesc;
Contains all the incremental state of a shader as it is being built,as well as helpers to
manipulate that state.
*/
-class GrGLShaderBuilder {
+class GrGLProgramBuilder {
public:
- typedef GrTAllocator<GrGLShaderVar> VarArray;
- typedef GrGLProgramEffects::TextureSampler TextureSampler;
- typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
-
enum ShaderVisibility {
kVertex_Visibility = 0x1,
kGeometry_Visibility = 0x2,
@@ -89,87 +88,11 @@ public:
return fUniformHandles;
}
GrGLuint getProgramID() const { SkASSERT(fProgramID); return fProgramID; }
- bool hasVertexShader() const { SkASSERT(fProgramID); return fHasVertexShader; }
+ bool hasVertexShader() const { SkASSERT(fProgramID); return !fFragOnly; }
int getTexCoordSetCount() const { SkASSERT(fProgramID); return fTexCoordSetCnt; }
const UniformInfoArray& getUniformInfos() const { return fUniforms; }
- virtual ~GrGLShaderBuilder() {}
-
- /**
- * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
- * if code is added that uses one of these features without calling enableFeature()
- */
- enum GLSLFeature {
- kStandardDerivatives_GLSLFeature = 0,
-
- kLastGLSLFeature = kStandardDerivatives_GLSLFeature
- };
-
- /**
- * If the feature is supported then true is returned and any necessary #extension declarations
- * are added to the shaders. If the feature is not supported then false will be returned.
- */
- bool enableFeature(GLSLFeature);
-
- /**
- * Called by GrGLEffects to add code the fragment shader.
- */
- void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
- va_list args;
- va_start(args, format);
- fFSCode.appendVAList(format, args);
- va_end(args);
- }
-
- void fsCodeAppend(const char* str) { fFSCode.append(str); }
-
- /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
- Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
- order of the result depends on the GrTextureAccess associated with the TextureSampler. */
- void appendTextureLookup(SkString* out,
- const TextureSampler&,
- const char* coordName,
- GrSLType coordType = kVec2f_GrSLType) const;
-
- /** Version of above that appends the result to the fragment shader code instead.*/
- void fsAppendTextureLookup(const TextureSampler&,
- const char* coordName,
- GrSLType coordType = kVec2f_GrSLType);
-
-
- /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
- always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
- float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
- called. */
- void fsAppendTextureLookupAndModulate(const char* modulation,
- const TextureSampler&,
- const char* coordName,
- GrSLType coordType = kVec2f_GrSLType);
-
- /** Emits a helper function outside of main() in the fragment shader. */
- void fsEmitFunction(GrSLType returnType,
- const char* name,
- int argCnt,
- const GrGLShaderVar* args,
- const char* body,
- SkString* outName);
-
- typedef uint8_t DstReadKey;
- typedef uint8_t FragPosKey;
-
- /** Returns a key for adding code to read the copy-of-dst color in service of effects that
- require reading the dst. It must not return 0 because 0 indicates that there is no dst
- copy read at all (in which case this function should not be called). */
- static DstReadKey KeyForDstRead(const GrTexture* dstCopy, 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&);
-
- /** 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);
+ virtual ~GrGLProgramBuilder() {}
/** 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
@@ -200,52 +123,18 @@ public:
return this->getUniformVariable(u).c_str();
}
- /**
- * This returns a variable name to access the 2D, perspective correct version of the coords in
- * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
- * perspective divide into the fragment shader (xy / z) to convert them to 2D.
- */
- SkString ensureFSCoords2D(const TransformedCoordsArray&, int index);
-
- /** Returns a variable name that represents the position of the fragment in the FS. The position
- is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
- const char* fragmentPosition();
-
- /** Returns the variable name that holds the color of the destination pixel. This may be NULL if
- no effect advertised that it will read the destination. */
- const char* dstColor();
-
const GrGLContextInfo& ctxInfo() const;
- /**
- * Helper for begining and ending a block in the fragment code. TODO: Make GrGLShaderBuilder
- * aware of all blocks and turn single \t's into the correct number of tabs (or spaces) so that
- * our shaders print pretty without effect writers tracking indentation.
- */
- class FSBlock {
- public:
- FSBlock(GrGLShaderBuilder* builder) : fBuilder(builder) {
- SkASSERT(NULL != builder);
- fBuilder->fsCodeAppend("\t{\n");
- }
-
- ~FSBlock() {
- fBuilder->fsCodeAppend("\t}\n");
- }
- private:
- GrGLShaderBuilder* fBuilder;
- };
+ GrGLFragmentShaderBuilder* getFragmentShaderBuilder() { return &fFS; }
protected:
- GrGLShaderBuilder(GrGpuGL*, const GrGLProgramDesc&);
+ typedef GrTAllocator<GrGLShaderVar> VarArray;
+ GrGLProgramBuilder(GrGpuGL*, const GrGLProgramDesc&);
GrGpuGL* gpu() const { return fGpu; }
const GrGLProgramDesc& desc() const { return fDesc; }
- /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
- GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
-
// Helper for emitEffects().
void createAndEmitEffects(GrGLProgramEffectsBuilder*,
const GrEffectStage* effectStages[],
@@ -269,9 +158,10 @@ protected:
SkAutoTUnref<GrGLProgramEffects> fColorEffects;
SkAutoTUnref<GrGLProgramEffects> fCoverageEffects;
BuiltinUniformHandles fUniformHandles;
- bool fHasVertexShader;
+ bool fFragOnly;
int fTexCoordSetCnt;
GrGLuint fProgramID;
+ GrGLFragmentShaderBuilder fFS;
private:
class CodeStage : SkNoncopyable {
public:
@@ -351,84 +241,27 @@ private:
*/
virtual void emitCodeAfterEffects() = 0;
- /** Enables using the secondary color output and returns the name of the var in which it is
- to be stored */
- const char* enableSecondaryOutput();
- /** Gets the name of the primary color output. */
- const char* getColorOutputName() const;
-
/**
* Compiles all the shaders, links them into a program, and writes the program id to the output
* struct.
**/
bool finish();
- /**
- * Features that should only be enabled by GrGLShaderBuilder itself.
- */
- enum GLSLPrivateFeature {
- kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
- kLastGLSLPrivateFeature = kFragCoordConventions_GLSLPrivateFeature
- };
- bool enablePrivateFeature(GLSLPrivateFeature);
-
- // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
- // track the enables separately for each shader.
- void addFSFeature(uint32_t featureBit, const char* extensionName);
-
- // 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.
- };
-
- enum {
- kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed.
- kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to top-left.
- kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left.
- };
-
const GrGLProgramDesc& fDesc;
GrGpuGL* fGpu;
- uint32_t fFSFeaturesAddedMask;
- SkString fFSFunctions;
- SkString fFSExtensions;
- VarArray fFSInputs;
- VarArray fFSOutputs;
UniformInfoArray fUniforms;
- SkString fFSCode;
-
- bool fSetupFragPosition;
- bool fTopLeftFragPosRead;
-
- bool fHasCustomColorOutput;
- bool fHasSecondaryOutput;
+ friend class GrGLShaderBuilder;
+ friend class GrGLVertexShaderBuilder;
+ friend class GrGLFragmentShaderBuilder;
+ friend class GrGLGeometryShaderBuilder;
};
////////////////////////////////////////////////////////////////////////////////
-class GrGLFullShaderBuilder : public GrGLShaderBuilder {
+class GrGLFullProgramBuilder : public GrGLProgramBuilder {
public:
- GrGLFullShaderBuilder(GrGpuGL*, const GrGLProgramDesc&);
-
- /**
- * Called by GrGLEffects to add code to one of the shaders.
- */
- void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
- va_list args;
- va_start(args, format);
- fVSCode.appendVAList(format, args);
- va_end(args);
- }
-
- void vsCodeAppend(const char* str) { fVSCode.append(str); }
-
- /** Add a vertex attribute to the current program that is passed in from the vertex data.
- Returns false if the attribute was already there, true otherwise. */
- bool addAttribute(GrSLType type, const char* name);
+ GrGLFullProgramBuilder(GrGpuGL*, const GrGLProgramDesc&);
/** Add a varying variable to the current program to pass values between vertex and fragment
shaders. If the last two parameters are non-NULL, they are filled in with the name
@@ -438,23 +271,7 @@ public:
const char** vsOutName = NULL,
const char** fsInName = NULL);
- /** Returns a vertex attribute that represents the vertex position in the VS. This is the
- pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
- */
- const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
-
- /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
- as positionAttribute() or it may not be. It depends upon whether the rendering code
- specified explicit local coords or not in the GrDrawState. */
- const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
-
- /**
- * Are explicit local coordinates provided as input to the vertex shader.
- */
- bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
-
- bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
- const SkString* getEffectAttributeName(int attributeIndex) const;
+ GrGLVertexShaderBuilder* getVertexShaderBuilder() { return &fVS; }
private:
virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) SK_OVERRIDE;
@@ -471,33 +288,17 @@ private:
virtual void bindProgramLocations(GrGLuint programId) SK_OVERRIDE;
- VarArray fVSAttrs;
- VarArray fVSOutputs;
- VarArray fGSInputs;
- VarArray fGSOutputs;
-
- SkString fVSCode;
-
- struct AttributePair {
- void set(int index, const SkString& name) {
- fIndex = index; fName = name;
- }
- int fIndex;
- SkString fName;
- };
- SkSTArray<10, AttributePair, true> fEffectAttributes;
-
- GrGLShaderVar* fPositionVar;
- GrGLShaderVar* fLocalCoordsVar;
+ GrGLGeometryShaderBuilder fGS;
+ GrGLVertexShaderBuilder fVS;
- typedef GrGLShaderBuilder INHERITED;
+ typedef GrGLProgramBuilder INHERITED;
};
////////////////////////////////////////////////////////////////////////////////
-class GrGLFragmentOnlyShaderBuilder : public GrGLShaderBuilder {
+class GrGLFragmentOnlyProgramBuilder : public GrGLProgramBuilder {
public:
- GrGLFragmentOnlyShaderBuilder(GrGpuGL*, const GrGLProgramDesc&);
+ GrGLFragmentOnlyProgramBuilder(GrGpuGL*, const GrGLProgramDesc&);
int addTexCoordSets(int count);
@@ -511,7 +312,7 @@ private:
virtual void emitCodeAfterEffects() SK_OVERRIDE {}
- typedef GrGLShaderBuilder INHERITED;
+ typedef GrGLProgramBuilder INHERITED;
};
#endif
diff --git a/src/gpu/gl/GrGLSLPrettyPrint.cpp b/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp
index 27f4b44e66..27f4b44e66 100644
--- a/src/gpu/gl/GrGLSLPrettyPrint.cpp
+++ b/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp
diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.cpp b/src/gpu/gl/builders/GrGLShaderBuilder.cpp
new file mode 100644
index 0000000000..4dea142632
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLShaderBuilder.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLShaderBuilder.h"
+#include "GrGLProgramBuilder.h"
+#include "../GrGpuGL.h"
+#include "../GrGLShaderVar.h"
+
+namespace {
+inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) {
+ if (kVec2f_GrSLType == type) {
+ return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D";
+ } else {
+ SkASSERT(kVec3f_GrSLType == type);
+ return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj";
+ }
+}
+void append_texture_lookup(SkString* out,
+ GrGpuGL* gpu,
+ const char* samplerName,
+ const char* coordName,
+ uint32_t configComponentMask,
+ const char* swizzle,
+ GrSLType varyingType = kVec2f_GrSLType) {
+ SkASSERT(NULL != coordName);
+
+ out->appendf("%s(%s, %s)",
+ sample_function_name(varyingType, gpu->glslGeneration()),
+ samplerName,
+ coordName);
+
+ char mangledSwizzle[5];
+
+ // The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle
+ // is available.
+ if (!gpu->glCaps().textureSwizzleSupport() &&
+ (kA_GrColorComponentFlag == configComponentMask)) {
+ char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a';
+ int i;
+ for (i = 0; '\0' != swizzle[i]; ++i) {
+ mangledSwizzle[i] = alphaChar;
+ }
+ mangledSwizzle[i] ='\0';
+ swizzle = mangledSwizzle;
+ }
+ // For shader prettiness we omit the swizzle rather than appending ".rgba".
+ if (memcmp(swizzle, "rgba", 4)) {
+ out->appendf(".%s", swizzle);
+ }
+}
+static const int kVarsPerBlock = 8;
+}
+
+GrGLShaderBuilder::GrGLShaderBuilder(GrGLProgramBuilder* program)
+ : fProgramBuilder(program)
+ , fInputs(kVarsPerBlock)
+ , fOutputs(kVarsPerBlock)
+ , fFeaturesAddedMask(0) {
+}
+
+void GrGLShaderBuilder::emitFunction(GrSLType returnType,
+ const char* name,
+ int argCnt,
+ const GrGLShaderVar* args,
+ const char* body,
+ SkString* outName) {
+ fFunctions.append(GrGLSLTypeString(returnType));
+ fProgramBuilder->nameVariable(outName, '\0', name);
+ fFunctions.appendf(" %s", outName->c_str());
+ fFunctions.append("(");
+ const GrGLContextInfo& ctxInfo = fProgramBuilder->gpu()->ctxInfo();
+ for (int i = 0; i < argCnt; ++i) {
+ args[i].appendDecl(ctxInfo, &fFunctions);
+ if (i < argCnt - 1) {
+ fFunctions.append(", ");
+ }
+ }
+ fFunctions.append(") {\n");
+ fFunctions.append(body);
+ fFunctions.append("}\n\n");
+}
+
+void GrGLShaderBuilder::appendTextureLookup(SkString* out,
+ const TextureSampler& sampler,
+ const char* coordName,
+ GrSLType varyingType) const {
+ append_texture_lookup(out,
+ fProgramBuilder->gpu(),
+ fProgramBuilder->getUniformCStr(sampler.samplerUniform()),
+ coordName,
+ sampler.configComponentMask(),
+ sampler.swizzle(),
+ varyingType);
+}
+
+void GrGLShaderBuilder::appendTextureLookup(const TextureSampler& sampler,
+ const char* coordName,
+ GrSLType varyingType) {
+ this->appendTextureLookup(&fCode, sampler, coordName, varyingType);
+}
+
+void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation,
+ const TextureSampler& sampler,
+ const char* coordName,
+ GrSLType varyingType) {
+ SkString lookup;
+ this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
+ 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)) {
+ fExtensions.appendf("#extension %s: require\n", extensionName);
+ fFeaturesAddedMask |= featureBit;
+ }
+}
+
+void GrGLShaderBuilder::appendTextureLookup(const char* samplerName,
+ const char* coordName,
+ uint32_t configComponentMask,
+ const char* swizzle) {
+ append_texture_lookup(&fCode,
+ fProgramBuilder->gpu(),
+ samplerName,
+ coordName,
+ configComponentMask,
+ swizzle,
+ kVec2f_GrSLType);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGLFullProgramBuilder* program)
+ : INHERITED(program)
+ , fFullProgramBuilder(program) {}
diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.h b/src/gpu/gl/builders/GrGLShaderBuilder.h
new file mode 100644
index 0000000000..1d0fa6a790
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLShaderBuilder.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLShaderBuilder_DEFINED
+#define GrGLShaderBuilder_DEFINED
+
+#include "gl/GrGLProgramDesc.h"
+#include "gl/GrGLProgramEffects.h"
+#include "gl/GrGLSL.h"
+#include "gl/GrGLProgramDataManager.h"
+#include "GrAllocator.h"
+#include "GrBackendEffectFactory.h"
+#include "GrColor.h"
+#include "GrEffect.h"
+#include "SkTypes.h"
+
+#include <stdarg.h>
+
+class GrGLContextInfo;
+class GrEffectStage;
+class GrGLProgramDesc;
+class GrGLProgramBuilder;
+class GrGLFullProgramBuilder;
+
+/**
+ base class for all shaders builders
+*/
+class GrGLShaderBuilder {
+public:
+ typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
+ typedef GrGLProgramEffects::TextureSampler TextureSampler;
+ GrGLShaderBuilder(GrGLProgramBuilder* program);
+
+ void addInput(GrGLShaderVar i) { fInputs.push_back(i); }
+ void addOutput(GrGLShaderVar i) { fOutputs.push_back(i); }
+
+ /*
+ * We put texture lookups in the base class because it is TECHNICALLY possible to do texture
+ * lookups in any kind of shader. However, for the time being using these calls on non-fragment
+ * shaders will result in a shader compilation error as texture sampler uniforms are only
+ * visible to the fragment shader. It would not be hard to change this behavior, if someone
+ * actually wants to do texture lookups in a non-fragment shader
+ *
+ * TODO if append texture lookup is used on a non-fragment shader, sampler uniforms should be
+ * made visible to that shaders
+ */
+ /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
+ Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
+ order of the result depends on the GrTextureAccess associated with the TextureSampler. */
+ void appendTextureLookup(SkString* out,
+ const TextureSampler&,
+ const char* coordName,
+ GrSLType coordType = kVec2f_GrSLType) const;
+
+ /** Version of above that appends the result to the fragment shader code instead.*/
+ void appendTextureLookup(const TextureSampler&,
+ const char* coordName,
+ GrSLType coordType = kVec2f_GrSLType);
+
+
+ /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
+ always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
+ float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
+ called. */
+ void appendTextureLookupAndModulate(const char* modulation,
+ const TextureSampler&,
+ 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 GrGLEffects to add code to one of the shaders.
+ */
+ void codeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
+ va_list args;
+ va_start(args, format);
+ fCode.appendVAList(format, args);
+ va_end(args);
+ }
+
+ void codeAppend(const char* str) { fCode.append(str); }
+
+ void codePrependf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
+ va_list args;
+ va_start(args, format);
+ fCode.prependVAList(format, args);
+ va_end(args);
+ }
+
+ /** Emits a helper function outside of main() in the fragment shader. */
+ void emitFunction(GrSLType returnType,
+ const char* name,
+ int argCnt,
+ const GrGLShaderVar* args,
+ const char* body,
+ SkString* outName);
+
+ /*
+ * Get parent builder for adding uniforms
+ */
+ GrGLProgramBuilder* getProgramBuilder() { return fProgramBuilder; }
+
+ /**
+ * Helper for begining and ending a block in the fragment code.
+ */
+ class ShaderBlock {
+ public:
+ ShaderBlock(GrGLShaderBuilder* builder) : fBuilder(builder) {
+ SkASSERT(NULL != builder);
+ fBuilder->codeAppend("{");
+ }
+
+ ~ShaderBlock() {
+ fBuilder->codeAppend("}");
+ }
+ private:
+ GrGLShaderBuilder* fBuilder;
+ };
+protected:
+
+ /*
+ * this super low level function is just for use internally to builders
+ */
+ void appendTextureLookup(const char* samplerName,
+ const char* coordName,
+ uint32_t configComponentMask,
+ const char* swizzle);
+
+ /*
+ * A general function which enables an extension in a shader if the feature bit is not present
+ */
+ void addFeature(uint32_t featureBit, const char* extensionName);
+
+ typedef GrTAllocator<GrGLShaderVar> VarArray;
+
+ GrGLProgramBuilder* fProgramBuilder;
+
+ SkString fCode;
+ SkString fFunctions;
+ SkString fExtensions;
+
+ VarArray fInputs;
+ VarArray fOutputs;
+ uint32_t fFeaturesAddedMask;
+};
+
+
+/*
+ * Full Shader builder is the base class for shaders which are only accessible through full program
+ * builder, ie vertex, geometry, and later TCU / TES. Using this base class, they can access the
+ * full program builder functionality through the full program pointer
+ */
+class GrGLFullShaderBuilder : public GrGLShaderBuilder {
+public:
+ GrGLFullShaderBuilder(GrGLFullProgramBuilder* program);
+
+ GrGLFullProgramBuilder* fullProgramBuilder() { return fFullProgramBuilder; }
+protected:
+ GrGLFullProgramBuilder* fFullProgramBuilder;
+private:
+ typedef GrGLShaderBuilder INHERITED;
+};
+#endif
diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
new file mode 100644
index 0000000000..dff8c7e684
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLShaderStringBuilder.h"
+#include "../GrGpuGL.h"
+#include "gl/GrGLSLPrettyPrint.h"
+#include "SkRTConf.h"
+#include "SkTraceEvent.h"
+
+#define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
+#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X)
+
+SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
+ "Print the source code for all shaders generated.");
+
+GrGLuint GrGLCompileAndAttachShader(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 0;
+ }
+
+ #ifdef SK_DEBUG
+ SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, false);
+ const GrGLchar* sourceStr = prettySource.c_str();
+ GrGLint sourceLength = static_cast<GrGLint>(prettySource.size());
+ #else
+ GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size());
+ const GrGLchar* sourceStr = shaderSrc.c_str();
+ #endif
+ GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
+ GR_GL_CALL(gli, CompileShader(shaderId));
+
+ // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds.
+ bool checkCompiled = !glCtx.isChromium();
+ #ifdef SK_DEBUG
+ checkCompiled = true;
+ #endif
+ if (checkCompiled) {
+ GrGLint compiled = GR_GL_INIT_ZERO;
+ GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));
+
+ if (!compiled) {
+ GrGLint infoLen = GR_GL_INIT_ZERO;
+ GR_GL_CALL(gli, GetShaderiv(shaderId, 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 Chromium cmd
+ // buffer param validation.
+ GrGLsizei length = GR_GL_INIT_ZERO;
+ GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1,
+ &length, (char*)log.get()));
+ GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str());
+ GrPrintf("\n%s", log.get());
+ }
+ SkDEBUGFAIL("Shader compilation failed!");
+ GR_GL_CALL(gli, DeleteShader(shaderId));
+ return 0;
+ }
+ }
+
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader",
+ TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(shaderSrc.c_str()));
+ if (c_PrintShaders) {
+ GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str());
+ 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));
+
+ return shaderId;
+}
diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.h b/src/gpu/gl/builders/GrGLShaderStringBuilder.h
new file mode 100644
index 0000000000..8c18fa570a
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLShaderStringBuilder_DEFINED
+#define GrGLShaderStringBuilder_DEFINED
+
+#include "GrAllocator.h"
+#include "gl/GrGLContext.h"
+#include "SkTypes.h"
+
+GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
+ GrGLuint programId,
+ GrGLenum type,
+ const SkString& shaderSrc);
+
+#endif
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
new file mode 100644
index 0000000000..6abc085706
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLVertexShaderBuilder.h"
+#include "GrGLProgramBuilder.h"
+#include "GrGLShaderStringBuilder.h"
+#include "../GrGpuGL.h"
+
+#define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
+#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X)
+
+namespace {
+inline const char* color_attribute_name() { return "aColor"; }
+inline const char* coverage_attribute_name() { return "aCoverage"; }
+}
+
+GrGLVertexShaderBuilder::GrGLVertexShaderBuilder(GrGLFullProgramBuilder* program)
+ : INHERITED(program)
+ , fPositionVar(NULL)
+ , fLocalCoordsVar(NULL) {
+}
+bool GrGLVertexShaderBuilder::addAttribute(GrSLType type, const char* name) {
+ for (int i = 0; i < fInputs.count(); ++i) {
+ const GrGLShaderVar& attr = fInputs[i];
+ // if attribute already added, don't add it again
+ if (attr.getName().equals(name)) {
+ return false;
+ }
+ }
+ fInputs.push_back().set(type, GrGLShaderVar::kAttribute_TypeModifier, name);
+ return true;
+}
+
+bool GrGLVertexShaderBuilder::addEffectAttribute(int attributeIndex,
+ GrSLType type,
+ const SkString& name) {
+ if (!this->addAttribute(type, name.c_str())) {
+ return false;
+ }
+
+ fEffectAttributes.push_back().set(attributeIndex, name);
+ return true;
+}
+
+void GrGLVertexShaderBuilder::emitAttributes(const GrEffectStage& stage) {
+ int numAttributes = stage.getVertexAttribIndexCount();
+ const int* attributeIndices = stage.getVertexAttribIndices();
+ for (int a = 0; a < numAttributes; ++a) {
+ // TODO: Make addAttribute mangle the name.
+ SkString attributeName("aAttr");
+ attributeName.appendS32(attributeIndices[a]);
+ this->addEffectAttribute(attributeIndices[a],
+ stage.getEffect()->vertexAttribType(a),
+ attributeName);
+ }
+}
+
+const SkString* GrGLVertexShaderBuilder::getEffectAttributeName(int attributeIndex) const {
+ const AttributePair* attribEnd = fEffectAttributes.end();
+ for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attribEnd; ++attrib) {
+ if (attrib->fIndex == attributeIndex) {
+ return &attrib->fName;
+ }
+ }
+
+ return NULL;
+}
+
+void GrGLVertexShaderBuilder::addVarying(GrSLType type, const char* name, const char** vsOutName) {
+ fOutputs.push_back();
+ fOutputs.back().setType(type);
+ fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
+ fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'v', name);
+
+ if (vsOutName) {
+ *vsOutName = fOutputs.back().getName().c_str();
+ }
+}
+
+
+void GrGLVertexShaderBuilder::bindProgramLocations(GrGLuint programId) {
+ const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->desc().getHeader();
+ GrGpuGL* gpu = fProgramBuilder->gpu();
+
+ // Bind the attrib locations to same values for all shaders
+ SkASSERT(-1 != header.fPositionAttributeIndex);
+ GL_CALL(BindAttribLocation(programId,
+ header.fPositionAttributeIndex,
+ fPositionVar->c_str()));
+ if (-1 != header.fLocalCoordAttributeIndex) {
+ GL_CALL(BindAttribLocation(programId,
+ header.fLocalCoordAttributeIndex,
+ fLocalCoordsVar->c_str()));
+ }
+ if (-1 != header.fColorAttributeIndex) {
+ GL_CALL(BindAttribLocation(programId,
+ header.fColorAttributeIndex,
+ color_attribute_name()));
+ }
+ if (-1 != header.fCoverageAttributeIndex) {
+ GL_CALL(BindAttribLocation(programId,
+ header.fCoverageAttributeIndex,
+ coverage_attribute_name()));
+ }
+
+ const AttributePair* attribEnd = fEffectAttributes.end();
+ for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attribEnd; ++attrib) {
+ GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_str()));
+ }
+}
+
+bool GrGLVertexShaderBuilder::compileAndAttachShaders(GrGLuint programId,
+ SkTDArray<GrGLuint>* shaderIds) const {
+ GrGpuGL* gpu = fProgramBuilder->gpu();
+ const GrGLContext& glCtx = gpu->glContext();
+ const GrGLContextInfo& ctxInfo = gpu->ctxInfo();
+ SkString vertShaderSrc(GrGetGLSLVersionDecl(ctxInfo));
+ fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kVertex_Visibility, &vertShaderSrc);
+ fProgramBuilder->appendDecls(fInputs, &vertShaderSrc);
+ fProgramBuilder->appendDecls(fOutputs, &vertShaderSrc);
+ vertShaderSrc.append("void main() {\n");
+ vertShaderSrc.append(fCode);
+ vertShaderSrc.append("}\n");
+ GrGLuint vertShaderId = GrGLCompileAndAttachShader(glCtx, programId,
+ GR_GL_VERTEX_SHADER, vertShaderSrc);
+ if (!vertShaderId) {
+ return false;
+ }
+ *shaderIds->append() = vertShaderId;
+ return true;
+}
+
+void GrGLVertexShaderBuilder::emitCodeAfterEffects() {
+ const char* rtAdjustName;
+ fProgramBuilder->fUniformHandles.fRTAdjustmentUni =
+ fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+ kVec4f_GrSLType,
+ "rtAdjustment",
+ &rtAdjustName);
+
+ // Transform from Skia's device coords to GL's normalized device coords.
+ this->codeAppendf(
+ "\tgl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);\n",
+ rtAdjustName, rtAdjustName);
+}
+
+void GrGLVertexShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) {
+ const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->desc().getHeader();
+
+ fPositionVar = &fInputs.push_back();
+ fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
+ if (-1 != header.fLocalCoordAttributeIndex) {
+ fLocalCoordsVar = &fInputs.push_back();
+ fLocalCoordsVar->set(kVec2f_GrSLType,
+ GrGLShaderVar::kAttribute_TypeModifier,
+ "aLocalCoords");
+ } else {
+ fLocalCoordsVar = fPositionVar;
+ }
+
+ const char* viewMName;
+ fProgramBuilder->fUniformHandles.fViewMatrixUni =
+ fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+ kMat33f_GrSLType,
+ "ViewM",
+ &viewMName);
+
+ // Transform the position into Skia's device coords.
+ this->codeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n",
+ viewMName, fPositionVar->c_str());
+
+ // we output point size in the GS if present
+ if (header.fEmitsPointSize
+#if GR_GL_EXPERIMENTAL_GS
+ && !header.fExperimentalGS
+#endif
+ ) {
+ this->codeAppend("\tgl_PointSize = 1.0;\n");
+ }
+
+ if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) {
+ this->addAttribute(kVec4f_GrSLType, color_attribute_name());
+ const char *vsName, *fsName;
+ fFullProgramBuilder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
+ this->codeAppendf("\t%s = %s;\n", vsName, color_attribute_name());
+ *color = fsName;
+ }
+
+ if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
+ this->addAttribute(kVec4f_GrSLType, coverage_attribute_name());
+ const char *vsName, *fsName;
+ fFullProgramBuilder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
+ this->codeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name());
+ *coverage = fsName;
+ }
+}
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
new file mode 100644
index 0000000000..c576f57882
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLVertexShader_DEFINED
+#define GrGLVertexShader_DEFINED
+#include "GrGLShaderBuilder.h"
+
+class GrGLProgramBuilder;
+
+class GrGLVertexShaderBuilder : public GrGLFullShaderBuilder {
+public:
+ GrGLVertexShaderBuilder(GrGLFullProgramBuilder* program);
+
+ /*
+ * Add attribute will push a new attribute onto the end. It will also assert if there is
+ * a duplicate attribute
+ */
+ bool addAttribute(GrSLType type, const char* name);
+
+ bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
+
+ /*
+ * this call is only for GrGLProgramEffects' internal use
+ */
+ void emitAttributes(const GrEffectStage& stage);
+
+ /**
+ * Are explicit local coordinates provided as input to the vertex shader.
+ */
+ bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
+
+ const SkString* getEffectAttributeName(int attributeIndex) const;
+
+ /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
+ as positionAttribute() or it may not be. It depends upon whether the rendering code
+ specified explicit local coords or not in the GrDrawState. */
+ const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
+
+ /** Returns a vertex attribute that represents the vertex position in the VS. This is the
+ pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
+ */
+ const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
+
+private:
+ /*
+ * Internal call for GrGLFullProgramBuilder.addVarying
+ */
+ void addVarying(GrSLType type,
+ const char* name,
+ const char** vsOutName);
+
+ /*
+ * private helpers for compilation by GrGLProgramBuilder
+ */
+ void bindProgramLocations(GrGLuint programId);
+ bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
+ void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage);
+ void emitCodeAfterEffects();
+
+ struct AttributePair {
+ void set(int index, const SkString& name) {
+ fIndex = index; fName = name;
+ }
+ int fIndex;
+ SkString fName;
+ };
+
+ SkSTArray<10, AttributePair, true> fEffectAttributes;
+ GrGLShaderVar* fPositionVar;
+ GrGLShaderVar* fLocalCoordsVar;
+
+ friend class GrGLFullProgramBuilder;
+
+ typedef GrGLFullShaderBuilder INHERITED;
+};
+
+#endif
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 5763211029..3ab17d4f8d 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -102,13 +102,13 @@ bool GrGLProgramDesc::setRandom(SkRandom* random,
header->fCoverageEffectCnt = numCoverageStages;
if (dstRead) {
- header->fDstReadKey = SkToU8(GrGLShaderBuilder::KeyForDstRead(dstCopyTexture,
+ header->fDstReadKey = SkToU8(GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture,
gpu->glCaps()));
} else {
header->fDstReadKey = 0;
}
if (fragPos) {
- header->fFragPosKey = SkToU8(GrGLShaderBuilder::KeyForFragmentPosition(dstRenderTarget,
+ header->fFragPosKey = SkToU8(GrGLFragmentShaderBuilder::KeyForFragmentPosition(dstRenderTarget,
gpu->glCaps()));
} else {
header->fFragPosKey = 0;