TestUtils.h revision 52771272f4f018f4fc6846224bf047497e784af1
1b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler/* 2b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * Copyright (C) 2015 The Android Open Source Project 3b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * 4b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * Licensed under the Apache License, Version 2.0 (the "License"); 5b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * you may not use this file except in compliance with the License. 6b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * You may obtain a copy of the License at 7b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * 8b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * http://www.apache.org/licenses/LICENSE-2.0 9b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * 10b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * Unless required by applicable law or agreed to in writing, software 11b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * distributed under the License is distributed on an "AS IS" BASIS, 12b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * See the License for the specific language governing permissions and 14b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * limitations under the License. 15b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler */ 16b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 17b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#pragma once 18b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 19b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <DeviceInfo.h> 20b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <DisplayList.h> 21b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <Matrix.h> 22b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <Rect.h> 23b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <RenderNode.h> 24b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <hwui/Bitmap.h> 25b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <pipeline/skia/SkiaRecordingCanvas.h> 26b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <renderstate/RenderState.h> 27b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <renderthread/RenderThread.h> 28b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <Snapshot.h> 29b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 30b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <RecordedOp.h> 31b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <RecordingCanvas.h> 32b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 33b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#include <memory> 34b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 35b8592357c37e681ba709b524a7202b7787f35e5aTony Mantlernamespace android { 36b8592357c37e681ba709b524a7202b7787f35e5aTony Mantlernamespace uirenderer { 37b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 38b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#define EXPECT_MATRIX_APPROX_EQ(a, b) \ 39b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler EXPECT_TRUE(TestUtils::matricesAreApproxEqual(a, b)) 40b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 41b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#define EXPECT_RECT_APPROX_EQ(a, b) \ 42b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler EXPECT_TRUE(MathUtils::areEqual((a).left, (b).left) \ 43b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler && MathUtils::areEqual((a).top, (b).top) \ 44b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler && MathUtils::areEqual((a).right, (b).right) \ 45b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler && MathUtils::areEqual((a).bottom, (b).bottom)); 46b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 47b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#define EXPECT_CLIP_RECT(expRect, clipStatePtr) \ 48b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler EXPECT_NE(nullptr, (clipStatePtr)) << "Op is unclipped"; \ 49b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler if ((clipStatePtr)->mode == ClipMode::Rectangle) { \ 50b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler EXPECT_EQ((expRect), reinterpret_cast<const ClipRect*>(clipStatePtr)->rect); \ 51b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } else { \ 52b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler ADD_FAILURE() << "ClipState not a rect"; \ 53b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 54b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler/** 55b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * Like gtest's TEST, but runs on the RenderThread, and 'renderThread' is passed, in top level scope 56b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * (for e.g. accessing its RenderState) 57b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler */ 58b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#define RENDERTHREAD_TEST(test_case_name, test_name) \ 59b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler class test_case_name##_##test_name##_RenderThreadTest { \ 60b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler public: \ 61b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static void doTheThing(renderthread::RenderThread& renderThread); \ 62b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler }; \ 63b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler TEST(test_case_name, test_name) { \ 64b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler TestUtils::runOnRenderThread(test_case_name##_##test_name##_RenderThreadTest::doTheThing); \ 65b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler }; \ 66b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler void test_case_name##_##test_name##_RenderThreadTest::doTheThing(renderthread::RenderThread& renderThread) 67b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 68b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler/** 69b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * Sets a property value temporarily, generally for the duration of a test, restoring the previous 70b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * value when going out of scope. 71b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * 72b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * Can be used e.g. to test behavior only active while Properties::debugOverdraw is enabled. 73b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler */ 74b8592357c37e681ba709b524a7202b7787f35e5aTony Mantlertemplate <typename T> 75b8592357c37e681ba709b524a7202b7787f35e5aTony Mantlerclass ScopedProperty { 76b8592357c37e681ba709b524a7202b7787f35e5aTony Mantlerpublic: 77b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler ScopedProperty(T& property, T newValue) 78b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler : mPropertyPtr(&property) 79b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler , mOldValue(property) { 80b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler property = newValue; 81b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 82b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler ~ScopedProperty() { 83b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler *mPropertyPtr = mOldValue; 84b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 85b8592357c37e681ba709b524a7202b7787f35e5aTony Mantlerprivate: 86b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler T* mPropertyPtr; 87b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler T mOldValue; 88b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler}; 89b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 90b8592357c37e681ba709b524a7202b7787f35e5aTony Mantlerclass TestUtils { 91b8592357c37e681ba709b524a7202b7787f35e5aTony Mantlerpublic: 92b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler class SignalingDtor { 93b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler public: 94b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler SignalingDtor() 95b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler : mSignal(nullptr) {} 96b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler explicit SignalingDtor(int* signal) 97b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler : mSignal(signal) {} 98b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler void setSignal(int* signal) { 99b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler mSignal = signal; 100b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 101b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler ~SignalingDtor() { 102b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler if (mSignal) { 103b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler (*mSignal)++; 104b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 105b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 106b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler private: 107b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler int* mSignal; 108b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler }; 109b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 110b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static bool matricesAreApproxEqual(const Matrix4& a, const Matrix4& b) { 111b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler for (int i = 0; i < 16; i++) { 112b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler if (!MathUtils::areEqual(a[i], b[i])) { 113b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler return false; 114b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 115b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 116b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler return true; 117b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 118b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 119b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static std::unique_ptr<Snapshot> makeSnapshot(const Matrix4& transform, const Rect& clip) { 120b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler std::unique_ptr<Snapshot> snapshot(new Snapshot()); 121b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler // store clip first, so it isn't transformed 122b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler snapshot->setClip(clip.left, clip.top, clip.right, clip.bottom); 123b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler *(snapshot->transform) = transform; 124b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler return snapshot; 125b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 126b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 127b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static sk_sp<Bitmap> createBitmap(int width, int height, 128b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler SkColorType colorType = kN32_SkColorType) { 129b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler SkImageInfo info = SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType); 130b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler return Bitmap::allocateHeapBitmap(info); 131b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 132b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 133b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static sk_sp<Bitmap> createBitmap(int width, int height, SkBitmap* outBitmap) { 134b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler SkImageInfo info = SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType); 135b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler outBitmap->setInfo(info); 136b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler return Bitmap::allocateHeapBitmap(outBitmap, nullptr); 137b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 138b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 139b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static sp<DeferredLayerUpdater> createTextureLayerUpdater( 140b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler renderthread::RenderThread& renderThread, uint32_t width, uint32_t height, 141b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler const SkMatrix& transform); 142b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 143b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler template<class CanvasType> 144b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static std::unique_ptr<DisplayList> createDisplayList(int width, int height, 145b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler std::function<void(CanvasType& canvas)> canvasCallback) { 146b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler CanvasType canvas(width, height); 147b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler canvasCallback(canvas); 148b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler return std::unique_ptr<DisplayList>(canvas.finishRecording()); 149b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 150b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 151b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static sp<RenderNode> createNode(int left, int top, int right, int bottom, 152b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler std::function<void(RenderProperties& props, Canvas& canvas)> setup) { 153b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#if HWUI_NULL_GPU 154b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler // if RenderNodes are being sync'd/used, device info will be needed, since 155b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler // DeviceInfo::maxTextureSize() affects layer property 156b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler DeviceInfo::initialize(); 157b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#endif 158b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 159b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler sp<RenderNode> node = new RenderNode(); 160b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler RenderProperties& props = node->mutateStagingProperties(); 161b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler props.setLeftTopRightBottom(left, top, right, bottom); 162b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler if (setup) { 163b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(props.getWidth(), 164b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler props.getHeight())); 165b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler setup(props, *canvas.get()); 166b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler node->setStagingDisplayList(canvas->finishRecording(), nullptr); 167b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 168b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler node->setPropertyFieldsDirty(0xFFFFFFFF); 169b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler return node; 170b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 171b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 172b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler template<class RecordingCanvasType> 173b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static sp<RenderNode> createNode(int left, int top, int right, int bottom, 174b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler std::function<void(RenderProperties& props, RecordingCanvasType& canvas)> setup) { 175b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#if HWUI_NULL_GPU 176b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler // if RenderNodes are being sync'd/used, device info will be needed, since 177b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler // DeviceInfo::maxTextureSize() affects layer property 178b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler DeviceInfo::initialize(); 179b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler#endif 180b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 181b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler sp<RenderNode> node = new RenderNode(); 182b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler RenderProperties& props = node->mutateStagingProperties(); 183b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler props.setLeftTopRightBottom(left, top, right, bottom); 184b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler if (setup) { 185b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler RecordingCanvasType canvas(props.getWidth(), props.getHeight()); 186b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler setup(props, canvas); 187b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler node->setStagingDisplayList(canvas.finishRecording(), nullptr); 188b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 189b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler node->setPropertyFieldsDirty(0xFFFFFFFF); 190b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler return node; 191b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 192b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 193b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static void recordNode(RenderNode& node, 194b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler std::function<void(Canvas&)> contentCallback) { 195b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas( 196b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler node.stagingProperties().getWidth(), node.stagingProperties().getHeight())); 197b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler contentCallback(*canvas.get()); 198b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler node.setStagingDisplayList(canvas->finishRecording(), nullptr); 199b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 200b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 201b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static sp<RenderNode> createSkiaNode(int left, int top, int right, int bottom, 202b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler std::function<void(RenderProperties& props, skiapipeline::SkiaRecordingCanvas& canvas)> setup, 203b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler const char* name = nullptr, skiapipeline::SkiaDisplayList* displayList = nullptr) { 204b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler #if HWUI_NULL_GPU 205b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler // if RenderNodes are being sync'd/used, device info will be needed, since 206b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler // DeviceInfo::maxTextureSize() affects layer property 207b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler DeviceInfo::initialize(); 208b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler #endif 209b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler sp<RenderNode> node = new RenderNode(); 210b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler if (name) { 211b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler node->setName(name); 212b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 213b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler RenderProperties& props = node->mutateStagingProperties(); 214b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler props.setLeftTopRightBottom(left, top, right, bottom); 215b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler if (displayList) { 216b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler node->setStagingDisplayList(displayList, nullptr); 217b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 218b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler if (setup) { 219b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler std::unique_ptr<skiapipeline::SkiaRecordingCanvas> canvas( 220b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler new skiapipeline::SkiaRecordingCanvas(nullptr, 221b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler props.getWidth(), props.getHeight())); 222b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler setup(props, *canvas.get()); 223b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler node->setStagingDisplayList(canvas->finishRecording(), nullptr); 224b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 225b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler node->setPropertyFieldsDirty(0xFFFFFFFF); 226b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler TestUtils::syncHierarchyPropertiesAndDisplayList(node); 227b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler return node; 228b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 229b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 230b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler /** 231b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * Forces a sync of a tree of RenderNode, such that every descendant will have its staging 232b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * properties and DisplayList moved to the render copies. 233b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * 234b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * Note: does not check dirtiness bits, so any non-staging DisplayLists will be discarded. 235b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * For this reason, this should generally only be called once on a tree. 236b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler */ 237b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static void syncHierarchyPropertiesAndDisplayList(sp<RenderNode>& node) { 238b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler syncHierarchyPropertiesAndDisplayListImpl(node.get()); 239b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 240b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 241b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static sp<RenderNode>& getSyncedNode(sp<RenderNode>& node) { 242b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler syncHierarchyPropertiesAndDisplayList(node); 243b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler return node; 244b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 245b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 246b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler typedef std::function<void(renderthread::RenderThread& thread)> RtCallback; 247b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 248b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler class TestTask : public renderthread::RenderTask { 249b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler public: 250b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler explicit TestTask(RtCallback rtCallback) 251b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler : rtCallback(rtCallback) {} 252b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler virtual ~TestTask() {} 253b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler virtual void run() override; 254b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler RtCallback rtCallback; 255b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler }; 256b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler 257b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler /** 258b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler * NOTE: requires surfaceflinger to run, otherwise this method will wait indefinitely. 259b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler */ 260b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler static void runOnRenderThread(RtCallback rtCallback) { 261b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler TestTask task(rtCallback); 262b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler renderthread::RenderThread::getInstance().queueAndWait(&task); 263b8592357c37e681ba709b524a7202b7787f35e5aTony Mantler } 264 265 static bool isRenderThreadRunning() { 266 return renderthread::RenderThread::hasInstance(); 267 } 268 269 static SkColor interpolateColor(float fraction, SkColor start, SkColor end); 270 271 static void layoutTextUnscaled(const SkPaint& paint, const char* text, 272 std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions, 273 float* outTotalAdvance, Rect* outBounds); 274 275 static void drawUtf8ToCanvas(Canvas* canvas, const char* text, 276 const SkPaint& paint, float x, float y); 277 278 static void drawUtf8ToCanvas(Canvas* canvas, const char* text, 279 const SkPaint& paint, const SkPath& path); 280 281 static std::unique_ptr<uint16_t[]> asciiToUtf16(const char* str); 282 283 class MockFunctor : public Functor { 284 public: 285 virtual status_t operator ()(int what, void* data) { 286 mLastMode = what; 287 return DrawGlInfo::kStatusDone; 288 } 289 int getLastMode() const { return mLastMode; } 290 private: 291 int mLastMode = -1; 292 }; 293 294 static SkColor getColor(const sk_sp<SkSurface>& surface, int x, int y); 295 296 static SkRect getClipBounds(const SkCanvas* canvas); 297 static SkRect getLocalClipBounds(const SkCanvas* canvas); 298 299private: 300 static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) { 301 node->syncProperties(); 302 node->syncDisplayList(nullptr); 303 auto displayList = node->getDisplayList(); 304 if (displayList) { 305 for (auto&& childOp : displayList->getChildren()) { 306 syncHierarchyPropertiesAndDisplayListImpl(childOp->renderNode); 307 } 308 } 309 } 310 311}; // class TestUtils 312 313} /* namespace uirenderer */ 314} /* namespace android */ 315