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

Commit a1b962e5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge changes I9a231625,Idaf3a905 into sc-dev am: 46614cfa

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14491702

Change-Id: I5ed796435c91df9428464fa3e1ec3798401b7d2d
parents d4c5a9f5 46614cfa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -553,7 +553,7 @@ public:
    bool promotedToLayer() const {
        return mLayerProperties.mType == LayerType::None && fitsOnLayer() &&
               (mComputedFields.mNeedLayerForFunctors || mLayerProperties.mImageFilter != nullptr ||
                !mLayerProperties.getStretchEffect().isEmpty() ||
                mLayerProperties.getStretchEffect().requiresLayer() ||
                (!MathUtils::isZero(mPrimitiveFields.mAlpha) && mPrimitiveFields.mAlpha < 1 &&
                 mPrimitiveFields.mHasOverlappingRendering));
    }
+6 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#pragma once

#include "Properties.h"
#include "utils/MathUtils.h"

#include <SkImage.h>
@@ -108,6 +109,11 @@ public:
        return matrix;
    }

    bool requiresLayer() const {
        return !(isEmpty() ||
                 Properties::stretchEffectBehavior == StretchEffectBehavior::LinearScale);
    }

private:
    static sk_sp<SkRuntimeEffect> getStretchEffect();
    mutable SkVector mStretchDirection{0, 0};
+1 −6
Original line number Diff line number Diff line
@@ -171,16 +171,11 @@ void RenderNodeDrawable::forceDraw(SkCanvas* canvas) const {
    displayList->mProjectedOutline = nullptr;
}

static bool stretchNeedsLayer(const LayerProperties& properties) {
    return Properties::stretchEffectBehavior != StretchEffectBehavior::LinearScale &&
           !properties.getStretchEffect().isEmpty();
}

static bool layerNeedsPaint(const sk_sp<SkImage>& snapshotImage, const LayerProperties& properties,
                            float alphaMultiplier, SkPaint* paint) {
    if (alphaMultiplier < 1.0f || properties.alpha() < 255 ||
        properties.xferMode() != SkBlendMode::kSrcOver || properties.getColorFilter() != nullptr ||
        properties.getImageFilter() != nullptr || stretchNeedsLayer(properties)) {
        properties.getImageFilter() != nullptr || properties.getStretchEffect().requiresLayer()) {
        paint->setAlpha(properties.alpha() * alphaMultiplier);
        paint->setBlendMode(properties.xferMode());
        paint->setColorFilter(sk_ref_sp(properties.getColorFilter()));
+2 −1
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@ namespace test {
class TestScene {
public:
    struct Options {
        int count = 0;
        int frameCount = 150;
        int repeatCount = 1;
        int reportFrametimeWeight = 0;
        bool renderOffscreen = true;
    };
+200 −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 <SkFont.h>
#include <cstdio>
#include "TestSceneBase.h"
#include "hwui/Paint.h"
#include "tests/common/TestUtils.h"

class StretchyListViewAnimation;
class StretchyListViewHolePunch;
class StretchyLinearListView;
class StretchyLinearListViewHolePunch;

static TestScene::Registrar _StretchyListViewAnimation(TestScene::Info{
        "stretchylistview",
        "A mock ListView of scrolling content that's stretching. Doesn't re-bind/re-record views "
        "as they are recycled, so won't upload much content (either glyphs, or bitmaps).",
        TestScene::simpleCreateScene<StretchyListViewAnimation>});

static TestScene::Registrar _StretchyListViewHolePunch(TestScene::Info{
        "stretchylistview_holepunch",
        "A mock ListView of scrolling content that's stretching. Includes a hole punch",
        TestScene::simpleCreateScene<StretchyListViewHolePunch>});

static TestScene::Registrar _StretchyLinearListView(TestScene::Info{
        "stretchylistview_linear",
        "A mock ListView of scrolling content that's stretching using a linear stretch effect.",
        TestScene::simpleCreateScene<StretchyLinearListView>});

static TestScene::Registrar _StretchyLinearListViewHolePunch(TestScene::Info{
        "stretchylistview_linear_holepunch",
        "A mock ListView of scrolling content that's stretching using a linear stretch effect. "
        "Includes a hole punch",
        TestScene::simpleCreateScene<StretchyLinearListViewHolePunch>});

class StretchyListViewAnimation : public TestScene {
protected:
    virtual StretchEffectBehavior stretchBehavior() { return StretchEffectBehavior::Shader; }
    virtual bool haveHolePunch() { return false; }

private:
    int mItemHeight;
    int mItemSpacing;
    int mItemWidth;
    int mItemLeft;
    sp<RenderNode> mListView;
    std::vector<sp<RenderNode> > mListItems;

    sk_sp<Bitmap> createRandomCharIcon(int cardHeight) {
        SkBitmap skBitmap;
        int size = cardHeight - (dp(10) * 2);
        sk_sp<Bitmap> bitmap(TestUtils::createBitmap(size, size, &skBitmap));
        SkCanvas canvas(skBitmap);
        canvas.clear(0);

        SkPaint paint;
        paint.setAntiAlias(true);
        SkColor randomColor = BrightColors[rand() % BrightColorsCount];
        paint.setColor(randomColor);
        canvas.drawCircle(size / 2, size / 2, size / 2, paint);

        bool bgDark =
                SkColorGetR(randomColor) + SkColorGetG(randomColor) + SkColorGetB(randomColor) <
                128 * 3;
        paint.setColor(bgDark ? Color::White : Color::Grey_700);

        SkFont font;
        font.setSize(size / 2);
        char charToShow = 'A' + (rand() % 26);
        const SkPoint pos = {SkIntToScalar(size / 2),
                             /*approximate centering*/ SkFloatToScalar(size * 0.7f)};
        canvas.drawSimpleText(&charToShow, 1, SkTextEncoding::kUTF8, pos.fX, pos.fY, font, paint);
        return bitmap;
    }

    static sk_sp<Bitmap> createBoxBitmap(bool filled) {
        int size = dp(20);
        int stroke = dp(2);
        SkBitmap skBitmap;
        auto bitmap = TestUtils::createBitmap(size, size, &skBitmap);
        SkCanvas canvas(skBitmap);
        canvas.clear(Color::Transparent);

        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setColor(filled ? Color::Yellow_500 : Color::Grey_700);
        paint.setStyle(filled ? SkPaint::kStrokeAndFill_Style : SkPaint::kStroke_Style);
        paint.setStrokeWidth(stroke);
        canvas.drawRect(SkRect::MakeLTRB(stroke, stroke, size - stroke, size - stroke), paint);
        return bitmap;
    }

    void createListItem(RenderProperties& props, Canvas& canvas, int cardId, int itemWidth,
                        int itemHeight) {
        static sk_sp<Bitmap> filledBox(createBoxBitmap(true));
        static sk_sp<Bitmap> strokedBox(createBoxBitmap(false));
        const bool addHolePunch = cardId == 2 && haveHolePunch();
        // TODO: switch to using round rect clipping, once merging correctly handles that
        Paint roundRectPaint;
        roundRectPaint.setAntiAlias(true);
        roundRectPaint.setColor(Color::White);
        if (addHolePunch) {
            // Punch a hole but then cover it up, we don't want to actually see it
            canvas.punchHole(SkRRect::MakeRect(SkRect::MakeWH(itemWidth, itemHeight)));
        }
        canvas.drawRoundRect(0, 0, itemWidth, itemHeight, dp(6), dp(6), roundRectPaint);

        Paint textPaint;
        textPaint.setColor(rand() % 2 ? Color::Black : Color::Grey_500);
        textPaint.getSkFont().setSize(dp(20));
        textPaint.setAntiAlias(true);
        char buf[256];
        snprintf(buf, sizeof(buf), "This card is #%d", cardId);
        TestUtils::drawUtf8ToCanvas(&canvas, buf, textPaint, itemHeight, dp(25));
        textPaint.getSkFont().setSize(dp(15));
        if (addHolePunch) {
            TestUtils::drawUtf8ToCanvas(&canvas, "I have a hole punch", textPaint, itemHeight,
                                        dp(45));
        } else {
            TestUtils::drawUtf8ToCanvas(&canvas, "This is some more text on the card", textPaint,
                                        itemHeight, dp(45));
        }

        auto randomIcon = createRandomCharIcon(itemHeight);
        canvas.drawBitmap(*randomIcon, dp(10), dp(10), nullptr);

        auto box = rand() % 2 ? filledBox : strokedBox;
        canvas.drawBitmap(*box, itemWidth - dp(10) - box->width(), dp(10), nullptr);
    }

    void createContent(int width, int height, Canvas& canvas) override {
        srand(0);
        mItemHeight = dp(60);
        mItemSpacing = dp(16);
        mItemWidth = std::min((height - mItemSpacing * 2), (int)dp(300));
        mItemLeft = (width - mItemWidth) / 2;
        int heightWithSpacing = mItemHeight + mItemSpacing;
        for (int y = 0; y < height + (heightWithSpacing - 1); y += heightWithSpacing) {
            int id = mListItems.size();
            auto node = TestUtils::createNode(mItemLeft, y, mItemLeft + mItemWidth, y + mItemHeight,
                                              [this, id](RenderProperties& props, Canvas& canvas) {
                                                  createListItem(props, canvas, id, mItemWidth,
                                                                 mItemHeight);
                                              });
            mListItems.push_back(node);
        }
        mListView = TestUtils::createNode(0, 0, width, height,
                                          [this](RenderProperties& props, Canvas& canvas) {
                                              for (size_t ci = 0; ci < mListItems.size(); ci++) {
                                                  canvas.drawRenderNode(mListItems[ci].get());
                                              }
                                          });

        canvas.drawColor(Color::Grey_500, SkBlendMode::kSrcOver);
        canvas.drawRenderNode(mListView.get());
    }

    void doFrame(int frameNr) override {
        if (frameNr == 0) {
            Properties::stretchEffectBehavior = stretchBehavior();
        }
        auto& props = mListView->mutateStagingProperties();
        auto& stretch = props.mutateLayerProperties().mutableStretchEffect();
        stretch.setEmpty();
        frameNr = frameNr % 150;
        // Animate from 0f to .1f
        const float sY = (frameNr > 75 ? 150 - frameNr : frameNr) / 1500.f;
        stretch.mergeWith({{.fX = 0, .fY = sY},
                           static_cast<float>(props.getWidth()),
                           static_cast<float>(props.getHeight())});
        mListView->setPropertyFieldsDirty(RenderNode::GENERIC);
    }
};

class StretchyListViewHolePunch : public StretchyListViewAnimation {
    bool haveHolePunch() override { return true; }
};

class StretchyLinearListView : public StretchyListViewAnimation {
    StretchEffectBehavior stretchBehavior() override { return StretchEffectBehavior::LinearScale; }
};

class StretchyLinearListViewHolePunch : public StretchyListViewAnimation {
    StretchEffectBehavior stretchBehavior() override { return StretchEffectBehavior::LinearScale; }
    bool haveHolePunch() override { return true; }
};
 No newline at end of file
Loading