diff options
author | 2021-02-12 21:20:33 -0500 | |
---|---|---|
committer | 2021-02-17 11:30:21 -0500 | |
commit | 0f9dce7ed5490f1d08fcf2a0f82b8512bb0c150c (patch) | |
tree | 74d86da2247bb7d16f565ba2edcb0e67da6fa5d3 /libs/hwui | |
parent | 15c4d3210ad1374bc0feacecc74608eaae60b76a (diff) |
Custom looper code for Android
Test: make
Bug: 178700363
Change-Id: I1d328275ab5e0c9b6b9171ef075f71274e50a3f5
Diffstat (limited to 'libs/hwui')
-rw-r--r-- | libs/hwui/Android.bp | 1 | ||||
-rw-r--r-- | libs/hwui/SkiaCanvas.cpp | 24 | ||||
-rw-r--r-- | libs/hwui/SkiaCanvas.h | 24 | ||||
-rw-r--r-- | libs/hwui/hwui/BlurDrawLooper.cpp | 45 | ||||
-rw-r--r-- | libs/hwui/hwui/BlurDrawLooper.h | 53 | ||||
-rw-r--r-- | libs/hwui/hwui/Paint.h | 8 | ||||
-rw-r--r-- | libs/hwui/jni/Paint.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp | 24 | ||||
-rw-r--r-- | libs/hwui/tests/unit/SkiaBehaviorTests.cpp | 13 | ||||
-rw-r--r-- | libs/hwui/tests/unit/SkiaCanvasTests.cpp | 3 | ||||
-rw-r--r-- | libs/hwui/utils/PaintUtils.h | 1 |
11 files changed, 129 insertions, 73 deletions
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index f48122858267..070475064c12 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -444,6 +444,7 @@ cc_defaults { "renderthread/TimeLord.cpp", "hwui/AnimatedImageDrawable.cpp", "hwui/Bitmap.cpp", + "hwui/BlurDrawLooper.cpp", "hwui/Canvas.cpp", "hwui/ImageDecoder.cpp", "hwui/MinikinSkia.cpp", diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 8fddf713f1fa..1fddac4cd05d 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -463,9 +463,7 @@ void SkiaCanvas::drawPoints(const float* points, int count, const Paint& paint, } void SkiaCanvas::drawPoint(float x, float y, const Paint& paint) { - apply_looper(&paint, [&](const SkPaint& p) { - mCanvas->drawPoint(x, y, p); - }); + apply_looper(&paint, [&](const SkPaint& p) { mCanvas->drawPoint(x, y, p); }); } void SkiaCanvas::drawPoints(const float* points, int count, const Paint& paint) { @@ -493,9 +491,7 @@ void SkiaCanvas::drawRect(float left, float top, float right, float bottom, cons void SkiaCanvas::drawRegion(const SkRegion& region, const Paint& paint) { if (CC_UNLIKELY(paint.nothingToDraw())) return; - apply_looper(&paint, [&](const SkPaint& p) { - mCanvas->drawRegion(region, p); - }); + apply_looper(&paint, [&](const SkPaint& p) { mCanvas->drawRegion(region, p); }); } void SkiaCanvas::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, @@ -509,24 +505,18 @@ void SkiaCanvas::drawRoundRect(float left, float top, float right, float bottom, void SkiaCanvas::drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner, const Paint& paint) { - apply_looper(&paint, [&](const SkPaint& p) { - mCanvas->drawDRRect(outer, inner, p); - }); + apply_looper(&paint, [&](const SkPaint& p) { mCanvas->drawDRRect(outer, inner, p); }); } void SkiaCanvas::drawCircle(float x, float y, float radius, const Paint& paint) { if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return; - apply_looper(&paint, [&](const SkPaint& p) { - mCanvas->drawCircle(x, y, radius, p); - }); + apply_looper(&paint, [&](const SkPaint& p) { mCanvas->drawCircle(x, y, radius, p); }); } void SkiaCanvas::drawOval(float left, float top, float right, float bottom, const Paint& paint) { if (CC_UNLIKELY(paint.nothingToDraw())) return; SkRect oval = SkRect::MakeLTRB(left, top, right, bottom); - apply_looper(&paint, [&](const SkPaint& p) { - mCanvas->drawOval(oval, p); - }); + apply_looper(&paint, [&](const SkPaint& p) { mCanvas->drawOval(oval, p); }); } void SkiaCanvas::drawArc(float left, float top, float right, float bottom, float startAngle, @@ -547,9 +537,7 @@ void SkiaCanvas::drawPath(const SkPath& path, const Paint& paint) { if (CC_UNLIKELY(path.isEmpty() && (!path.isInverseFillType()))) { return; } - apply_looper(&paint, [&](const SkPaint& p) { - mCanvas->drawPath(path, p); - }); + apply_looper(&paint, [&](const SkPaint& p) { mCanvas->drawPath(path, p); }); } void SkiaCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const Paint& paint) { diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h index 155f6df7b703..eac3f2217bd8 100644 --- a/libs/hwui/SkiaCanvas.h +++ b/libs/hwui/SkiaCanvas.h @@ -208,29 +208,21 @@ protected: */ PaintCoW&& filterPaint(PaintCoW&& paint) const; + // proc(const SkPaint& modifiedPaint) template <typename Proc> void apply_looper(const Paint* paint, Proc proc) { SkPaint skp; - SkDrawLooper* looper = nullptr; + BlurDrawLooper* looper = nullptr; if (paint) { skp = *filterPaint(paint); looper = paint->getLooper(); } if (looper) { - SkSTArenaAlloc<256> alloc; - SkDrawLooper::Context* ctx = looper->makeContext(&alloc); - if (ctx) { - SkDrawLooper::Context::Info info; - for (;;) { - SkPaint p = skp; - if (!ctx->next(&info, &p)) { - break; - } - mCanvas->save(); - mCanvas->translate(info.fTranslate.fX, info.fTranslate.fY); - proc(p); - mCanvas->restore(); - } - } + looper->apply(skp, [&](SkPoint offset, const SkPaint& modifiedPaint) { + mCanvas->save(); + mCanvas->translate(offset.fX, offset.fY); + proc(modifiedPaint); + mCanvas->restore(); + }); } else { proc(skp); } diff --git a/libs/hwui/hwui/BlurDrawLooper.cpp b/libs/hwui/hwui/BlurDrawLooper.cpp new file mode 100644 index 000000000000..27a038d4598e --- /dev/null +++ b/libs/hwui/hwui/BlurDrawLooper.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlurDrawLooper.h" +#include <SkMaskFilter.h> + +namespace android { + +BlurDrawLooper::BlurDrawLooper(SkColor4f color, float blurSigma, SkPoint offset) + : mColor(color), mBlurSigma(blurSigma), mOffset(offset) {} + +BlurDrawLooper::~BlurDrawLooper() = default; + +SkPoint BlurDrawLooper::apply(SkPaint* paint) const { + paint->setColor(mColor); + if (mBlurSigma > 0) { + paint->setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, mBlurSigma, true)); + } + return mOffset; +} + +sk_sp<BlurDrawLooper> BlurDrawLooper::Make(SkColor4f color, SkColorSpace* cs, float blurSigma, + SkPoint offset) { + if (cs) { + SkPaint tmp; + tmp.setColor(color, cs); // converts color to sRGB + color = tmp.getColor4f(); + } + return sk_sp<BlurDrawLooper>(new BlurDrawLooper(color, blurSigma, offset)); +} + +} // namespace android diff --git a/libs/hwui/hwui/BlurDrawLooper.h b/libs/hwui/hwui/BlurDrawLooper.h new file mode 100644 index 000000000000..7e6786f7dfbc --- /dev/null +++ b/libs/hwui/hwui/BlurDrawLooper.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GRAPHICS_BLURDRAWLOOPER_H_ +#define ANDROID_GRAPHICS_BLURDRAWLOOPER_H_ + +#include <SkPaint.h> +#include <SkRefCnt.h> + +class SkColorSpace; + +namespace android { + +class BlurDrawLooper : public SkRefCnt { +public: + static sk_sp<BlurDrawLooper> Make(SkColor4f, SkColorSpace*, float blurSigma, SkPoint offset); + + ~BlurDrawLooper() override; + + // proc(SkPoint offset, const SkPaint& modifiedPaint) + template <typename DrawProc> + void apply(const SkPaint& paint, DrawProc proc) const { + SkPaint p(paint); + proc(this->apply(&p), p); // draw the shadow + proc({0, 0}, paint); // draw the original (on top) + } + +private: + const SkColor4f mColor; + const float mBlurSigma; + const SkPoint mOffset; + + SkPoint apply(SkPaint* paint) const; + + BlurDrawLooper(SkColor4f, float, SkPoint); +}; + +} // namespace android + +#endif // ANDROID_GRAPHICS_BLURDRAWLOOPER_H_ diff --git a/libs/hwui/hwui/Paint.h b/libs/hwui/hwui/Paint.h index 05bae5c9f778..d9c9eeed03e9 100644 --- a/libs/hwui/hwui/Paint.h +++ b/libs/hwui/hwui/Paint.h @@ -17,11 +17,11 @@ #ifndef ANDROID_GRAPHICS_PAINT_H_ #define ANDROID_GRAPHICS_PAINT_H_ +#include "BlurDrawLooper.h" #include "Typeface.h" #include <cutils/compiler.h> -#include <SkDrawLooper.h> #include <SkFont.h> #include <SkPaint.h> #include <string> @@ -59,8 +59,8 @@ public: SkFont& getSkFont() { return mFont; } const SkFont& getSkFont() const { return mFont; } - SkDrawLooper* getLooper() const { return mLooper.get(); } - void setLooper(sk_sp<SkDrawLooper> looper) { mLooper = std::move(looper); } + BlurDrawLooper* getLooper() const { return mLooper.get(); } + void setLooper(sk_sp<BlurDrawLooper> looper) { mLooper = std::move(looper); } // These shadow the methods on SkPaint, but we need to so we can keep related // attributes in-sync. @@ -155,7 +155,7 @@ public: private: SkFont mFont; - sk_sp<SkDrawLooper> mLooper; + sk_sp<BlurDrawLooper> mLooper; float mLetterSpacing = 0; float mWordSpacing = 0; diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp index 3c86b28262b0..bcec0fa8a1cc 100644 --- a/libs/hwui/jni/Paint.cpp +++ b/libs/hwui/jni/Paint.cpp @@ -25,7 +25,6 @@ #include <nativehelper/ScopedUtfChars.h> #include <nativehelper/ScopedPrimitiveArray.h> -#include "SkBlurDrawLooper.h" #include "SkColorFilter.h" #include "SkFont.h" #include "SkFontMetrics.h" @@ -39,6 +38,7 @@ #include "unicode/ushape.h" #include "utils/Blur.h" +#include <hwui/BlurDrawLooper.h> #include <hwui/MinikinSkia.h> #include <hwui/MinikinUtils.h> #include <hwui/Paint.h> @@ -964,13 +964,13 @@ namespace PaintGlue { } else { SkScalar sigma = android::uirenderer::Blur::convertRadiusToSigma(radius); - paint->setLooper(SkBlurDrawLooper::Make(color, cs.get(), sigma, dx, dy)); + paint->setLooper(BlurDrawLooper::Make(color, cs.get(), sigma, {dx, dy})); } } static jboolean hasShadowLayer(CRITICAL_JNI_PARAMS_COMMA jlong paintHandle) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); - return paint->getLooper() && paint->getLooper()->asABlurShadow(nullptr); + return paint->getLooper() != nullptr; } static jboolean equalsForTextMeasurement(CRITICAL_JNI_PARAMS_COMMA jlong lPaint, jlong rPaint) { diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp index ee7c4d8bb54a..b2884023a83d 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -194,28 +194,20 @@ SkiaCanvas::PaintCoW&& SkiaRecordingCanvas::filterBitmap(PaintCoW&& paint) { return filterPaint(std::move(paint)); } -static SkDrawLooper* get_looper(const Paint* paint) { +static BlurDrawLooper* get_looper(const Paint* paint) { return paint ? paint->getLooper() : nullptr; } template <typename Proc> -void applyLooper(SkDrawLooper* looper, const SkPaint* paint, Proc proc) { +void applyLooper(BlurDrawLooper* looper, const SkPaint* paint, Proc proc) { if (looper) { - SkSTArenaAlloc<256> alloc; - SkDrawLooper::Context* ctx = looper->makeContext(&alloc); - if (ctx) { - SkDrawLooper::Context::Info info; - for (;;) { - SkPaint p; - if (paint) { - p = *paint; - } - if (!ctx->next(&info, &p)) { - break; - } - proc(info.fTranslate.fX, info.fTranslate.fY, &p); - } + SkPaint p; + if (paint) { + p = *paint; } + looper->apply(p, [&](SkPoint offset, const SkPaint& modifiedPaint) { + proc(offset.fX, offset.fY, &modifiedPaint); + }); } else { proc(0, 0, paint); } diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp index 7951537e1525..a1ba70a22581 100644 --- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp +++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp @@ -16,7 +16,6 @@ #include "tests/common/TestUtils.h" -#include <SkBlurDrawLooper.h> #include <SkColorMatrixFilter.h> #include <SkColorSpace.h> #include <SkImagePriv.h> @@ -85,15 +84,3 @@ TEST(SkiaBehavior, srgbColorSpaceIsSingleton) { ASSERT_EQ(sRGB1.get(), sRGB2.get()); } -TEST(SkiaBehavior, blurDrawLooper) { - sk_sp<SkDrawLooper> looper = SkBlurDrawLooper::Make(SK_ColorRED, 5.0f, 3.0f, 4.0f); - - SkDrawLooper::BlurShadowRec blur; - bool success = looper->asABlurShadow(&blur); - ASSERT_TRUE(success); - - ASSERT_EQ(SK_ColorRED, blur.fColor); - ASSERT_EQ(5.0f, blur.fSigma); - ASSERT_EQ(3.0f, blur.fOffset.fX); - ASSERT_EQ(4.0f, blur.fOffset.fY); -} diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp index f77ca2a8c06c..dae3c9435712 100644 --- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp +++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp @@ -17,7 +17,6 @@ #include "tests/common/TestUtils.h" #include <hwui/Paint.h> -#include <SkBlurDrawLooper.h> #include <SkCanvasStateUtils.h> #include <SkPicture.h> #include <SkPictureRecorder.h> @@ -37,7 +36,7 @@ TEST(SkiaCanvas, drawShadowLayer) { // it is transparent to ensure that we still draw the rect since it has a looper paint.setColor(SK_ColorTRANSPARENT); // this is how view's shadow layers are implemented - paint.setLooper(SkBlurDrawLooper::Make(0xF0000000, 6.0f, 0, 10)); + paint.setLooper(BlurDrawLooper::Make({0, 0, 0, 240.0f / 255}, nullptr, 6.0f, {0, 10})); canvas.drawRect(3, 3, 7, 7, paint); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE); diff --git a/libs/hwui/utils/PaintUtils.h b/libs/hwui/utils/PaintUtils.h index e2fdf2fcb5a5..09c6a4fdf50d 100644 --- a/libs/hwui/utils/PaintUtils.h +++ b/libs/hwui/utils/PaintUtils.h @@ -20,7 +20,6 @@ #include <utils/Blur.h> #include <SkColorFilter.h> -#include <SkDrawLooper.h> #include <SkPaint.h> #include <SkShader.h> |