blob: 289b6210b4a857bef048ef764018e18769638456 [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
bsalomon@google.com374e7592012-10-23 17:30:45 +000012class GrGLTextureDomainEffect : public GrGLLegacyProgramStage {
tomhudson@google.com2f68e762012-07-17 18:43:21 +000013public:
14 GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
bsalomon@google.coma469c282012-10-24 18:28:34 +000015 const GrEffect& stage);
tomhudson@google.com2f68e762012-07-17 18:43:21 +000016
bsalomon@google.com777c3aa2012-07-25 20:58:20 +000017 virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
tomhudson@google.com57143a22012-07-17 19:07:35 +000018 virtual void emitVS(GrGLShaderBuilder* builder,
tomhudson@google.com2f68e762012-07-17 18:43:21 +000019 const char* vertexCoords) SK_OVERRIDE { }
tomhudson@google.com57143a22012-07-17 19:07:35 +000020 virtual void emitFS(GrGLShaderBuilder* builder,
tomhudson@google.com2f68e762012-07-17 18:43:21 +000021 const char* outputColor,
22 const char* inputColor,
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000023 const TextureSamplerArray&) SK_OVERRIDE;
tomhudson@google.com2f68e762012-07-17 18:43:21 +000024
bsalomon@google.coma469c282012-10-24 18:28:34 +000025 virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
tomhudson@google.com2f68e762012-07-17 18:43:21 +000026
bsalomon@google.coma469c282012-10-24 18:28:34 +000027 static inline StageKey GenKey(const GrEffect&, const GrGLCaps&) { return 0; }
tomhudson@google.com2f68e762012-07-17 18:43:21 +000028
29private:
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000030 GrGLUniformManager::UniformHandle fNameUni;
tomhudson@google.com2f68e762012-07-17 18:43:21 +000031
bsalomon@google.com374e7592012-10-23 17:30:45 +000032 typedef GrGLLegacyProgramStage INHERITED;
tomhudson@google.com2f68e762012-07-17 18:43:21 +000033};
34
35GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
bsalomon@google.coma469c282012-10-24 18:28:34 +000036 const GrEffect& stage)
bsalomon@google.com374e7592012-10-23 17:30:45 +000037 : INHERITED(factory)
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000038 , fNameUni(GrGLUniformManager::kInvalidUniformHandle) {
tomhudson@google.com2f68e762012-07-17 18:43:21 +000039}
40
bsalomon@google.com777c3aa2012-07-25 20:58:20 +000041void GrGLTextureDomainEffect::setupVariables(GrGLShaderBuilder* builder) {
tomhudson@google.com57143a22012-07-17 19:07:35 +000042 fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
bsalomon@google.com777c3aa2012-07-25 20:58:20 +000043 kVec4f_GrSLType, "TexDom");
tomhudson@google.com2f68e762012-07-17 18:43:21 +000044};
45
tomhudson@google.com57143a22012-07-17 19:07:35 +000046void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* builder,
tomhudson@google.com2f68e762012-07-17 18:43:21 +000047 const char* outputColor,
48 const char* inputColor,
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000049 const TextureSamplerArray& samplers) {
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +000050 builder->fFSCode.appendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n",
51 builder->defaultTexCoordsName(),
tomhudson@google.com57143a22012-07-17 19:07:35 +000052 builder->getUniformCStr(fNameUni),
53 builder->getUniformCStr(fNameUni));
tomhudson@google.com2f68e762012-07-17 18:43:21 +000054
bsalomon@google.com868a8e72012-08-30 19:11:34 +000055 builder->fFSCode.appendf("\t%s = ", outputColor);
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000056 builder->appendTextureLookupAndModulate(&builder->fFSCode,
57 inputColor,
58 samplers[0],
59 "clampCoord");
bsalomon@google.com868a8e72012-08-30 19:11:34 +000060 builder->fFSCode.append(";\n");
tomhudson@google.com2f68e762012-07-17 18:43:21 +000061}
62
bsalomon@google.coma469c282012-10-24 18:28:34 +000063void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEffect& data) {
tomhudson@google.com2f68e762012-07-17 18:43:21 +000064 const GrTextureDomainEffect& effect = static_cast<const GrTextureDomainEffect&>(data);
65 const GrRect& domain = effect.domain();
66
67 float values[4] = {
68 GrScalarToFloat(domain.left()),
69 GrScalarToFloat(domain.top()),
70 GrScalarToFloat(domain.right()),
71 GrScalarToFloat(domain.bottom())
72 };
73 // vertical flip if necessary
74 const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect.texture(0));
75 if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
76 values[1] = 1.0f - values[1];
77 values[3] = 1.0f - values[3];
78 // The top and bottom were just flipped, so correct the ordering
79 // of elements so that values = (l, t, r, b).
80 SkTSwap(values[1], values[3]);
81 }
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000082 uman.set4fv(fNameUni, 0, 1, values);
tomhudson@google.com2f68e762012-07-17 18:43:21 +000083}
84
85
86///////////////////////////////////////////////////////////////////////////////
87
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +000088GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, const GrRect& domain)
tomhudson@google.com2f68e762012-07-17 18:43:21 +000089 : GrSingleTextureEffect(texture)
90 , fTextureDomain(domain) {
tomhudson@google.com2f68e762012-07-17 18:43:21 +000091}
92
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +000093GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
94 const GrRect& domain,
95 const GrTextureParams& params)
96 : GrSingleTextureEffect(texture, params)
97 , fTextureDomain(domain) {
98}
99
tomhudson@google.com2f68e762012-07-17 18:43:21 +0000100GrTextureDomainEffect::~GrTextureDomainEffect() {
101
102}
103
104const GrProgramStageFactory& GrTextureDomainEffect::getFactory() const {
105 return GrTProgramStageFactory<GrTextureDomainEffect>::getInstance();
106}
107
bsalomon@google.coma469c282012-10-24 18:28:34 +0000108bool GrTextureDomainEffect::isEqual(const GrEffect& sBase) const {
tomhudson@google.com2f68e762012-07-17 18:43:21 +0000109 const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
110 return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
111}
bsalomon@google.com0a7672f2012-08-03 18:12:20 +0000112
113///////////////////////////////////////////////////////////////////////////////
114
115GR_DEFINE_CUSTOM_STAGE_TEST(GrTextureDomainEffect);
116
bsalomon@google.coma469c282012-10-24 18:28:34 +0000117GrEffect* GrTextureDomainEffect::TestCreate(SkRandom* random,
118 GrContext* context,
119 GrTexture* textures[]) {
bsalomon@google.com8d3d2102012-08-03 18:49:51 +0000120 int texIdx = random->nextBool() ? GrCustomStageUnitTest::kSkiaPMTextureIdx :
121 GrCustomStageUnitTest::kAlphaTextureIdx;
bsalomon@google.com0a7672f2012-08-03 18:12:20 +0000122 GrRect domain;
123 domain.fLeft = random->nextUScalar1();
124 domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1);
125 domain.fTop = random->nextUScalar1();
126 domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1);
127 return SkNEW_ARGS(GrTextureDomainEffect, (textures[texIdx], domain));
128}