blob: e639df8d225e69d96d9d6032fef9ccff92228ebd [file] [log] [blame]
tomhudson@google.com2f68e762012-07-17 18:43:21 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrTextureDomainEffect.h"
9#include "gl/GrGLProgramStage.h"
10#include "GrProgramStageFactory.h"
11
12class GrGLTextureDomainEffect : public GrGLProgramStage {
13public:
14 GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
15 const GrCustomStage& stage);
16
17 virtual void setupVariables(GrGLShaderBuilder* state,
18 int stage) SK_OVERRIDE;
19 virtual void emitVS(GrGLShaderBuilder* state,
20 const char* vertexCoords) SK_OVERRIDE { }
21 virtual void emitFS(GrGLShaderBuilder* state,
22 const char* outputColor,
23 const char* inputColor,
24 const char* samplerName) SK_OVERRIDE;
25
26 virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
27
28 virtual void setData(const GrGLInterface*,
29 const GrCustomStage&,
30 const GrRenderTarget*,
31 int stageNum) SK_OVERRIDE;
32
33 static inline StageKey GenKey(const GrCustomStage&) { return 0; }
34
35private:
36 const GrGLShaderVar* fNameVar;
37 int fNameLocation;
38
39 typedef GrGLProgramStage INHERITED;
40};
41
42GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
43 const GrCustomStage& stage)
44 : GrGLProgramStage(factory)
45 , fNameVar(NULL)
46 , fNameLocation(0) {
47}
48
49void GrGLTextureDomainEffect::setupVariables(GrGLShaderBuilder* state,
50 int stage) {
51 fNameVar = &state->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
52 kVec4f_GrSLType, "uTexDom", stage);
53 fNameLocation = kUseUniform;
54};
55
56void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* state,
57 const char* outputColor,
58 const char* inputColor,
59 const char* samplerName) {
60 SkString coordVar("clampCoord");
61 state->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
62 GrGLShaderVar::TypeString(GrSLFloatVectorType(state->fCoordDims)),
63 coordVar.c_str(),
64 state->fSampleCoords.c_str(),
65 fNameVar->getName().c_str(),
66 fNameVar->getName().c_str());
67 state->fSampleCoords = coordVar;
68
69 state->emitDefaultFetch(outputColor, samplerName);
70}
71
72void GrGLTextureDomainEffect::initUniforms(const GrGLInterface* gl, int programID) {
73 GR_GL_CALL_RET(gl, fNameLocation,
74 GetUniformLocation(programID, fNameVar->getName().c_str()));
75 GrAssert(kUnusedUniform != fNameLocation);
76}
77
78void GrGLTextureDomainEffect::setData(const GrGLInterface* gl,
79 const GrCustomStage& data,
80 const GrRenderTarget*,
81 int stageNum) {
82 const GrTextureDomainEffect& effect = static_cast<const GrTextureDomainEffect&>(data);
83 const GrRect& domain = effect.domain();
84
85 float values[4] = {
86 GrScalarToFloat(domain.left()),
87 GrScalarToFloat(domain.top()),
88 GrScalarToFloat(domain.right()),
89 GrScalarToFloat(domain.bottom())
90 };
91 // vertical flip if necessary
92 const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect.texture(0));
93 if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
94 values[1] = 1.0f - values[1];
95 values[3] = 1.0f - values[3];
96 // The top and bottom were just flipped, so correct the ordering
97 // of elements so that values = (l, t, r, b).
98 SkTSwap(values[1], values[3]);
99 }
100
101 GR_GL_CALL(gl, Uniform4fv(fNameLocation, 1, values));
102}
103
104
105///////////////////////////////////////////////////////////////////////////////
106
107GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, GrRect domain)
108 : GrSingleTextureEffect(texture)
109 , fTextureDomain(domain) {
110
111}
112
113GrTextureDomainEffect::~GrTextureDomainEffect() {
114
115}
116
117const GrProgramStageFactory& GrTextureDomainEffect::getFactory() const {
118 return GrTProgramStageFactory<GrTextureDomainEffect>::getInstance();
119}
120
121bool GrTextureDomainEffect::isEqual(const GrCustomStage& sBase) const {
122 const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
123 return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
124}
125
126