summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/hwui/tests/common/scenes/TvApp.cpp274
1 files changed, 274 insertions, 0 deletions
diff --git a/libs/hwui/tests/common/scenes/TvApp.cpp b/libs/hwui/tests/common/scenes/TvApp.cpp
new file mode 100644
index 000000000000..04fc2d46f946
--- /dev/null
+++ b/libs/hwui/tests/common/scenes/TvApp.cpp
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2017 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/BitmapAllocationTestUtils.h"
+#include "SkBlendMode.h"
+
+class TvApp;
+class TvAppNoRoundedCorner;
+class TvAppColorFilter;
+class TvAppNoRoundedCornerColorFilter;
+
+static bool _TvApp(
+ BitmapAllocationTestUtils::registerBitmapAllocationScene<TvApp>(
+ "tvapp", "A dense grid of cards:"
+ "with rounded corner, using overlay RenderNode for dimming."));
+
+static bool _TvAppNoRoundedCorner(
+ BitmapAllocationTestUtils::registerBitmapAllocationScene<TvAppNoRoundedCorner>(
+ "tvapp_norc", "A dense grid of cards:"
+ "no rounded corner, using overlay RenderNode for dimming"));
+
+static bool _TvAppColorFilter(
+ BitmapAllocationTestUtils::registerBitmapAllocationScene<TvAppColorFilter>(
+ "tvapp_cf", "A dense grid of cards:"
+ "with rounded corner, using ColorFilter for dimming"));
+
+static bool _TvAppNoRoundedCornerColorFilter(
+ BitmapAllocationTestUtils::registerBitmapAllocationScene<TvAppNoRoundedCornerColorFilter>(
+ "tvapp_norc_cf", "A dense grid of cards:"
+ "no rounded corner, using ColorFilter for dimming"));
+
+class TvApp : public TestScene {
+public:
+ TvApp(BitmapAllocationTestUtils::BitmapAllocator allocator)
+ : TestScene()
+ , mAllocator(allocator) { }
+
+ sp<RenderNode> mBg;
+ std::vector<sp<RenderNode>> mCards;
+ std::vector<sp<RenderNode>> mInfoAreas;
+ std::vector<sp<RenderNode>> mImages;
+ std::vector<sp<RenderNode>> mOverlays;
+ std::vector<sk_sp<Bitmap>> mCachedBitmaps;
+ BitmapAllocationTestUtils::BitmapAllocator mAllocator;
+ sk_sp<Bitmap> mSingleBitmap;
+ int mSeed = 0;
+ int mSeed2 = 0;
+
+ void createContent(int width, int height, Canvas& canvas) override {
+ mBg = createBitmapNode(canvas, 0xFF9C27B0, 0, 0, width, height);
+ canvas.drawRenderNode(mBg.get());
+
+ canvas.insertReorderBarrier(true);
+ mSingleBitmap = mAllocator(dp(160), dp(120), kRGBA_8888_SkColorType,
+ [](SkBitmap& skBitmap) {
+ skBitmap.eraseColor(0xFF0000FF);
+ });
+
+ for (int y = dp(18) - dp(178); y < height - dp(18); y += dp(178)) {
+ bool isFirstCard = true;
+ for (int x = dp(18); x < width - dp(18); x += dp(178)) {
+ sp<RenderNode> card = createCard(x, y, dp(160), dp(160), isFirstCard);
+ isFirstCard = false;
+ canvas.drawRenderNode(card.get());
+ mCards.push_back(card);
+ }
+ }
+ canvas.insertReorderBarrier(false);
+ }
+
+ void doFrame(int frameNr) override {
+ size_t numCards = mCards.size();
+ for (size_t ci = 0; ci < numCards; ci++) {
+ updateCard(ci, frameNr);
+ }
+ }
+
+private:
+ sp<RenderNode> createBitmapNode(Canvas& canvas, SkColor color, int left, int top,
+ int width, int height) {
+ return TestUtils::createNode(left, top, left + width , top + height,
+ [this, width, height, color](RenderProperties& props, Canvas& canvas) {
+ sk_sp<Bitmap> bitmap = mAllocator(width, height, kRGBA_8888_SkColorType,
+ [color](SkBitmap& skBitmap) {
+ skBitmap.eraseColor(color);
+ });
+ canvas.drawBitmap(*bitmap, 0, 0, nullptr);
+ });
+ }
+
+ sp<RenderNode> createSharedBitmapNode(Canvas& canvas, int left, int top,
+ int width, int height, sk_sp<Bitmap>bitmap) {
+ return TestUtils::createNode(left, top, left + width , top + height,
+ [bitmap](RenderProperties& props, Canvas& canvas) {
+ canvas.drawBitmap(*bitmap, 0, 0, nullptr);
+ });
+ }
+
+ sp<RenderNode> createInfoNode(Canvas& canvas, int left, int top,
+ int width, int height, const char* text, const char* text2) {
+ return TestUtils::createNode(left, top, left + width , top + height,
+ [text, text2](RenderProperties& props, Canvas& canvas) {
+ canvas.drawColor(0xFFFFEEEE, SkBlendMode::kSrcOver);
+
+ SkPaint paint;
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ paint.setAntiAlias(true);
+ paint.setTextSize(24);
+
+ paint.setColor(Color::Black);
+ TestUtils::drawUtf8ToCanvas(&canvas, text, paint, 10, 30);
+ paint.setTextSize(20);
+ TestUtils::drawUtf8ToCanvas(&canvas, text2, paint, 10, 54);
+
+ });
+ }
+
+ sp<RenderNode> createColorNode(Canvas& canvas, int left, int top,
+ int width, int height, SkColor color) {
+ return TestUtils::createNode(left, top, left + width , top + height,
+ [color](RenderProperties& props, Canvas& canvas) {
+ canvas.drawColor(color, SkBlendMode::kSrcOver);
+ });
+ }
+
+ virtual bool useSingleBitmap() {
+ return false;
+ }
+
+ virtual float roundedCornerRadius() {
+ return dp(2);
+ }
+
+ // when true, use overlay RenderNode for dimming, otherwise apply a ColorFilter to dim image
+ virtual bool useOverlay() {
+ return true;
+ }
+
+ sp<RenderNode> createCard(int x, int y, int width, int height, bool selected) {
+ return TestUtils::createNode(x, y, x + width, y + height,
+ [width, height, selected, this](RenderProperties& props, Canvas& canvas) {
+ if (selected) {
+ props.setElevation(dp(16));
+ props.setScaleX(1.2);
+ props.setScaleY(1.2);
+ }
+ props.mutableOutline().setRoundRect(0, 0, width, height, roundedCornerRadius(), 1);
+ props.mutableOutline().setShouldClip(true);
+
+ sk_sp<Bitmap> bitmap = useSingleBitmap() ? mSingleBitmap
+ : mAllocator(width, dp(120), kRGBA_8888_SkColorType, [this](SkBitmap& skBitmap) {
+ skBitmap.eraseColor(0xFF000000 | ((mSeed << 3) & 0xFF));
+ });
+ sp<RenderNode> cardImage = createSharedBitmapNode(canvas, 0, 0, width, dp(120),
+ bitmap);
+ canvas.drawRenderNode(cardImage.get());
+ mCachedBitmaps.push_back(bitmap);
+ mImages.push_back(cardImage);
+
+ char buffer[128];
+ sprintf(buffer, "Video %d-%d", mSeed, mSeed + 1);
+ mSeed++;
+ char buffer2[128];
+ sprintf(buffer2, "Studio %d", mSeed2++);
+ sp<RenderNode> infoArea = createInfoNode(canvas, 0, dp(120), width, height, buffer, buffer2);
+ canvas.drawRenderNode(infoArea.get());
+ mInfoAreas.push_back(infoArea);
+
+ if (useOverlay()) {
+ sp<RenderNode> overlayColor = createColorNode(canvas, 0, 0, width, height, 0x00000000);
+ canvas.drawRenderNode(overlayColor.get());
+ mOverlays.push_back(overlayColor);
+ }
+ });
+ }
+
+ void updateCard(int ci, int curFrame) {
+ // updating card's translation Y
+ sp<RenderNode> card = mCards[ci];
+ card->setPropertyFieldsDirty(RenderNode::Y);
+ card->mutateStagingProperties().setTranslationY(curFrame % 150);
+
+ // re-recording card's canvas, not necessary but to add some burden to CPU
+ std::unique_ptr<Canvas> cardcanvas(Canvas::create_recording_canvas(
+ card->stagingProperties().getWidth(),
+ card->stagingProperties().getHeight()));
+ sp<RenderNode> image = mImages[ci];
+ sp<RenderNode> infoArea = mInfoAreas[ci];
+ cardcanvas->drawRenderNode(infoArea.get());
+
+ if (useOverlay()) {
+ cardcanvas->drawRenderNode(image.get());
+ // re-recording card overlay's canvas, animating overlay color alpha
+ sp<RenderNode> overlay = mOverlays[ci];
+ std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(
+ overlay->stagingProperties().getWidth(),
+ overlay->stagingProperties().getHeight()));
+ canvas->drawColor((curFrame % 150) << 24, SkBlendMode::kSrcOver);
+ overlay->setStagingDisplayList(canvas->finishRecording());
+ cardcanvas->drawRenderNode(overlay.get());
+ } else {
+ // re-recording image node's canvas, animating ColorFilter
+ std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(
+ image->stagingProperties().getWidth(),
+ image->stagingProperties().getHeight()));
+ SkPaint paint;
+ sk_sp<SkColorFilter> filter(SkColorFilter::MakeModeFilter((curFrame % 150) << 24,
+ SkBlendMode::kSrcATop));
+ paint.setColorFilter(filter);
+ sk_sp<Bitmap> bitmap = mCachedBitmaps[ci];
+ canvas->drawBitmap(*bitmap, 0, 0, &paint);
+ image->setStagingDisplayList(canvas->finishRecording());
+ cardcanvas->drawRenderNode(image.get());
+ }
+
+ card->setStagingDisplayList(cardcanvas->finishRecording());
+ }
+};
+
+class TvAppNoRoundedCorner : public TvApp {
+public:
+ TvAppNoRoundedCorner(BitmapAllocationTestUtils::BitmapAllocator allocator)
+ : TvApp(allocator) { }
+
+private:
+
+ virtual float roundedCornerRadius() override {
+ return dp(0);
+ }
+};
+
+class TvAppColorFilter : public TvApp {
+public:
+ TvAppColorFilter(BitmapAllocationTestUtils::BitmapAllocator allocator)
+ : TvApp(allocator) { }
+
+private:
+
+ virtual bool useOverlay() override {
+ return false;
+ }
+};
+
+class TvAppNoRoundedCornerColorFilter : public TvApp {
+public:
+ TvAppNoRoundedCornerColorFilter(BitmapAllocationTestUtils::BitmapAllocator allocator)
+ : TvApp(allocator) { }
+
+private:
+
+ virtual float roundedCornerRadius() override {
+ return dp(0);
+ }
+
+ virtual bool useOverlay() override {
+ return false;
+ }
+};
+
+