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

Commit 83b2cb13 authored by Sergei Vasilinetc's avatar Sergei Vasilinetc Committed by Android (Google) Code Review
Browse files

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

parents 4a618f5e 06a62f6f
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);
    }
};