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

Commit dfabfea7 authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Add ListView rendering benchmark"

parents 362ab0dd 54fa17f6
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -1383,7 +1383,10 @@ class DrawRenderNodeOp : public DrawBoundedOp {
    friend class TestUtils;
    friend class TestUtils;
public:
public:
    DrawRenderNodeOp(RenderNode* renderNode, const mat4& transformFromParent, bool clipIsSimple)
    DrawRenderNodeOp(RenderNode* renderNode, const mat4& transformFromParent, bool clipIsSimple)
            : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr)
            : DrawBoundedOp(0, 0,
                    renderNode->stagingProperties().getWidth(),
                    renderNode->stagingProperties().getHeight(),
                    nullptr)
            , renderNode(renderNode)
            , renderNode(renderNode)
            , mRecordedWithPotentialStencilClip(!clipIsSimple || !transformFromParent.isSimple())
            , mRecordedWithPotentialStencilClip(!clipIsSimple || !transformFromParent.isSimple())
            , localMatrix(transformFromParent)
            , localMatrix(transformFromParent)
+16 −15
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@
#include "FrameInfoVisualizer.h"
#include "FrameInfoVisualizer.h"


#include "OpenGLRenderer.h"
#include "OpenGLRenderer.h"
#include "utils/Color.h"


#include <cutils/compiler.h>
#include <cutils/compiler.h>
#include <array>
#include <array>
@@ -27,19 +28,19 @@
#define PROFILE_DRAW_THRESHOLD_STROKE_WIDTH 2
#define PROFILE_DRAW_THRESHOLD_STROKE_WIDTH 2
#define PROFILE_DRAW_DP_PER_MS 7
#define PROFILE_DRAW_DP_PER_MS 7


namespace android {
namespace uirenderer {

// Must be NUM_ELEMENTS in size
// Must be NUM_ELEMENTS in size
static const SkColor THRESHOLD_COLOR = 0xff5faa4d;
static const SkColor THRESHOLD_COLOR = Color::Green_500;
static const SkColor BAR_FAST_ALPHA = 0x8F000000;
static const SkColor BAR_FAST_MASK = 0x8FFFFFFF;
static const SkColor BAR_JANKY_ALPHA = 0xDF000000;
static const SkColor BAR_JANKY_MASK = 0xDFFFFFFF;


// We could get this from TimeLord and use the actual frame interval, but
// We could get this from TimeLord and use the actual frame interval, but
// this is good enough
// this is good enough
#define FRAME_THRESHOLD 16
#define FRAME_THRESHOLD 16
#define FRAME_THRESHOLD_NS 16000000
#define FRAME_THRESHOLD_NS 16000000


namespace android {
namespace uirenderer {

struct BarSegment {
struct BarSegment {
    FrameInfoIndex start;
    FrameInfoIndex start;
    FrameInfoIndex end;
    FrameInfoIndex end;
@@ -47,13 +48,13 @@ struct BarSegment {
};
};


static const std::array<BarSegment,7> Bar {{
static const std::array<BarSegment,7> Bar {{
    { FrameInfoIndex::IntendedVsync, FrameInfoIndex::HandleInputStart, 0x00796B },
    { FrameInfoIndex::IntendedVsync, FrameInfoIndex::HandleInputStart, Color::Teal_700 },
    { FrameInfoIndex::HandleInputStart, FrameInfoIndex::PerformTraversalsStart, 0x388E3C },
    { FrameInfoIndex::HandleInputStart, FrameInfoIndex::PerformTraversalsStart, Color::Green_700 },
    { FrameInfoIndex::PerformTraversalsStart, FrameInfoIndex::DrawStart, 0x689F38},
    { FrameInfoIndex::PerformTraversalsStart, FrameInfoIndex::DrawStart, Color::LightGreen_700 },
    { FrameInfoIndex::DrawStart, FrameInfoIndex::SyncStart, 0x2196F3},
    { FrameInfoIndex::DrawStart, FrameInfoIndex::SyncStart, Color::Blue_500 },
    { FrameInfoIndex::SyncStart, FrameInfoIndex::IssueDrawCommandsStart, 0x4FC3F7},
    { FrameInfoIndex::SyncStart, FrameInfoIndex::IssueDrawCommandsStart, Color::LightBlue_300 },
    { FrameInfoIndex::IssueDrawCommandsStart, FrameInfoIndex::SwapBuffers, 0xF44336},
    { FrameInfoIndex::IssueDrawCommandsStart, FrameInfoIndex::SwapBuffers, Color::Red_500},
    { FrameInfoIndex::SwapBuffers, FrameInfoIndex::FrameCompleted, 0xFF9800},
    { FrameInfoIndex::SwapBuffers, FrameInfoIndex::FrameCompleted, Color::Orange_500},
}};
}};


static int dpToPx(int dp, float density) {
static int dpToPx(int dp, float density) {
@@ -197,9 +198,9 @@ void FrameInfoVisualizer::drawGraph(OpenGLRenderer* canvas) {
    SkPaint paint;
    SkPaint paint;
    for (size_t i = 0; i < Bar.size(); i++) {
    for (size_t i = 0; i < Bar.size(); i++) {
        nextBarSegment(Bar[i].start, Bar[i].end);
        nextBarSegment(Bar[i].start, Bar[i].end);
        paint.setColor(Bar[i].color | BAR_FAST_ALPHA);
        paint.setColor(Bar[i].color & BAR_FAST_MASK);
        canvas->drawRects(mFastRects.get(), mNumFastRects * 4, &paint);
        canvas->drawRects(mFastRects.get(), mNumFastRects * 4, &paint);
        paint.setColor(Bar[i].color | BAR_JANKY_ALPHA);
        paint.setColor(Bar[i].color & BAR_JANKY_MASK);
        canvas->drawRects(mJankyRects.get(), mNumJankyRects * 4, &paint);
        canvas->drawRects(mJankyRects.get(), mNumJankyRects * 4, &paint);
    }
    }
}
}
+2 −1
Original line number Original line Diff line number Diff line
@@ -435,8 +435,9 @@ void RecordingCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
            refPaint(paint), refBitmap(*bitmap)));
            refPaint(paint), refBitmap(*bitmap)));
}
}
void RecordingCanvas::drawRenderNode(RenderNode* renderNode) {
void RecordingCanvas::drawRenderNode(RenderNode* renderNode) {
    auto&& stagingProps = renderNode->stagingProperties();
    RenderNodeOp* op = new (alloc()) RenderNodeOp(
    RenderNodeOp* op = new (alloc()) RenderNodeOp(
            Rect(0, 0, renderNode->getWidth(), renderNode->getHeight()), // are these safe? they're theoretically dynamic
            Rect(stagingProps.getWidth(), stagingProps.getHeight()),
            *(mState.currentSnapshot()->transform),
            *(mState.currentSnapshot()->transform),
            mState.getRenderTargetClipBounds(),
            mState.getRenderTargetClipBounds(),
            renderNode);
            renderNode);
+146 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2015 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 "utils/Color.h"

#include <cstdio>

class ListViewAnimation;

static Benchmark _ListView(BenchmarkInfo{
    "listview",
    "A mock ListView of scrolling content. Doesn't re-bind/re-record views as they are recycled, so"
    "won't upload much content (either glyphs, or bitmaps).",
    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(cardWidth, cardHeight);
        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());
    }
private:
    SkBitmap createRandomCharIcon() {
        int size = cardHeight - (dp(10) * 2);
        SkBitmap bitmap = TestUtils::createSkBitmap(size, size);
        SkCanvas canvas(bitmap);
        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);
        paint.setTextAlign(SkPaint::kCenter_Align);
        paint.setTextSize(size / 2);
        char charToShow = 'A' + (rand() % 26);
        canvas.drawText(&charToShow, 1, size / 2, /*approximate centering*/ size * 0.7, paint);
        return bitmap;
    }

    static SkBitmap createBoxBitmap(bool filled) {
        int size = dp(20);
        int stroke = dp(2);
        SkBitmap bitmap = TestUtils::createSkBitmap(size, size);
        SkCanvas canvas(bitmap);
        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;
    }

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

            props.mutableOutline().setRoundRect(0, 0, cardWidth, cardHeight, dp(6), 1);
            props.mutableOutline().setShouldClip(true);
            canvas.drawColor(Color::White, SkXfermode::kSrcOver_Mode);

            SkPaint textPaint;
            textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
            textPaint.setColor(rand() % 2 ? Color::Black : Color::Grey_500);
            textPaint.setTextSize(dp(20));
            textPaint.setAntiAlias(true);
            char buf[256];
            snprintf(buf, sizeof(buf), "This card is #%d", cardId);
            TestUtils::drawTextToCanvas(&canvas, buf, textPaint, cardHeight, dp(25));
            textPaint.setTextSize(dp(15));
            TestUtils::drawTextToCanvas(&canvas, "This is some more text on the card", textPaint,
                    cardHeight, dp(45));

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

            const SkBitmap& boxBitmap = rand() % 2 ? filledBox : strokedBox;
            canvas.drawBitmap(boxBitmap, cardWidth - dp(10) - boxBitmap.width(), dp(10), nullptr);
        });
    }
};
+8 −7
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
 */
 */


#include "TestSceneBase.h"
#include "TestSceneBase.h"
#include "utils/Color.h"


class RecentsAnimation;
class RecentsAnimation;


@@ -29,16 +30,16 @@ class RecentsAnimation : public TestScene {
public:
public:
    void createContent(int width, int height, TestCanvas& renderer) override {
    void createContent(int width, int height, TestCanvas& renderer) override {
        static SkColor COLORS[] = {
        static SkColor COLORS[] = {
                0xFFF44336,
                Color::Red_500,
                0xFF9C27B0,
                Color::Purple_500,
                0xFF2196F3,
                Color::Blue_500,
                0xFF4CAF50,
                Color::Green_500,
        };
        };


        thumbnailSize = std::min(std::min(width, height) / 2, 720);
        thumbnailSize = std::min(std::min(width, height) / 2, 720);
        int cardsize = std::min(width, height) - dp(64);
        int cardsize = std::min(width, height) - dp(64);


        renderer.drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
        renderer.drawColor(Color::White, SkXfermode::kSrcOver_Mode);
        renderer.insertReorderBarrier(true);
        renderer.insertReorderBarrier(true);


        int x = dp(32);
        int x = dp(32);
@@ -63,7 +64,7 @@ public:
            mCards[ci]->setPropertyFieldsDirty(RenderNode::Y);
            mCards[ci]->setPropertyFieldsDirty(RenderNode::Y);
        }
        }
        mThumbnail.eraseColor(TestUtils::interpolateColor(
        mThumbnail.eraseColor(TestUtils::interpolateColor(
                curFrame / 150.0f, 0xFF4CAF50, 0xFFFF5722));
                curFrame / 150.0f, Color::Green_500, Color::DeepOrange_500));
    }
    }


private:
private:
@@ -75,7 +76,7 @@ private:
            props.mutableOutline().setRoundRect(0, 0, width, height, dp(10), 1);
            props.mutableOutline().setRoundRect(0, 0, width, height, dp(10), 1);
            props.mutableOutline().setShouldClip(true);
            props.mutableOutline().setShouldClip(true);


            canvas.drawColor(0xFFEEEEEE, SkXfermode::kSrcOver_Mode);
            canvas.drawColor(Color::Grey_200, SkXfermode::kSrcOver_Mode);
            canvas.drawBitmap(thumb, 0, 0, thumb.width(), thumb.height(),
            canvas.drawBitmap(thumb, 0, 0, thumb.width(), thumb.height(),
                    0, 0, width, height, nullptr);
                    0, 0, width, height, nullptr);
        });
        });
Loading