GrTextureDomain.cpp revision d698f77c13d97c61109b861eac4d25b14a5de935
12f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com/*
22f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com * Copyright 2012 Google Inc.
32f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com *
42f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be
52f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com * found in the LICENSE file.
62f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com */
72f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
82f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com#include "GrTextureDomainEffect.h"
9d698f77c13d97c61109b861eac4d25b14a5de935bsalomon@google.com#include "gl/GrGLEffect.h"
102f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com#include "GrProgramStageFactory.h"
112f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
12374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.comclass GrGLTextureDomainEffect : public GrGLLegacyProgramStage {
132f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.compublic:
14021fc736f89fddac4f26b3f32f50263ff8fe3279bsalomon@google.com    GrGLTextureDomainEffect(const GrProgramStageFactory&, const GrEffect&);
152f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
16777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com    virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
1757143a2d87ef5fb7276ffc11abaa2e77d31f0ad8tomhudson@google.com    virtual void emitVS(GrGLShaderBuilder* builder,
182f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com                        const char* vertexCoords) SK_OVERRIDE { }
1957143a2d87ef5fb7276ffc11abaa2e77d31f0ad8tomhudson@google.com    virtual void emitFS(GrGLShaderBuilder* builder,
202f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com                        const char* outputColor,
212f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com                        const char* inputColor,
22f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com                        const TextureSamplerArray&) SK_OVERRIDE;
232f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
24a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.com    virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
252f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
26a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.com    static inline StageKey GenKey(const GrEffect&, const GrGLCaps&) { return 0; }
272f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
282f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.comprivate:
29dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    GrGLUniformManager::UniformHandle fNameUni;
302f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
31374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com    typedef GrGLLegacyProgramStage INHERITED;
322f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com};
332f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
342f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.comGrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
35021fc736f89fddac4f26b3f32f50263ff8fe3279bsalomon@google.com                                                 const GrEffect&)
36374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com    : INHERITED(factory)
37dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    , fNameUni(GrGLUniformManager::kInvalidUniformHandle) {
382f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
392f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
40777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.comvoid GrGLTextureDomainEffect::setupVariables(GrGLShaderBuilder* builder) {
4157143a2d87ef5fb7276ffc11abaa2e77d31f0ad8tomhudson@google.com    fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
42777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com                                   kVec4f_GrSLType, "TexDom");
432f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com};
442f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
4557143a2d87ef5fb7276ffc11abaa2e77d31f0ad8tomhudson@google.comvoid GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* builder,
462f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com                                     const char* outputColor,
472f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com                                     const char* inputColor,
48f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com                                     const TextureSamplerArray& samplers) {
4934bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com    builder->fFSCode.appendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n",
5034bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com                           builder->defaultTexCoordsName(),
5157143a2d87ef5fb7276ffc11abaa2e77d31f0ad8tomhudson@google.com                           builder->getUniformCStr(fNameUni),
5257143a2d87ef5fb7276ffc11abaa2e77d31f0ad8tomhudson@google.com                           builder->getUniformCStr(fNameUni));
532f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
54868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com    builder->fFSCode.appendf("\t%s = ", outputColor);
55f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com    builder->appendTextureLookupAndModulate(&builder->fFSCode,
56f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com                                            inputColor,
57f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com                                            samplers[0],
58f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com                                            "clampCoord");
59868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com    builder->fFSCode.append(";\n");
602f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
612f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
62a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.comvoid GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEffect& data) {
632f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    const GrTextureDomainEffect& effect = static_cast<const GrTextureDomainEffect&>(data);
642f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    const GrRect& domain = effect.domain();
652f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
662f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    float values[4] = {
672f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        GrScalarToFloat(domain.left()),
682f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        GrScalarToFloat(domain.top()),
692f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        GrScalarToFloat(domain.right()),
702f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        GrScalarToFloat(domain.bottom())
712f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    };
722f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    // vertical flip if necessary
732f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect.texture(0));
742f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
752f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        values[1] = 1.0f - values[1];
762f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        values[3] = 1.0f - values[3];
772f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        // The top and bottom were just flipped, so correct the ordering
782f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        // of elements so that values = (l, t, r, b).
792f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        SkTSwap(values[1], values[3]);
802f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    }
81dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    uman.set4fv(fNameUni, 0, 1, values);
822f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
832f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
842f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
852f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com///////////////////////////////////////////////////////////////////////////////
862f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
871ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.comGrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, const GrRect& domain)
882f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    : GrSingleTextureEffect(texture)
892f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    , fTextureDomain(domain) {
902f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
912f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
921ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.comGrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
931ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com                                             const GrRect& domain,
941ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com                                             const GrTextureParams& params)
951ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com    : GrSingleTextureEffect(texture, params)
961ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com    , fTextureDomain(domain) {
971ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com}
981ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com
992f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.comGrTextureDomainEffect::~GrTextureDomainEffect() {
1002f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
1012f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
1022f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
1032f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.comconst GrProgramStageFactory& GrTextureDomainEffect::getFactory() const {
1042f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    return GrTProgramStageFactory<GrTextureDomainEffect>::getInstance();
1052f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
1062f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
107a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.combool GrTextureDomainEffect::isEqual(const GrEffect& sBase) const {
1082f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
1092f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
1102f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
1110a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com
1120a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
1130a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com
114f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.comGR_DEFINE_EFFECT_TEST(GrTextureDomainEffect);
1150a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com
116a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.comGrEffect* GrTextureDomainEffect::TestCreate(SkRandom* random,
117a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.com                                            GrContext* context,
118a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.com                                            GrTexture* textures[]) {
1196f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
1206f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com                                      GrEffectUnitTest::kAlphaTextureIdx;
1210a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com    GrRect domain;
1220a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com    domain.fLeft = random->nextUScalar1();
1230a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com    domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1);
1240a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com    domain.fTop = random->nextUScalar1();
1250a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com    domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1);
1260a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com    return SkNEW_ARGS(GrTextureDomainEffect, (textures[texIdx], domain));
1270a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com}
128