blob: 23e5398b93072a02c4386c0051e01a9fade6589f [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 Craikd3daa312015-11-06 10:59:56 -0800100 typedef std::function<int(RenderProperties&)> PropSetupCallback;
101
102 static PropSetupCallback getHwLayerSetupCallback() {
103 static PropSetupCallback sLayerSetupCallback = [] (RenderProperties& properties) {
104 properties.mutateLayerProperties().setType(LayerType::RenderLayer);
105 return RenderNode::GENERIC;
106 };
107 return sLayerSetupCallback;
108 }
109
110 static sp<RenderNode> createNode(int left, int top, int right, int bottom,
111 PropSetupCallback propSetupCallback = nullptr) {
Chris Craik76caecf2015-11-02 19:17:45 -0800112 // if RenderNodes are being sync'd/used, device info will be needed, since
113 // DeviceInfo::maxTextureSize() affects layer property
114 DeviceInfo::initialize();
115
Chris Craikb565df12015-10-05 13:00:52 -0700116 sp<RenderNode> node = new RenderNode();
117 node->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom);
118 node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
Chris Craikd3daa312015-11-06 10:59:56 -0800119 if (propSetupCallback) {
120 node->setPropertyFieldsDirty(propSetupCallback(node->mutateStagingProperties()));
Chris Craik0b7e8242015-10-28 16:50:44 -0700121 }
122 return node;
123 }
Chris Craikb565df12015-10-05 13:00:52 -0700124
Chris Craik0b7e8242015-10-28 16:50:44 -0700125 template<class CanvasType>
126 static sp<RenderNode> createNode(int left, int top, int right, int bottom,
Chris Craikd3daa312015-11-06 10:59:56 -0800127 std::function<void(CanvasType& canvas)> canvasCallback,
128 PropSetupCallback propSetupCallback = nullptr) {
129 sp<RenderNode> node = createNode(left, top, right, bottom, propSetupCallback);
Chris Craik0b7e8242015-10-28 16:50:44 -0700130
131 auto&& props = node->stagingProperties(); // staging, since not sync'd yet
132 CanvasType canvas(props.getWidth(), props.getHeight());
Chris Craikb565df12015-10-05 13:00:52 -0700133 canvasCallback(canvas);
134 node->setStagingDisplayList(canvas.finishRecording());
135 return node;
136 }
137
Chris Craik161f54b2015-11-05 11:08:52 -0800138 static void syncHierarchyPropertiesAndDisplayList(sp<RenderNode>& node) {
139 syncHierarchyPropertiesAndDisplayListImpl(node.get());
Chris Craikb565df12015-10-05 13:00:52 -0700140 }
Chris Craik0a24b142015-10-19 17:10:19 -0700141
Chris Craik0b7e8242015-10-28 16:50:44 -0700142 typedef std::function<void(renderthread::RenderThread& thread)> RtCallback;
Chris Craik0a24b142015-10-19 17:10:19 -0700143
144 class TestTask : public renderthread::RenderTask {
145 public:
146 TestTask(RtCallback rtCallback)
147 : rtCallback(rtCallback) {}
148 virtual ~TestTask() {}
149 virtual void run() override {
150 // RenderState only valid once RenderThread is running, so queried here
151 RenderState& renderState = renderthread::RenderThread::getInstance().renderState();
152
153 renderState.onGLContextCreated();
Chris Craik0b7e8242015-10-28 16:50:44 -0700154 rtCallback(renderthread::RenderThread::getInstance());
Chris Craik0a24b142015-10-19 17:10:19 -0700155 renderState.onGLContextDestroyed();
156 };
157 RtCallback rtCallback;
158 };
159
160 /**
161 * NOTE: requires surfaceflinger to run, otherwise this method will wait indefinitely.
162 */
163 static void runOnRenderThread(RtCallback rtCallback) {
164 TestTask task(rtCallback);
165 renderthread::RenderThread::getInstance().queueAndWait(&task);
166 }
Chris Craik161f54b2015-11-05 11:08:52 -0800167private:
168 static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) {
169 node->syncProperties();
170 node->syncDisplayList();
171 auto displayList = node->getDisplayList();
172 if (displayList) {
173 for (auto&& childOp : displayList->getChildren()) {
174 syncHierarchyPropertiesAndDisplayListImpl(childOp->renderNode);
175 }
176 }
177 }
178
Chris Craikb565df12015-10-05 13:00:52 -0700179}; // class TestUtils
180
181} /* namespace uirenderer */
182} /* namespace android */
183
184#endif /* TEST_UTILS_H */