Home | History | Annotate | Download | only in effects
      1 /*
      2  * Copyright 2018 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 /**************************************************************************************************
      9  *** This file was autogenerated from GrRectBlurEffect.fp; do not modify.
     10  **************************************************************************************************/
     11 #ifndef GrRectBlurEffect_DEFINED
     12 #define GrRectBlurEffect_DEFINED
     13 #include "SkTypes.h"
     14 
     15 #include "GrProxyProvider.h"
     16 #include "GrShaderCaps.h"
     17 #include "SkBlurMask.h"
     18 #include "SkScalar.h"
     19 #include "GrFragmentProcessor.h"
     20 #include "GrCoordTransform.h"
     21 class GrRectBlurEffect : public GrFragmentProcessor {
     22 public:
     23     static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrProxyProvider* proxyProvider,
     24                                                           float sigma) {
     25         unsigned int profileSize = SkScalarCeilToInt(6 * sigma);
     26 
     27         static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
     28         GrUniqueKey key;
     29         GrUniqueKey::Builder builder(&key, kDomain, 1, "Rect Blur Mask");
     30         builder[0] = profileSize;
     31         builder.finish();
     32 
     33         sk_sp<GrTextureProxy> blurProfile(
     34                 proxyProvider->findOrCreateProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin));
     35         if (!blurProfile) {
     36             SkImageInfo ii = SkImageInfo::MakeA8(profileSize, 1);
     37 
     38             SkBitmap bitmap;
     39             if (!bitmap.tryAllocPixels(ii)) {
     40                 return nullptr;
     41             }
     42 
     43             SkBlurMask::ComputeBlurProfile(bitmap.getAddr8(0, 0), profileSize, sigma);
     44             bitmap.setImmutable();
     45 
     46             sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
     47             if (!image) {
     48                 return nullptr;
     49             }
     50 
     51             blurProfile =
     52                     proxyProvider->createTextureProxy(std::move(image), kNone_GrSurfaceFlags, 1,
     53                                                       SkBudgeted::kYes, SkBackingFit::kExact);
     54             if (!blurProfile) {
     55                 return nullptr;
     56             }
     57 
     58             SkASSERT(blurProfile->origin() == kTopLeft_GrSurfaceOrigin);
     59             proxyProvider->assignUniqueKeyToProxy(key, blurProfile.get());
     60         }
     61 
     62         return blurProfile;
     63     }
     64     const SkRect& rect() const { return fRect; }
     65     float sigma() const { return fSigma; }
     66 
     67     static std::unique_ptr<GrFragmentProcessor> Make(GrProxyProvider* proxyProvider,
     68                                                      const GrShaderCaps& caps, const SkRect& rect,
     69                                                      float sigma) {
     70         if (!caps.floatIs32Bits()) {
     71             // We promote the rect uniform from half to float when it has large values for
     72             // precision. If we don't have full float then fail.
     73             if (SkScalarAbs(rect.fLeft) > 16000.f || SkScalarAbs(rect.fTop) > 16000.f ||
     74                 SkScalarAbs(rect.fRight) > 16000.f || SkScalarAbs(rect.fBottom) > 16000.f ||
     75                 SkScalarAbs(rect.width()) > 16000.f || SkScalarAbs(rect.height()) > 16000.f) {
     76                 return nullptr;
     77             }
     78         }
     79         int doubleProfileSize = SkScalarCeilToInt(12 * sigma);
     80 
     81         if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) {
     82             // if the blur sigma is too large so the gaussian overlaps the whole
     83             // rect in either direction, fall back to CPU path for now.
     84             return nullptr;
     85         }
     86 
     87         sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(proxyProvider, sigma));
     88         if (!blurProfile) {
     89             return nullptr;
     90         }
     91 
     92         return std::unique_ptr<GrFragmentProcessor>(new GrRectBlurEffect(
     93                 rect, sigma, std::move(blurProfile),
     94                 GrSamplerState(GrSamplerState::WrapMode::kClamp, GrSamplerState::Filter::kBilerp)));
     95     }
     96     GrRectBlurEffect(const GrRectBlurEffect& src);
     97     std::unique_ptr<GrFragmentProcessor> clone() const override;
     98     const char* name() const override { return "RectBlurEffect"; }
     99 
    100 private:
    101     GrRectBlurEffect(SkRect rect, float sigma, sk_sp<GrTextureProxy> blurProfile,
    102                      GrSamplerState samplerParams)
    103             : INHERITED(kGrRectBlurEffect_ClassID,
    104                         (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
    105             , fRect(rect)
    106             , fSigma(sigma)
    107             , fBlurProfile(std::move(blurProfile), samplerParams) {
    108         this->setTextureSamplerCnt(1);
    109     }
    110     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
    111     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
    112     bool onIsEqual(const GrFragmentProcessor&) const override;
    113     const TextureSampler& onTextureSampler(int) const override;
    114     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
    115     SkRect fRect;
    116     float fSigma;
    117     TextureSampler fBlurProfile;
    118     typedef GrFragmentProcessor INHERITED;
    119 };
    120 #endif
    121