ListViewAnimation.cpp revision 15c3f19a445b8df575911a16e8a6dba755a084b5
154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik/* 254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * Copyright (C) 2015 The Android Open Source Project 354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * 454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * you may not use this file except in compliance with the License. 654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * You may obtain a copy of the License at 754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * 854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * http://www.apache.org/licenses/LICENSE-2.0 954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * 1054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * Unless required by applicable law or agreed to in writing, software 1154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * distributed under the License is distributed on an "AS IS" BASIS, 1254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * See the License for the specific language governing permissions and 1454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik * limitations under the License. 1554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik */ 1654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 1754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik#include "TestSceneBase.h" 1854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik#include "utils/Color.h" 1954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 2054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik#include <cstdio> 2154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 2254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craikclass ListViewAnimation; 2354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 2454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craikstatic Benchmark _ListView(BenchmarkInfo{ 2554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik "listview", 2654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik "A mock ListView of scrolling content. Doesn't re-bind/re-record views as they are recycled, so" 2754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik "won't upload much content (either glyphs, or bitmaps).", 2854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik simpleCreateScene<ListViewAnimation> 2954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik}); 3054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 3154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craikclass ListViewAnimation : public TestScene { 3254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craikpublic: 3354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik int cardHeight; 3454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik int cardSpacing; 3554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik int cardWidth; 3654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik int cardLeft; 3754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik sp<RenderNode> listView; 3854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik std::vector< sp<RenderNode> > cards; 3954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik void createContent(int width, int height, TestCanvas& canvas) override { 4054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik srand(0); 4154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik cardHeight = dp(60); 4254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik cardSpacing = dp(16); 4354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik cardWidth = std::min((height - cardSpacing * 2), (int)dp(300)); 4454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik cardLeft = (width - cardWidth) / 2; 4554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 4654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik for (int y = 0; y < height + (cardHeight + cardSpacing - 1); y += (cardHeight + cardSpacing)) { 4754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik cards.push_back(createCard(cards.size(), y)); 4854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik } 4954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik listView = TestUtils::createNode(0, 0, width, height, 5054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik [this](RenderProperties& props, TestCanvas& canvas) { 5154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik for (size_t ci = 0; ci < cards.size(); ci++) { 5254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik canvas.drawRenderNode(cards[ci].get()); 5354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik } 5454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik }); 5554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 5654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik canvas.drawColor(Color::Grey_500, SkXfermode::kSrcOver_Mode); 5754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik canvas.drawRenderNode(listView.get()); 5854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik } 5954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 6054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik void doFrame(int frameNr) override { 6154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik int scrollPx = dp(frameNr) * 3; 6254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik int cardIndexOffset = scrollPx / (cardSpacing + cardHeight); 6354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik int pxOffset = -(scrollPx % (cardSpacing + cardHeight)); 6454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 6515c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik TestCanvas canvas( 6615c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik listView->stagingProperties().getWidth(), 6715c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik listView->stagingProperties().getHeight()); 6854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik for (size_t ci = 0; ci < cards.size(); ci++) { 6954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik // update card position 7054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik auto card = cards[(ci + cardIndexOffset) % cards.size()]; 7154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik int top = ((int)ci) * (cardSpacing + cardHeight) + pxOffset; 7254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik card->mutateStagingProperties().setLeftTopRightBottom( 7354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik cardLeft, top, cardLeft + cardWidth, top + cardHeight); 7454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik card->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); 7554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 7654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik // draw it to parent DisplayList 7754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik canvas.drawRenderNode(cards[ci].get()); 7854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik } 7954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik listView->setStagingDisplayList(canvas.finishRecording()); 8054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik } 8154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craikprivate: 8254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik SkBitmap createRandomCharIcon() { 8354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik int size = cardHeight - (dp(10) * 2); 8454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik SkBitmap bitmap = TestUtils::createSkBitmap(size, size); 8554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik SkCanvas canvas(bitmap); 8654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik canvas.clear(0); 8754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 8854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik SkPaint paint; 8954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik paint.setAntiAlias(true); 9054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik SkColor randomColor = BrightColors[rand() % BrightColorsCount]; 9154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik paint.setColor(randomColor); 9254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik canvas.drawCircle(size / 2, size / 2, size / 2, paint); 9354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 9454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik bool bgDark = SkColorGetR(randomColor) + SkColorGetG(randomColor) + SkColorGetB(randomColor) 9554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik < 128 * 3; 9654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik paint.setColor(bgDark ? Color::White : Color::Grey_700); 9754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik paint.setTextAlign(SkPaint::kCenter_Align); 9854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik paint.setTextSize(size / 2); 9954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik char charToShow = 'A' + (rand() % 26); 10054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik canvas.drawText(&charToShow, 1, size / 2, /*approximate centering*/ size * 0.7, paint); 10154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik return bitmap; 10254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik } 10354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 10454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik static SkBitmap createBoxBitmap(bool filled) { 10554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik int size = dp(20); 10654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik int stroke = dp(2); 10754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik SkBitmap bitmap = TestUtils::createSkBitmap(size, size); 10854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik SkCanvas canvas(bitmap); 10954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik canvas.clear(Color::Transparent); 11054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 11154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik SkPaint paint; 11254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik paint.setAntiAlias(true); 11354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik paint.setColor(filled ? Color::Yellow_500 : Color::Grey_700); 11454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik paint.setStyle(filled ? SkPaint::kStrokeAndFill_Style : SkPaint::kStroke_Style); 11554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik paint.setStrokeWidth(stroke); 11654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik canvas.drawRect(SkRect::MakeLTRB(stroke, stroke, size - stroke, size - stroke), paint); 11754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik return bitmap; 11854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik } 11954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 12054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik sp<RenderNode> createCard(int cardId, int top) { 12154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik return TestUtils::createNode(cardLeft, top, cardLeft + cardWidth, top + cardHeight, 12254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik [this, cardId](RenderProperties& props, TestCanvas& canvas) { 12354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik static SkBitmap filledBox = createBoxBitmap(true); 12454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik static SkBitmap strokedBox = createBoxBitmap(false); 12554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 12615c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik // TODO: switch to using round rect clipping, once merging correctly handles that 12715c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik SkPaint roundRectPaint; 12815c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik roundRectPaint.setAntiAlias(true); 12915c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik roundRectPaint.setColor(Color::White); 13015c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik canvas.drawRoundRect(0, 0, cardWidth, cardHeight, dp(6), dp(6), roundRectPaint); 13154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 13254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik SkPaint textPaint; 13354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 13454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik textPaint.setColor(rand() % 2 ? Color::Black : Color::Grey_500); 13554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik textPaint.setTextSize(dp(20)); 13654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik textPaint.setAntiAlias(true); 13754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik char buf[256]; 13854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik snprintf(buf, sizeof(buf), "This card is #%d", cardId); 13954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik TestUtils::drawTextToCanvas(&canvas, buf, textPaint, cardHeight, dp(25)); 14054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik textPaint.setTextSize(dp(15)); 14154fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik TestUtils::drawTextToCanvas(&canvas, "This is some more text on the card", textPaint, 14254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik cardHeight, dp(45)); 14354fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 14454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik canvas.drawBitmap(createRandomCharIcon(), dp(10), dp(10), nullptr); 14554fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik 14654fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik const SkBitmap& boxBitmap = rand() % 2 ? filledBox : strokedBox; 14754fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik canvas.drawBitmap(boxBitmap, cardWidth - dp(10) - boxBitmap.width(), dp(10), nullptr); 14854fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik }); 14954fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik } 15054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik}; 151