13aad3b01afc77993ff051c02e49186294e312980humper@google.com/*
23aad3b01afc77993ff051c02e49186294e312980humper@google.com * Copyright 2013 Google Inc.
33aad3b01afc77993ff051c02e49186294e312980humper@google.com *
43aad3b01afc77993ff051c02e49186294e312980humper@google.com * Use of this source code is governed by a BSD-style license that can be
53aad3b01afc77993ff051c02e49186294e312980humper@google.com * found in the LICENSE file.
63aad3b01afc77993ff051c02e49186294e312980humper@google.com */
73aad3b01afc77993ff051c02e49186294e312980humper@google.com
83aad3b01afc77993ff051c02e49186294e312980humper@google.com#ifndef GrBicubicTextureEffect_DEFINED
93aad3b01afc77993ff051c02e49186294e312980humper@google.com#define GrBicubicTextureEffect_DEFINED
103aad3b01afc77993ff051c02e49186294e312980humper@google.com
113aad3b01afc77993ff051c02e49186294e312980humper@google.com#include "GrSingleTextureEffect.h"
127d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org#include "GrTextureDomain.h"
13b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h"
14b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrTBackendProcessorFactory.h"
153aad3b01afc77993ff051c02e49186294e312980humper@google.com
163aad3b01afc77993ff051c02e49186294e312980humper@google.comclass GrGLBicubicEffect;
173aad3b01afc77993ff051c02e49186294e312980humper@google.com
183aad3b01afc77993ff051c02e49186294e312980humper@google.comclass GrBicubicEffect : public GrSingleTextureEffect {
193aad3b01afc77993ff051c02e49186294e312980humper@google.compublic:
20dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    enum {
21dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        kFilterTexelPad = 2, // Given a src rect in texels to be filtered, this number of
22dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                             // surrounding texels are needed by the kernel in x and y.
23dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    };
243aad3b01afc77993ff051c02e49186294e312980humper@google.com    virtual ~GrBicubicEffect();
253aad3b01afc77993ff051c02e49186294e312980humper@google.com
263aad3b01afc77993ff051c02e49186294e312980humper@google.com    static const char* Name() { return "Bicubic"; }
273aad3b01afc77993ff051c02e49186294e312980humper@google.com    const float* coefficients() const { return fCoefficients; }
283aad3b01afc77993ff051c02e49186294e312980humper@google.com
29b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrGLBicubicEffect GLProcessor;
303aad3b01afc77993ff051c02e49186294e312980humper@google.com
31b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
323aad3b01afc77993ff051c02e49186294e312980humper@google.com    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
333aad3b01afc77993ff051c02e49186294e312980humper@google.com
347d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org    const GrTextureDomain& domain() const { return fDomain; }
353aad3b01afc77993ff051c02e49186294e312980humper@google.com
36bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org    /**
377d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org     * Create a simple filter effect with custom bicubic coefficients and optional domain.
38bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org     */
39b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrTexture* tex, const SkScalar coefficients[16],
4083d081ae1d731b5039e99823620f5e287542ee39bsalomon                            const SkRect* domain = NULL) {
417d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        if (NULL == domain) {
427d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org            static const SkShader::TileMode kTileModes[] = { SkShader::kClamp_TileMode,
437d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org                                                             SkShader::kClamp_TileMode };
446267f81f3d60ce144ab2b09ea369420984d5c9d9bsalomon            return Create(tex, coefficients, GrCoordTransform::MakeDivByTextureWHMatrix(tex),
456267f81f3d60ce144ab2b09ea369420984d5c9d9bsalomon                          kTileModes);
467d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        } else {
4755fad7af61c21d502acb9891d631e8aa29e3628cbsalomon            return SkNEW_ARGS(GrBicubicEffect, (tex, coefficients,
486267f81f3d60ce144ab2b09ea369420984d5c9d9bsalomon                                                GrCoordTransform::MakeDivByTextureWHMatrix(tex),
496267f81f3d60ce144ab2b09ea369420984d5c9d9bsalomon                                                *domain));
507d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        }
513aad3b01afc77993ff051c02e49186294e312980humper@google.com    }
523aad3b01afc77993ff051c02e49186294e312980humper@google.com
53bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org    /**
54bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org     * Create a Mitchell filter effect with specified texture matrix and x/y tile modes.
55bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org     */
56b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrTexture* tex, const SkMatrix& matrix,
5783d081ae1d731b5039e99823620f5e287542ee39bsalomon                            SkShader::TileMode tileModes[2]) {
58bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org        return Create(tex, gMitchellCoefficients, matrix, tileModes);
593aad3b01afc77993ff051c02e49186294e312980humper@google.com    }
603aad3b01afc77993ff051c02e49186294e312980humper@google.com
61bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org    /**
627d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org     * Create a filter effect with custom bicubic coefficients, the texture matrix, and the x/y
637d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org     * tilemodes.
64bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org     */
65b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrTexture* tex, const SkScalar coefficients[16],
66b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix& matrix,
67b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkShader::TileMode tileModes[2]) {
6855fad7af61c21d502acb9891d631e8aa29e3628cbsalomon        return SkNEW_ARGS(GrBicubicEffect, (tex, coefficients, matrix, tileModes));
693aad3b01afc77993ff051c02e49186294e312980humper@google.com    }
703aad3b01afc77993ff051c02e49186294e312980humper@google.com
717d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org    /**
727d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org     * Create a Mitchell filter effect with a texture matrix and a domain.
737d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org     */
74b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrTexture* tex, const SkMatrix& matrix,
75b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkRect& domain) {
7655fad7af61c21d502acb9891d631e8aa29e3628cbsalomon        return SkNEW_ARGS(GrBicubicEffect, (tex, gMitchellCoefficients, matrix, domain));
777d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org    }
787d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org
799927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    /**
809927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org     * Determines whether the bicubic effect should be used based on the transformation from the
819927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org     * local coords to the device. Returns true if the bicubic effect should be used. filterMode
829927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org     * is set to appropriate filtering mode to use regardless of the return result (e.g. when this
839927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org     * returns false it may indicate that the best fallback is to use kMipMap, kBilerp, or
849927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org     * kNearest).
859927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org     */
869927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    static bool ShouldUseBicubic(const SkMatrix& localCoordsToDevice,
879927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org                                 GrTextureParams::FilterMode* filterMode);
889927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org
893aad3b01afc77993ff051c02e49186294e312980humper@google.comprivate:
90c3723db387a257a2b8beba1a515df355cd70d06askia.committer@gmail.com    GrBicubicEffect(GrTexture*, const SkScalar coefficients[16],
91bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org                    const SkMatrix &matrix, const SkShader::TileMode tileModes[2]);
927d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org    GrBicubicEffect(GrTexture*, const SkScalar coefficients[16],
937d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org                    const SkMatrix &matrix, const SkRect& domain);
94b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
957d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org
967d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org    float           fCoefficients[16];
977d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org    GrTextureDomain fDomain;
983aad3b01afc77993ff051c02e49186294e312980humper@google.com
99b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
100c3723db387a257a2b8beba1a515df355cd70d06askia.committer@gmail.com
1013aad3b01afc77993ff051c02e49186294e312980humper@google.com    static const SkScalar gMitchellCoefficients[16];
1023aad3b01afc77993ff051c02e49186294e312980humper@google.com
1033aad3b01afc77993ff051c02e49186294e312980humper@google.com    typedef GrSingleTextureEffect INHERITED;
1043aad3b01afc77993ff051c02e49186294e312980humper@google.com};
1053aad3b01afc77993ff051c02e49186294e312980humper@google.com
1063aad3b01afc77993ff051c02e49186294e312980humper@google.com#endif
107