blob: e949c4c08511f6b661693aa68a5ab4d3972bd76d [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
tomhudson@google.com57143a22012-07-17 19:07:35 +000012// For brevity, and these definitions are likely to move to a different class soon.
13typedef GrGLShaderBuilder::UniformHandle UniformHandle;
14static const UniformHandle kInvalidUniformHandle = GrGLShaderBuilder::kInvalidUniformHandle;
15
tomhudson@google.com2f68e762012-07-17 18:43:21 +000016class GrGLTextureDomainEffect : public GrGLProgramStage {
17public:
18 GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
19 const GrCustomStage& stage);
20
tomhudson@google.com57143a22012-07-17 19:07:35 +000021 virtual void setupVariables(GrGLShaderBuilder* builder,
tomhudson@google.com2f68e762012-07-17 18:43:21 +000022 int stage) SK_OVERRIDE;
tomhudson@google.com57143a22012-07-17 19:07:35 +000023 virtual void emitVS(GrGLShaderBuilder* builder,
tomhudson@google.com2f68e762012-07-17 18:43:21 +000024 const char* vertexCoords) SK_OVERRIDE { }
tomhudson@google.com57143a22012-07-17 19:07:35 +000025 virtual void emitFS(GrGLShaderBuilder* builder,
tomhudson@google.com2f68e762012-07-17 18:43:21 +000026 const char* outputColor,
27 const char* inputColor,
28 const char* samplerName) SK_OVERRIDE;
29
tomhudson@google.com57143a22012-07-17 19:07:35 +000030 virtual void initUniforms(const GrGLShaderBuilder* builder,
31 const GrGLInterface*,
32 int programID) SK_OVERRIDE;
tomhudson@google.com2f68e762012-07-17 18:43:21 +000033
34 virtual void setData(const GrGLInterface*,
35 const GrCustomStage&,
36 const GrRenderTarget*,
37 int stageNum) SK_OVERRIDE;
38
39 static inline StageKey GenKey(const GrCustomStage&) { return 0; }
40
41private:
tomhudson@google.com57143a22012-07-17 19:07:35 +000042 UniformHandle fNameUni;
43 int fNameLocation;
tomhudson@google.com2f68e762012-07-17 18:43:21 +000044
45 typedef GrGLProgramStage INHERITED;
46};
47
48GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
49 const GrCustomStage& stage)
50 : GrGLProgramStage(factory)
tomhudson@google.com57143a22012-07-17 19:07:35 +000051 , fNameUni(kInvalidUniformHandle)
tomhudson@google.com2f68e762012-07-17 18:43:21 +000052 , fNameLocation(0) {
53}
54
tomhudson@google.com57143a22012-07-17 19:07:35 +000055void GrGLTextureDomainEffect::setupVariables(GrGLShaderBuilder* builder,
tomhudson@google.com2f68e762012-07-17 18:43:21 +000056 int stage) {
tomhudson@google.com57143a22012-07-17 19:07:35 +000057 fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
58 kVec4f_GrSLType, "uTexDom", stage);
tomhudson@google.com2f68e762012-07-17 18:43:21 +000059 fNameLocation = kUseUniform;
60};
61
tomhudson@google.com57143a22012-07-17 19:07:35 +000062void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* builder,
tomhudson@google.com2f68e762012-07-17 18:43:21 +000063 const char* outputColor,
64 const char* inputColor,
65 const char* samplerName) {
66 SkString coordVar("clampCoord");
tomhudson@google.com57143a22012-07-17 19:07:35 +000067 builder->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
68 GrGLShaderVar::TypeString(GrSLFloatVectorType(builder->fCoordDims)),
tomhudson@google.com2f68e762012-07-17 18:43:21 +000069 coordVar.c_str(),
tomhudson@google.com57143a22012-07-17 19:07:35 +000070 builder->fSampleCoords.c_str(),
71 builder->getUniformCStr(fNameUni),
72 builder->getUniformCStr(fNameUni));
73 builder->fSampleCoords = coordVar;
tomhudson@google.com2f68e762012-07-17 18:43:21 +000074
tomhudson@google.com57143a22012-07-17 19:07:35 +000075 builder->emitDefaultFetch(outputColor, samplerName);
tomhudson@google.com2f68e762012-07-17 18:43:21 +000076}
77
tomhudson@google.com57143a22012-07-17 19:07:35 +000078void GrGLTextureDomainEffect::initUniforms(const GrGLShaderBuilder* builder,
79 const GrGLInterface* gl, int programID) {
tomhudson@google.com2f68e762012-07-17 18:43:21 +000080 GR_GL_CALL_RET(gl, fNameLocation,
tomhudson@google.com57143a22012-07-17 19:07:35 +000081 GetUniformLocation(programID, builder->getUniformCStr(fNameUni)));
tomhudson@google.com2f68e762012-07-17 18:43:21 +000082 GrAssert(kUnusedUniform != fNameLocation);
83}
84
85void GrGLTextureDomainEffect::setData(const GrGLInterface* gl,
86 const GrCustomStage& data,
87 const GrRenderTarget*,
88 int stageNum) {
89 const GrTextureDomainEffect& effect = static_cast<const GrTextureDomainEffect&>(data);
90 const GrRect& domain = effect.domain();
91
92 float values[4] = {
93 GrScalarToFloat(domain.left()),
94 GrScalarToFloat(domain.top()),
95 GrScalarToFloat(domain.right()),
96 GrScalarToFloat(domain.bottom())
97 };
98 // vertical flip if necessary
99 const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect.texture(0));
100 if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
101 values[1] = 1.0f - values[1];
102 values[3] = 1.0f - values[3];
103 // The top and bottom were just flipped, so correct the ordering
104 // of elements so that values = (l, t, r, b).
105 SkTSwap(values[1], values[3]);
106 }
107
108 GR_GL_CALL(gl, Uniform4fv(fNameLocation, 1, values));
109}
110
111
112///////////////////////////////////////////////////////////////////////////////
113
114GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, GrRect domain)
115 : GrSingleTextureEffect(texture)
116 , fTextureDomain(domain) {
117
118}
119
120GrTextureDomainEffect::~GrTextureDomainEffect() {
121
122}
123
124const GrProgramStageFactory& GrTextureDomainEffect::getFactory() const {
125 return GrTProgramStageFactory<GrTextureDomainEffect>::getInstance();
126}
127
128bool GrTextureDomainEffect::isEqual(const GrCustomStage& sBase) const {
129 const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
130 return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
131}
132
133