aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLGpu.cpp4
-rw-r--r--src/gpu/gl/GrGLGpu.h1
-rw-r--r--src/gpu/gl/GrGLProgram.cpp35
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp17
-rw-r--r--src/gpu/gl/GrGLProgramDesc.h3
-rw-r--r--src/gpu/gl/GrGLXferProcessor.cpp61
-rw-r--r--src/gpu/gl/GrGLXferProcessor.h18
-rw-r--r--src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp51
-rw-r--r--src/gpu/gl/builders/GrGLFragmentShaderBuilder.h1
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp6
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h5
11 files changed, 119 insertions, 83 deletions
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 6419aa6b52..dd55abb0a6 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1451,8 +1451,10 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
void GrGLGpu::buildProgramDesc(GrProgramDesc* desc,
const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
+ const GrProgramDesc::DescInfo& descInfo,
const GrBatchTracker& batchTracker) const {
- if (!GrGLProgramDescBuilder::Build(desc, primProc, pipeline, this, batchTracker)) {
+ if (!GrGLProgramDescBuilder::Build(desc, primProc, pipeline, descInfo, this,
+ batchTracker)) {
SkDEBUGFAIL("Failed to generate GL program descriptor");
}
}
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 18f0f749c4..7eda014344 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -108,6 +108,7 @@ public:
void buildProgramDesc(GrProgramDesc*,
const GrPrimitiveProcessor&,
const GrPipeline&,
+ const GrProgramDesc::DescInfo&,
const GrBatchTracker&) const SK_OVERRIDE;
private:
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index eebcf6b2f3..ad63dc4ea7 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -61,6 +61,10 @@ void GrGLProgram::abandon() {
void GrGLProgram::initSamplerUniforms() {
GL_CALL(UseProgram(fProgramID));
GrGLint texUnitIdx = 0;
+ if (fBuiltinUniformHandles.fDstCopySamplerUni.isValid()) {
+ fProgramDataManager.setSampler(fBuiltinUniformHandles.fDstCopySamplerUni, texUnitIdx);
+ fDstCopyTexUnit = texUnitIdx++;
+ }
this->initSamplers(fGeometryProcessor.get(), &texUnitIdx);
if (fXferProcessor.get()) {
this->initSamplers(fXferProcessor.get(), &texUnitIdx);
@@ -103,15 +107,38 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline
const GrBatchTracker& batchTracker) {
this->setRenderTargetState(primProc, pipeline);
+ const GrDeviceCoordTexture* dstCopy = pipeline.getDstCopy();
+ if (dstCopy) {
+ if (fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()) {
+ fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyTopLeftUni,
+ static_cast<GrGLfloat>(dstCopy->offset().fX),
+ static_cast<GrGLfloat>(dstCopy->offset().fY));
+ fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyScaleUni,
+ 1.f / dstCopy->texture()->width(),
+ 1.f / dstCopy->texture()->height());
+ GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture());
+ static GrTextureParams kParams; // the default is clamp, nearest filtering.
+ fGpu->bindTexture(fDstCopyTexUnit, kParams, texture);
+ } else {
+ SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid());
+ SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
+ }
+ } else {
+ SkASSERT(!fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid());
+ SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid());
+ SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
+ }
+
// we set the textures, and uniforms for installed processors in a generic way, but subclasses
// of GLProgram determine how to set coord transforms
fGeometryProcessor->fGLProc->setData(fProgramDataManager, primProc, batchTracker);
this->bindTextures(fGeometryProcessor.get(), primProc);
- const GrXferProcessor& xp = *pipeline.getXferProcessor();
- fXferProcessor->fGLProc->setData(fProgramDataManager, xp);
- this->bindTextures(fXferProcessor.get(), xp);
-
+ if (fXferProcessor.get()) {
+ const GrXferProcessor& xp = *pipeline.getXferProcessor();
+ fXferProcessor->fGLProc->setData(fProgramDataManager, xp);
+ this->bindTextures(fXferProcessor.get(), xp);
+ }
this->setFragmentData(primProc, pipeline);
// Some of GrGLProgram subclasses need to update state here
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index abe2439495..32f831e84c 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -89,6 +89,7 @@ static bool get_meta_key(const GrProcessor& proc,
bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc,
const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
+ const GrProgramDesc::DescInfo& descInfo,
const GrGLGpu* gpu,
const GrBatchTracker& batchTracker) {
// The descriptor is used as a cache key. Thus when a field of the
@@ -134,7 +135,21 @@ bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc,
// make sure any padding in the header is zeroed.
memset(header, 0, kHeaderSize);
- if (pipeline.readsFragPosition()) {
+ if (descInfo.fReadsDst) {
+ const GrDeviceCoordTexture* dstCopy = pipeline.getDstCopy();
+ SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport());
+ const GrTexture* dstCopyTexture = NULL;
+ if (dstCopy) {
+ dstCopyTexture = dstCopy->texture();
+ }
+ header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture,
+ gpu->glCaps());
+ SkASSERT(0 != header->fDstReadKey);
+ } else {
+ header->fDstReadKey = 0;
+ }
+
+ if (descInfo.fReadsFragPosition) {
header->fFragPosKey =
GrGLFragmentShaderBuilder::KeyForFragmentPosition(pipeline.getRenderTarget(),
gpu->glCaps());
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
index f2371556bf..e4db4c3581 100644
--- a/src/gpu/gl/GrGLProgramDesc.h
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -47,6 +47,8 @@ public:
* general draw information, as well as the specific color, geometry,
* and coverage stages which will be used to generate the GL Program for
* this optstate.
+ * @param DescInfo A descriptor info struct, generated by the optstate, which contains a number
+ * of important facts about the program the built descriptor will represent
* @param GrGLGpu A GL Gpu, the caps and Gpu object are used to output processor specific
* parts of the descriptor.
* @param GrDeviceCoordTexture A dstCopy texture, which may be null if frame buffer fetch is
@@ -56,6 +58,7 @@ public:
static bool Build(GrProgramDesc*,
const GrPrimitiveProcessor&,
const GrPipeline&,
+ const GrProgramDesc::DescInfo&,
const GrGLGpu*,
const GrBatchTracker&);
};
diff --git a/src/gpu/gl/GrGLXferProcessor.cpp b/src/gpu/gl/GrGLXferProcessor.cpp
deleted file mode 100644
index 5e8c00a976..0000000000
--- a/src/gpu/gl/GrGLXferProcessor.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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/GrGLXferProcessor.h"
-
-#include "GrXferProcessor.h"
-#include "gl/builders/GrGLFragmentShaderBuilder.h"
-#include "gl/builders/GrGLProgramBuilder.h"
-
-void GrGLXferProcessor::emitCode(const EmitArgs& args) {
- if (args.fXP.getDstCopyTexture()) {
- GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
- const char* dstColor = fsBuilder->dstColor();
-
- const char* dstCopyTopLeftName;
- const char* dstCopyCoordScaleName;
-
- fDstCopyTopLeftUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
- kVec2f_GrSLType,
- kDefault_GrSLPrecision,
- "DstCopyUpperLeft",
- &dstCopyTopLeftName);
- fDstCopyScaleUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
- kVec2f_GrSLType,
- kDefault_GrSLPrecision,
- "DstCopyCoordScale",
- &dstCopyCoordScaleName);
- const char* fragPos = fsBuilder->fragmentPosition();
-
- fsBuilder->codeAppend("// Read color from copy of the destination.\n");
- fsBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
- fragPos, dstCopyTopLeftName, dstCopyCoordScaleName);
- fsBuilder->codeAppendf("vec4 %s = ", dstColor);
- fsBuilder->appendTextureLookup(args.fSamplers[0], "_dstTexCoord", kVec2f_GrSLType);
- fsBuilder->codeAppend(";");
- }
-
- this->onEmitCode(args);
-}
-
-void GrGLXferProcessor::setData(const GrGLProgramDataManager& pdm, const GrXferProcessor& xp) {
- if (xp.getDstCopyTexture()) {
- if (fDstCopyTopLeftUni.isValid()) {
- pdm.set2f(fDstCopyTopLeftUni, static_cast<GrGLfloat>(xp.dstCopyTextureOffset().fX),
- static_cast<GrGLfloat>(xp.dstCopyTextureOffset().fY));
- pdm.set2f(fDstCopyScaleUni, 1.f / xp.getDstCopyTexture()->width(),
- 1.f / xp.getDstCopyTexture()->height());
- } else {
- SkASSERT(!fDstCopyScaleUni.isValid());
- }
- } else {
- SkASSERT(!fDstCopyTopLeftUni.isValid());
- SkASSERT(!fDstCopyScaleUni.isValid());
- }
- this->onSetData(pdm, xp);
-}
-
diff --git a/src/gpu/gl/GrGLXferProcessor.h b/src/gpu/gl/GrGLXferProcessor.h
index 7f60f32fe5..5c92559031 100644
--- a/src/gpu/gl/GrGLXferProcessor.h
+++ b/src/gpu/gl/GrGLXferProcessor.h
@@ -11,7 +11,6 @@
#include "GrGLProcessor.h"
class GrGLXPBuilder;
-class GrXferProcessor;
class GrGLXferProcessor {
public:
@@ -47,25 +46,16 @@ 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.
*/
- void emitCode(const EmitArgs&);
+ virtual void emitCode(const EmitArgs&) = 0;
/** A GrGLXferProcessor instance can be reused with any GrGLXferProcessor that produces
the same stage key; this function reads data from a GrGLXferProcessor and uploads any
uniform variables required by the shaders created in emitCode(). The GrXferProcessor
parameter is guaranteed to be of the same type that created this GrGLXferProcessor and
- to have an identical processor key as the one that created this GrGLXferProcessor. This
- function calls onSetData on the subclass of GrGLXferProcessor
- */
- void setData(const GrGLProgramDataManager& pdm, const GrXferProcessor& xp);
-
+ to have an identical processor key as the one that created this GrGLXferProcessor. */
+ virtual void setData(const GrGLProgramDataManager&,
+ const GrXferProcessor&) = 0;
private:
- virtual void onEmitCode(const EmitArgs&) = 0;
-
- virtual void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) = 0;
-
- GrGLProgramDataManager::UniformHandle fDstCopyTopLeftUni;
- GrGLProgramDataManager::UniformHandle fDstCopyScaleUni;
-
typedef GrGLProcessor INHERITED;
};
#endif
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
index 86c622d456..61932f3084 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
@@ -179,9 +179,56 @@ const char* GrGLFragmentShaderBuilder::dstColor() {
fbFetchColorName = declared_color_output_name();
}
return fbFetchColorName;
- } else {
+ } else if (fProgramBuilder->fUniformHandles.fDstCopySamplerUni.isValid()) {
return kDstCopyColorName;
- }
+ } else {
+ return "";
+ }
+}
+
+void GrGLFragmentShaderBuilder::emitCodeToReadDstTexture() {
+ bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & fProgramBuilder->header().fDstReadKey);
+ const char* dstCopyTopLeftName;
+ const char* dstCopyCoordScaleName;
+ const char* dstCopySamplerName;
+ uint32_t configMask;
+ if (SkToBool(kUseAlphaConfig_DstReadKeyBit & fProgramBuilder->header().fDstReadKey)) {
+ configMask = kA_GrColorComponentFlag;
+ } else {
+ configMask = kRGBA_GrColorComponentFlags;
+ }
+ fProgramBuilder->fUniformHandles.fDstCopySamplerUni =
+ fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kSampler2D_GrSLType,
+ kDefault_GrSLPrecision,
+ "DstCopySampler",
+ &dstCopySamplerName);
+ fProgramBuilder->fUniformHandles.fDstCopyTopLeftUni =
+ fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kVec2f_GrSLType,
+ kDefault_GrSLPrecision,
+ "DstCopyUpperLeft",
+ &dstCopyTopLeftName);
+ fProgramBuilder->fUniformHandles.fDstCopyScaleUni =
+ fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kVec2f_GrSLType,
+ kDefault_GrSLPrecision,
+ "DstCopyCoordScale",
+ &dstCopyCoordScaleName);
+ const char* fragPos = this->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 = ", GrGLFragmentShaderBuilder::kDstCopyColorName);
+ this->appendTextureLookup(dstCopySamplerName,
+ "_dstTexCoord",
+ configMask,
+ "rgba");
+ this->codeAppend(";");
}
void GrGLFragmentShaderBuilder::enableCustomOutput() {
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
index 903c5e1d7b..688bbe6269 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
@@ -97,6 +97,7 @@ public:
private:
// Private public interface, used by GrGLProgramBuilder to build a fragment shader
+ void emitCodeToReadDstTexture();
void enableCustomOutput();
void enableSecondaryOutput();
const char* getPrimaryColorOutputName() const;
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index bb278be395..088169622c 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -56,6 +56,12 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp
GrGLProgramBuilder* pb = builder.get();
+ // emit code to read the dst copy texture, if necessary
+ if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != pb->header().fDstReadKey &&
+ !gpu->glCaps().fbFetchSupport()) {
+ pb->fFS.emitCodeToReadDstTexture();
+ }
+
// TODO: Once all stages can handle taking a float or vec4 and correctly handling them we can
// seed correctly here
GrGLSLExpr4 inputColor;
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index a9288cc9b0..4b40cefad0 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -267,6 +267,11 @@ public:
// We use the render target height to provide a y-down frag coord when specifying
// origin_upper_left is not supported.
UniformHandle fRTHeightUni;
+
+ // Uniforms for computing texture coords to do the dst-copy lookup
+ UniformHandle fDstCopyTopLeftUni;
+ UniformHandle fDstCopyScaleUni;
+ UniformHandle fDstCopySamplerUni;
};
protected: