Home | History | Annotate | Download | only in effects
      1 /*
      2  * Copyright 2013 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 #ifndef GrBicubicTextureEffect_DEFINED
      9 #define GrBicubicTextureEffect_DEFINED
     10 
     11 #include "GrTextureDomain.h"
     12 #include "glsl/GrGLSLFragmentProcessor.h"
     13 
     14 class GrInvariantOutput;
     15 
     16 class GrBicubicEffect : public GrFragmentProcessor {
     17 public:
     18     enum {
     19         kFilterTexelPad = 2, // Given a src rect in texels to be filtered, this number of
     20                              // surrounding texels are needed by the kernel in x and y.
     21     };
     22 
     23     const char* name() const override { return "Bicubic"; }
     24 
     25     std::unique_ptr<GrFragmentProcessor> clone() const override {
     26         return std::unique_ptr<GrFragmentProcessor>(new GrBicubicEffect(*this));
     27     }
     28 
     29     const GrTextureDomain& domain() const { return fDomain; }
     30 
     31     /**
     32      * Create a Mitchell filter effect with specified texture matrix and x/y tile modes.
     33      */
     34     static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
     35                                                      const SkMatrix& matrix,
     36                                                      const GrSamplerState::WrapMode wrapModes[2]) {
     37         // Ignore the domain on x and y, since this factory relies solely on the wrap mode of the
     38         // sampler to constrain texture coordinates
     39         return Make(std::move(proxy), matrix, wrapModes, GrTextureDomain::kIgnore_Mode,
     40                     GrTextureDomain::kIgnore_Mode);
     41     }
     42 
     43     /**
     44      * Create a Mitchell filter effect with specified texture matrix and x/y tile modes. This
     45      * supports providing modes for the texture domain explicitly, in the event that it should
     46      * override the behavior of the sampler's tile mode (e.g. clamp to border unsupported).
     47      */
     48     static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
     49                                                      const SkMatrix& matrix,
     50                                                      const GrSamplerState::WrapMode wrapModes[2],
     51                                                      GrTextureDomain::Mode modeX,
     52                                                      GrTextureDomain::Mode modeY,
     53                                                      const SkRect* domain = nullptr) {
     54         SkRect resolvedDomain = domain ? *domain : GrTextureDomain::MakeTexelDomain(
     55                 SkIRect::MakeWH(proxy->width(), proxy->height()), modeX, modeY);
     56         return std::unique_ptr<GrFragmentProcessor>(new GrBicubicEffect(
     57                 std::move(proxy), matrix, resolvedDomain, wrapModes, modeX, modeY));
     58     }
     59 
     60     /**
     61      * Create a Mitchell filter effect with a texture matrix and a domain.
     62      */
     63     static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
     64                                                      const SkMatrix& matrix,
     65                                                      const SkRect& domain) {
     66         static const GrSamplerState::WrapMode kClampClamp[] = {
     67                 GrSamplerState::WrapMode::kClamp, GrSamplerState::WrapMode::kClamp};
     68         return Make(std::move(proxy), matrix, kClampClamp, GrTextureDomain::kClamp_Mode,
     69                 GrTextureDomain::kClamp_Mode, &domain);
     70     }
     71 
     72     /**
     73      * Determines whether the bicubic effect should be used based on the transformation from the
     74      * local coords to the device. Returns true if the bicubic effect should be used. filterMode
     75      * is set to appropriate filtering mode to use regardless of the return result (e.g. when this
     76      * returns false it may indicate that the best fallback is to use kMipMap, kBilerp, or
     77      * kNearest).
     78      */
     79     static bool ShouldUseBicubic(const SkMatrix& localCoordsToDevice,
     80                                  GrSamplerState::Filter* filterMode);
     81 
     82 private:
     83     GrBicubicEffect(sk_sp<GrTextureProxy>, const SkMatrix& matrix, const SkRect& domain,
     84                     const GrSamplerState::WrapMode wrapModes[2],
     85                     GrTextureDomain::Mode modeX, GrTextureDomain::Mode modeY);
     86     explicit GrBicubicEffect(const GrBicubicEffect&);
     87 
     88     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
     89 
     90     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
     91 
     92     bool onIsEqual(const GrFragmentProcessor&) const override;
     93 
     94     const TextureSampler& onTextureSampler(int) const override { return fTextureSampler; }
     95 
     96     GrCoordTransform fCoordTransform;
     97     GrTextureDomain fDomain;
     98     TextureSampler fTextureSampler;
     99 
    100     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
    101 
    102     typedef GrFragmentProcessor INHERITED;
    103 };
    104 
    105 #endif
    106