blob: 28e0fd8f3464ddeb8290511d42649e3de7654486 [file] [log] [blame]
Chris Craikb565df12015-10-05 13:00:52 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef TEST_UTILS_H
17#define TEST_UTILS_H
18
Chris Craik76caecf2015-11-02 19:17:45 -080019#include <DeviceInfo.h>
Chris Craik161f54b2015-11-05 11:08:52 -080020#include <DisplayList.h>
Chris Craikb565df12015-10-05 13:00:52 -070021#include <Matrix.h>
Chris Craik0a24b142015-10-19 17:10:19 -070022#include <Rect.h>
Chris Craikb565df12015-10-05 13:00:52 -070023#include <RenderNode.h>
Chris Craik0a24b142015-10-19 17:10:19 -070024#include <renderstate/RenderState.h>
25#include <renderthread/RenderThread.h>
26#include <Snapshot.h>
Chris Craikb565df12015-10-05 13:00:52 -070027
Chris Craik161f54b2015-11-05 11:08:52 -080028#if HWUI_NEW_OPS
29#include <RecordedOp.h>
30#else
31#include <DisplayListOp.h>
32#endif
33
Chris Craikb565df12015-10-05 13:00:52 -070034#include <memory>
35
36namespace android {
37namespace uirenderer {
38
39#define EXPECT_MATRIX_APPROX_EQ(a, b) \
40 EXPECT_TRUE(TestUtils::matricesAreApproxEqual(a, b))
41
Chris Craik6fe991e52015-10-20 09:39:42 -070042#define EXPECT_RECT_APPROX_EQ(a, b) \
43 EXPECT_TRUE(MathUtils::areEqual(a.left, b.left) \
44 && MathUtils::areEqual(a.top, b.top) \
45 && MathUtils::areEqual(a.right, b.right) \
46 && MathUtils::areEqual(a.bottom, b.bottom));
47
Chris Craikb565df12015-10-05 13:00:52 -070048class TestUtils {
49public:
Chris Craik76ace112015-10-29 12:46:19 -070050 class SignalingDtor {
51 public:
52 SignalingDtor()
53 : mSignal(nullptr) {}
54 SignalingDtor(int* signal)
55 : mSignal(signal) {}
56 void setSignal(int* signal) {
57 mSignal = signal;
58 }
59 ~SignalingDtor() {
60 if (mSignal) {
61 (*mSignal)++;
62 }
63 }
64 private:
65 int* mSignal;
66 };
67
Chris Craikb565df12015-10-05 13:00:52 -070068 static bool matricesAreApproxEqual(const Matrix4& a, const Matrix4& b) {
69 for (int i = 0; i < 16; i++) {
70 if (!MathUtils::areEqual(a[i], b[i])) {
71 return false;
72 }
73 }
74 return true;
75 }
76
77 static std::unique_ptr<Snapshot> makeSnapshot(const Matrix4& transform, const Rect& clip) {
78 std::unique_ptr<Snapshot> snapshot(new Snapshot());
79 snapshot->clip(clip.left, clip.top, clip.right, clip.bottom, SkRegion::kReplace_Op);
80 *(snapshot->transform) = transform;
81 return snapshot;
82 }
83
Chris Craikddf22152015-10-14 17:42:47 -070084 static SkBitmap createSkBitmap(int width, int height) {
85 SkBitmap bitmap;
Chris Craik0a24b142015-10-19 17:10:19 -070086 SkImageInfo info = SkImageInfo::MakeUnknown(width, height);
87 bitmap.setInfo(info);
88 bitmap.allocPixels(info);
Chris Craikddf22152015-10-14 17:42:47 -070089 return bitmap;
90 }
91
Chris Craikb565df12015-10-05 13:00:52 -070092 template<class CanvasType>
Chris Craik003cc3d2015-10-16 10:24:55 -070093 static std::unique_ptr<DisplayList> createDisplayList(int width, int height,
Chris Craikb565df12015-10-05 13:00:52 -070094 std::function<void(CanvasType& canvas)> canvasCallback) {
95 CanvasType canvas(width, height);
96 canvasCallback(canvas);
Chris Craik003cc3d2015-10-16 10:24:55 -070097 return std::unique_ptr<DisplayList>(canvas.finishRecording());
Chris Craikb565df12015-10-05 13:00:52 -070098 }
99
Chris Craik0b7e8242015-10-28 16:50:44 -0700100 static sp<RenderNode> createNode(int left, int top, int right, int bottom, bool onLayer = false) {
Chris Craik76caecf2015-11-02 19:17:45 -0800101 // if RenderNodes are being sync'd/used, device info will be needed, since
102 // DeviceInfo::maxTextureSize() affects layer property
103 DeviceInfo::initialize();
104
Chris Craikb565df12015-10-05 13:00:52 -0700105 sp<RenderNode> node = new RenderNode();
106 node->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom);
107 node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
Chris Craik0b7e8242015-10-28 16:50:44 -0700108 if (onLayer) {
109 node->mutateStagingProperties().mutateLayerProperties().setType(LayerType::RenderLayer);
110 node->setPropertyFieldsDirty(RenderNode::GENERIC);
111 }
112 return node;
113 }
Chris Craikb565df12015-10-05 13:00:52 -0700114
Chris Craik0b7e8242015-10-28 16:50:44 -0700115 template<class CanvasType>
116 static sp<RenderNode> createNode(int left, int top, int right, int bottom,
117 std::function<void(CanvasType& canvas)> canvasCallback, bool onLayer = false) {
118 sp<RenderNode> node = createNode(left, top, right, bottom, onLayer);
119
120 auto&& props = node->stagingProperties(); // staging, since not sync'd yet
121 CanvasType canvas(props.getWidth(), props.getHeight());
Chris Craikb565df12015-10-05 13:00:52 -0700122 canvasCallback(canvas);
123 node->setStagingDisplayList(canvas.finishRecording());
124 return node;
125 }
126
Chris Craik161f54b2015-11-05 11:08:52 -0800127 static void syncHierarchyPropertiesAndDisplayList(sp<RenderNode>& node) {
128 syncHierarchyPropertiesAndDisplayListImpl(node.get());
Chris Craikb565df12015-10-05 13:00:52 -0700129 }
Chris Craik0a24b142015-10-19 17:10:19 -0700130
Chris Craik0b7e8242015-10-28 16:50:44 -0700131 typedef std::function<void(renderthread::RenderThread& thread)> RtCallback;
Chris Craik0a24b142015-10-19 17:10:19 -0700132
133 class TestTask : public renderthread::RenderTask {
134 public:
135 TestTask(RtCallback rtCallback)
136 : rtCallback(rtCallback) {}
137 virtual ~TestTask() {}
138 virtual void run() override {
139 // RenderState only valid once RenderThread is running, so queried here
140 RenderState& renderState = renderthread::RenderThread::getInstance().renderState();
141
142 renderState.onGLContextCreated();
Chris Craik0b7e8242015-10-28 16:50:44 -0700143 rtCallback(renderthread::RenderThread::getInstance());
Chris Craik0a24b142015-10-19 17:10:19 -0700144 renderState.onGLContextDestroyed();
145 };
146 RtCallback rtCallback;
147 };
148
149 /**
150 * NOTE: requires surfaceflinger to run, otherwise this method will wait indefinitely.
151 */
152 static void runOnRenderThread(RtCallback rtCallback) {
153 TestTask task(rtCallback);
154 renderthread::RenderThread::getInstance().queueAndWait(&task);
155 }
Chris Craik161f54b2015-11-05 11:08:52 -0800156private:
157 static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) {
158 node->syncProperties();
159 node->syncDisplayList();
160 auto displayList = node->getDisplayList();
161 if (displayList) {
162 for (auto&& childOp : displayList->getChildren()) {
163 syncHierarchyPropertiesAndDisplayListImpl(childOp->renderNode);
164 }
165 }
166 }
167
Chris Craikb565df12015-10-05 13:00:52 -0700168}; // class TestUtils
169
170} /* namespace uirenderer */
171} /* namespace android */
172
173#endif /* TEST_UTILS_H */