Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f9dce7e authored by Mike Reed's avatar Mike Reed
Browse files

Custom looper code for Android

Test: make

Bug: 178700363
Change-Id: I1d328275ab5e0c9b6b9171ef075f71274e50a3f5
parent 15c4d321
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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",
+6 −18
Original line number Diff line number Diff line
@@ -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) {
+8 −16
Original line number Diff line number Diff line
@@ -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;
                    }
            looper->apply(skp, [&](SkPoint offset, const SkPaint& modifiedPaint) {
                mCanvas->save();
                    mCanvas->translate(info.fTranslate.fX, info.fTranslate.fY);
                    proc(p);
                mCanvas->translate(offset.fX, offset.fY);
                proc(modifiedPaint);
                mCanvas->restore();
                }
            }
            });
        } else {
            proc(skp);
        }
+45 −0
Original line number Diff line number Diff line
/*
 * 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
+53 −0
Original line number Diff line number Diff line
/*
 * 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_
Loading