blob: 6e09aaed5d58f5a422e729c59519a8ba20fca552 [file] [log] [blame]
Ethan Nicholas82399462017-10-16 12:35:44 -04001/*
Ethan Nicholas130fb3f2018-02-01 12:14:34 -05002 * Copyright 2018 Google Inc.
Ethan Nicholas82399462017-10-16 12:35:44 -04003 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Ethan Nicholas130fb3f2018-02-01 12:14:34 -05008/**************************************************************************************************
9 *** This file was autogenerated from GrRectBlurEffect.fp; do not modify.
10 **************************************************************************************************/
Ethan Nicholas82399462017-10-16 12:35:44 -040011#ifndef GrRectBlurEffect_DEFINED
12#define GrRectBlurEffect_DEFINED
13#include "SkTypes.h"
Ethan Nicholas82399462017-10-16 12:35:44 -040014
Robert Phillips1afd4cd2018-01-08 13:40:32 -050015#include "GrProxyProvider.h"
Robert Phillipsa41c6852019-02-07 10:44:10 -050016#include "GrShaderCaps.h"
Mike Reed554aa6a2018-03-12 11:36:26 -040017#include "SkBlurMask.h"
Brian Salomonff6a7cd2018-05-10 09:42:27 -040018#include "SkScalar.h"
Ethan Nicholas82399462017-10-16 12:35:44 -040019#include "GrFragmentProcessor.h"
20#include "GrCoordTransform.h"
Ethan Nicholas82399462017-10-16 12:35:44 -040021class GrRectBlurEffect : public GrFragmentProcessor {
22public:
Robert Phillips1afd4cd2018-01-08 13:40:32 -050023 static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrProxyProvider* proxyProvider,
Mike Kleind6ab77a2019-03-21 08:18:24 -050024 float sigma) {
Ethan Nicholas82399462017-10-16 12:35:44 -040025 unsigned int profileSize = SkScalarCeilToInt(6 * sigma);
26
27 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
Mike Kleind6ab77a2019-03-21 08:18:24 -050028 GrUniqueKey key;
29 GrUniqueKey::Builder builder(&key, kDomain, 1, "Rect Blur Mask");
Ethan Nicholas82399462017-10-16 12:35:44 -040030 builder[0] = profileSize;
31 builder.finish();
32
33 sk_sp<GrTextureProxy> blurProfile(
Robert Phillips1afd4cd2018-01-08 13:40:32 -050034 proxyProvider->findOrCreateProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin));
Ethan Nicholas82399462017-10-16 12:35:44 -040035 if (!blurProfile) {
Robert Phillipscb256592018-02-14 15:20:41 -050036 SkImageInfo ii = SkImageInfo::MakeA8(profileSize, 1);
Ethan Nicholas82399462017-10-16 12:35:44 -040037
Robert Phillipscb256592018-02-14 15:20:41 -050038 SkBitmap bitmap;
39 if (!bitmap.tryAllocPixels(ii)) {
40 return nullptr;
41 }
Ethan Nicholas82399462017-10-16 12:35:44 -040042
Robert Phillipscb256592018-02-14 15:20:41 -050043 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
Mike Kleind6ab77a2019-03-21 08:18:24 -050051 blurProfile =
52 proxyProvider->createTextureProxy(std::move(image), kNone_GrSurfaceFlags, 1,
53 SkBudgeted::kYes, SkBackingFit::kExact);
Ethan Nicholas82399462017-10-16 12:35:44 -040054 if (!blurProfile) {
55 return nullptr;
56 }
57
58 SkASSERT(blurProfile->origin() == kTopLeft_GrSurfaceOrigin);
Robert Phillips1afd4cd2018-01-08 13:40:32 -050059 proxyProvider->assignUniqueKeyToProxy(key, blurProfile.get());
Ethan Nicholas82399462017-10-16 12:35:44 -040060 }
61
62 return blurProfile;
63 }
Ethan Nicholas82399462017-10-16 12:35:44 -040064
Mike Kleind6ab77a2019-03-21 08:18:24 -050065 static std::unique_ptr<GrFragmentProcessor> Make(GrProxyProvider* proxyProvider,
66 const GrShaderCaps& caps, const SkRect& rect,
67 float sigma) {
Brian Salomonff6a7cd2018-05-10 09:42:27 -040068 if (!caps.floatIs32Bits()) {
69 // We promote the rect uniform from half to float when it has large values for
70 // precision. If we don't have full float then fail.
71 if (SkScalarAbs(rect.fLeft) > 16000.f || SkScalarAbs(rect.fTop) > 16000.f ||
72 SkScalarAbs(rect.fRight) > 16000.f || SkScalarAbs(rect.fBottom) > 16000.f ||
73 SkScalarAbs(rect.width()) > 16000.f || SkScalarAbs(rect.height()) > 16000.f) {
74 return nullptr;
75 }
76 }
Ethan Nicholas82399462017-10-16 12:35:44 -040077 int doubleProfileSize = SkScalarCeilToInt(12 * sigma);
78
79 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) {
80 // if the blur sigma is too large so the gaussian overlaps the whole
81 // rect in either direction, fall back to CPU path for now.
82 return nullptr;
83 }
84
Robert Phillips1afd4cd2018-01-08 13:40:32 -050085 sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(proxyProvider, sigma));
Ethan Nicholas82399462017-10-16 12:35:44 -040086 if (!blurProfile) {
87 return nullptr;
88 }
89
Robert Phillips2b2936e2017-10-20 15:11:35 -040090 return std::unique_ptr<GrFragmentProcessor>(new GrRectBlurEffect(
Mike Kleind6ab77a2019-03-21 08:18:24 -050091 rect, sigma, std::move(blurProfile),
Robert Phillips2b2936e2017-10-20 15:11:35 -040092 GrSamplerState(GrSamplerState::WrapMode::kClamp, GrSamplerState::Filter::kBilerp)));
Ethan Nicholas82399462017-10-16 12:35:44 -040093 }
94 GrRectBlurEffect(const GrRectBlurEffect& src);
95 std::unique_ptr<GrFragmentProcessor> clone() const override;
Mike Kleind6ab77a2019-03-21 08:18:24 -050096 const char* name() const override { return "RectBlurEffect"; }
Ethan Nicholasbcd51e82019-04-09 10:40:41 -040097 SkRect rect;
98 float sigma;
99 TextureSampler blurProfile;
Ethan Nicholas82399462017-10-16 12:35:44 -0400100
101private:
Mike Kleind6ab77a2019-03-21 08:18:24 -0500102 GrRectBlurEffect(SkRect rect, float sigma, sk_sp<GrTextureProxy> blurProfile,
103 GrSamplerState samplerParams)
Ethan Nicholas82399462017-10-16 12:35:44 -0400104 : INHERITED(kGrRectBlurEffect_ClassID,
105 (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400106 , rect(rect)
107 , sigma(sigma)
108 , blurProfile(std::move(blurProfile), samplerParams) {
Brian Salomonf7dcd762018-07-30 14:48:15 -0400109 this->setTextureSamplerCnt(1);
Ethan Nicholas82399462017-10-16 12:35:44 -0400110 }
111 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
112 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
113 bool onIsEqual(const GrFragmentProcessor&) const override;
Brian Salomonf7dcd762018-07-30 14:48:15 -0400114 const TextureSampler& onTextureSampler(int) const override;
Ethan Nicholas82399462017-10-16 12:35:44 -0400115 GR_DECLARE_FRAGMENT_PROCESSOR_TEST
Ethan Nicholas82399462017-10-16 12:35:44 -0400116 typedef GrFragmentProcessor INHERITED;
117};
118#endif