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

Commit 06a62f6f authored by sergeyv's avatar sergeyv
Browse files

Test scene that mocks list view with text items faded on left edge.

Change-Id: I6159f02fa511241beaff4f0eb605c4f0bee360d1
parent 6465299a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ hwui_src_files := \

hwui_test_common_src_files := \
    $(call all-cpp-files-under, tests/common/scenes) \
    tests/common/TestListViewSceneBase.cpp \
    tests/common/TestContext.cpp \
    tests/common/TestScene.cpp \
    tests/common/TestUtils.cpp
+78 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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 "TestListViewSceneBase.h"

#include "TestContext.h"
#include "TestUtils.h"

#include <utils/Color.h>

namespace android {
namespace uirenderer {
namespace test {

void TestListViewSceneBase::createContent(int width, int height, TestCanvas& canvas) {
    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 setup = std::bind(&TestListViewSceneBase::createListItem, this, std::placeholders::_1,
                std::placeholders::_2, id, mItemWidth, mItemHeight);
        auto node = TestUtils::createNode(mItemLeft, y, mItemLeft + mItemWidth,
                y + mItemHeight, setup);
        mListItems.push_back(node);
    }
    mListView = TestUtils::createNode(0, 0, width, height,
            [this](RenderProperties& props, TestCanvas& canvas) {
        for (size_t ci = 0; ci < mListItems.size(); ci++) {
            canvas.drawRenderNode(mListItems[ci].get());
        }
    });

    canvas.drawColor(Color::Grey_500, SkXfermode::kSrcOver_Mode);
    canvas.drawRenderNode(mListView.get());
}

void TestListViewSceneBase::doFrame(int frameNr) {
    int scrollPx = dp(frameNr) * 3;
    int itemIndexOffset = scrollPx / (mItemSpacing + mItemHeight);
    int pxOffset = -(scrollPx % (mItemSpacing + mItemHeight));

    TestCanvas canvas(
            mListView->stagingProperties().getWidth(),
            mListView->stagingProperties().getHeight());
    for (size_t ci = 0; ci < mListItems.size(); ci++) {
        // update item position
        auto listItem = mListItems[(ci + itemIndexOffset) % mListItems.size()];
        int top = ((int)ci) * (mItemSpacing + mItemHeight) + pxOffset;
        listItem->mutateStagingProperties().setLeftTopRightBottom(
                mItemLeft, top, mItemLeft + mItemWidth, top + mItemHeight);
        listItem->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);

        // draw it to parent DisplayList
        canvas.drawRenderNode(mListItems[ci].get());
    }
    mListView->setStagingDisplayList(canvas.finishRecording(), nullptr);
}

} // namespace test
} // namespace uirenderer
} // namespace android
+44 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.
 */
#pragma once

#include "TestScene.h"
#include <RenderNode.h>
#include <RenderProperties.h>

namespace android {
namespace uirenderer {
namespace test {

class TestListViewSceneBase : public TestScene {
public:
    virtual void createListItem(RenderProperties& props, TestCanvas& canvas, int id,
            int itemWidth, int itemHeight) = 0;
private:
    int mItemHeight;
    int mItemSpacing;
    int mItemWidth;
    int mItemLeft;
    sp<RenderNode> mListView;
    std::vector< sp<RenderNode> > mListItems;

    void createContent(int width, int height, TestCanvas& canvas) override;
    void doFrame(int frameNr) override;
};

} // namespace test
} // namespace uirenderer
} // namespace android
+60 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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 "TestSceneBase.h"
#include "tests/common/TestListViewSceneBase.h"

#include <SkGradientShader.h>

class ListOfFadedTextAnimation;

static TestScene::Registrar _ListOfFadedTextAnimation(TestScene::Info{
    "fadingedges",
    "A mock ListView of scrolling text with faded edge. Doesn't re-bind/re-record views"
    "as they are recycled, so won't upload much content (either glyphs, or bitmaps).",
    TestScene::simpleCreateScene<ListOfFadedTextAnimation>
});

class ListOfFadedTextAnimation : public TestListViewSceneBase {
    void createListItem(RenderProperties& props, TestCanvas& canvas, int id,
            int itemWidth, int itemHeight)  override {
        canvas.drawColor(Color::White, SkXfermode::kSrcOver_Mode);
        int length = dp(100);
        canvas.saveLayer(0, 0, length, itemHeight, nullptr, SaveFlags::HasAlphaLayer);
        SkPaint textPaint;
        textPaint.setTextSize(dp(20));
        textPaint.setAntiAlias(true);
        TestUtils::drawUtf8ToCanvas(&canvas, "not that long long text", textPaint, dp(10), dp(30));

        SkPoint pts[2];
        pts[0].set(0, 0);
        pts[1].set(0, 1);

        SkColor colors[2] = {Color::Black, Color::Transparent};
        SkAutoTUnref<SkShader> s(SkGradientShader::CreateLinear(pts, colors, NULL, 2,
                SkShader::kClamp_TileMode));

        SkMatrix matrix;
        matrix.setScale(1, length);
        matrix.postRotate(-90);
        SkPaint fadingPaint;
        fadingPaint.setShader(s->newWithLocalMatrix(matrix))->unref();
        SkXfermode* mode = SkXfermode::Create(SkXfermode::kDstOut_Mode);
        fadingPaint.setXfermode(mode);
        canvas.drawRect(0, 0, length, itemHeight, fadingPaint);
        canvas.restore();
    }
};
+29 −82
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
 */

#include "TestSceneBase.h"
#include "utils/Color.h"
#include "tests/common/TestListViewSceneBase.h"

#include <cstdio>

@@ -28,58 +28,8 @@ static TestScene::Registrar _ListView(TestScene::Info{
    TestScene::simpleCreateScene<ListViewAnimation>
});

class ListViewAnimation : public TestScene {
public:
    int cardHeight;
    int cardSpacing;
    int cardWidth;
    int cardLeft;
    sp<RenderNode> listView;
    std::vector< sp<RenderNode> > cards;
    void createContent(int width, int height, TestCanvas& canvas) override {
        srand(0);
        cardHeight = dp(60);
        cardSpacing = dp(16);
        cardWidth = std::min((height - cardSpacing * 2), (int)dp(300));
        cardLeft = (width - cardWidth) / 2;

        for (int y = 0; y < height + (cardHeight + cardSpacing - 1); y += (cardHeight + cardSpacing)) {
            cards.push_back(createCard(cards.size(), y));
        }
        listView = TestUtils::createNode(0, 0, width, height,
                [this](RenderProperties& props, TestCanvas& canvas) {
            for (size_t ci = 0; ci < cards.size(); ci++) {
                canvas.drawRenderNode(cards[ci].get());
            }
        });

        canvas.drawColor(Color::Grey_500, SkXfermode::kSrcOver_Mode);
        canvas.drawRenderNode(listView.get());
    }

    void doFrame(int frameNr) override {
        int scrollPx = dp(frameNr) * 3;
        int cardIndexOffset = scrollPx / (cardSpacing + cardHeight);
        int pxOffset = -(scrollPx % (cardSpacing + cardHeight));

        TestCanvas canvas(
                listView->stagingProperties().getWidth(),
                listView->stagingProperties().getHeight());
        for (size_t ci = 0; ci < cards.size(); ci++) {
            // update card position
            auto card = cards[(ci + cardIndexOffset) % cards.size()];
            int top = ((int)ci) * (cardSpacing + cardHeight) + pxOffset;
            card->mutateStagingProperties().setLeftTopRightBottom(
                    cardLeft, top, cardLeft + cardWidth, top + cardHeight);
            card->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);

            // draw it to parent DisplayList
            canvas.drawRenderNode(cards[ci].get());
        }
        listView->setStagingDisplayList(canvas.finishRecording(), nullptr);
    }
private:
    SkBitmap createRandomCharIcon() {
class ListViewAnimation : public TestListViewSceneBase {
    SkBitmap createRandomCharIcon(int cardHeight) {
        int size = cardHeight - (dp(10) * 2);
        SkBitmap bitmap = TestUtils::createSkBitmap(size, size);
        SkCanvas canvas(bitmap);
@@ -120,17 +70,15 @@ private:
        return bitmap;
    }

    sp<RenderNode> createCard(int cardId, int top) {
        return TestUtils::createNode(cardLeft, top, cardLeft + cardWidth, top + cardHeight,
                [this, cardId](RenderProperties& props, TestCanvas& canvas) {
    void createListItem(RenderProperties& props, TestCanvas& canvas, int cardId,
            int itemWidth, int itemHeight) override {
        static SkBitmap filledBox = createBoxBitmap(true);
        static SkBitmap strokedBox = createBoxBitmap(false);

        // TODO: switch to using round rect clipping, once merging correctly handles that
        SkPaint roundRectPaint;
        roundRectPaint.setAntiAlias(true);
        roundRectPaint.setColor(Color::White);
            canvas.drawRoundRect(0, 0, cardWidth, cardHeight, dp(6), dp(6), roundRectPaint);
        canvas.drawRoundRect(0, 0, itemWidth, itemHeight, dp(6), dp(6), roundRectPaint);

        SkPaint textPaint;
        textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
@@ -139,15 +87,14 @@ private:
        textPaint.setAntiAlias(true);
        char buf[256];
        snprintf(buf, sizeof(buf), "This card is #%d", cardId);
            TestUtils::drawUtf8ToCanvas(&canvas, buf, textPaint, cardHeight, dp(25));
        TestUtils::drawUtf8ToCanvas(&canvas, buf, textPaint, itemHeight, dp(25));
        textPaint.setTextSize(dp(15));
        TestUtils::drawUtf8ToCanvas(&canvas, "This is some more text on the card", textPaint,
                    cardHeight, dp(45));
                itemHeight, dp(45));

            canvas.drawBitmap(createRandomCharIcon(), dp(10), dp(10), nullptr);
        canvas.drawBitmap(createRandomCharIcon(itemHeight), dp(10), dp(10), nullptr);

        const SkBitmap& boxBitmap = rand() % 2 ? filledBox : strokedBox;
            canvas.drawBitmap(boxBitmap, cardWidth - dp(10) - boxBitmap.width(), dp(10), nullptr);
        });
        canvas.drawBitmap(boxBitmap, itemWidth - dp(10) - boxBitmap.width(), dp(10), nullptr);
    }
};