blob: 770f413352c265143e1857c24ace49ffba61e9ef [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
19#include <Matrix.h>
Chris Craik0a24b142015-10-19 17:10:19 -070020#include <Rect.h>
Chris Craikb565df12015-10-05 13:00:52 -070021#include <RenderNode.h>
Chris Craik0a24b142015-10-19 17:10:19 -070022#include <renderstate/RenderState.h>
23#include <renderthread/RenderThread.h>
24#include <Snapshot.h>
Chris Craikb565df12015-10-05 13:00:52 -070025
26#include <memory>
27
28namespace android {
29namespace uirenderer {
30
31#define EXPECT_MATRIX_APPROX_EQ(a, b) \
32 EXPECT_TRUE(TestUtils::matricesAreApproxEqual(a, b))
33
Chris Craik6fe991e52015-10-20 09:39:42 -070034#define EXPECT_RECT_APPROX_EQ(a, b) \
35 EXPECT_TRUE(MathUtils::areEqual(a.left, b.left) \
36 && MathUtils::areEqual(a.top, b.top) \
37 && MathUtils::areEqual(a.right, b.right) \
38 && MathUtils::areEqual(a.bottom, b.bottom));
39
Chris Craikb565df12015-10-05 13:00:52 -070040class TestUtils {
41public:
Chris Craik76ace112015-10-29 12:46:19 -070042 class SignalingDtor {
43 public:
44 SignalingDtor()
45 : mSignal(nullptr) {}
46 SignalingDtor(int* signal)
47 : mSignal(signal) {}
48 void setSignal(int* signal) {
49 mSignal = signal;
50 }
51 ~SignalingDtor() {
52 if (mSignal) {
53 (*mSignal)++;
54 }
55 }
56 private:
57 int* mSignal;
58 };
59
Chris Craikb565df12015-10-05 13:00:52 -070060 static bool matricesAreApproxEqual(const Matrix4& a, const Matrix4& b) {
61 for (int i = 0; i < 16; i++) {
62 if (!MathUtils::areEqual(a[i], b[i])) {
63 return false;
64 }
65 }
66 return true;
67 }
68
69 static std::unique_ptr<Snapshot> makeSnapshot(const Matrix4& transform, const Rect& clip) {
70 std::unique_ptr<Snapshot> snapshot(new Snapshot());
71 snapshot->clip(clip.left, clip.top, clip.right, clip.bottom, SkRegion::kReplace_Op);
72 *(snapshot->transform) = transform;
73 return snapshot;
74 }
75
Chris Craikddf22152015-10-14 17:42:47 -070076 static SkBitmap createSkBitmap(int width, int height) {
77 SkBitmap bitmap;
Chris Craik0a24b142015-10-19 17:10:19 -070078 SkImageInfo info = SkImageInfo::MakeUnknown(width, height);
79 bitmap.setInfo(info);
80 bitmap.allocPixels(info);
Chris Craikddf22152015-10-14 17:42:47 -070081 return bitmap;
82 }
83
Chris Craikb565df12015-10-05 13:00:52 -070084 template<class CanvasType>
Chris Craik003cc3d2015-10-16 10:24:55 -070085 static std::unique_ptr<DisplayList> createDisplayList(int width, int height,
Chris Craikb565df12015-10-05 13:00:52 -070086 std::function<void(CanvasType& canvas)> canvasCallback) {
87 CanvasType canvas(width, height);
88 canvasCallback(canvas);
Chris Craik003cc3d2015-10-16 10:24:55 -070089 return std::unique_ptr<DisplayList>(canvas.finishRecording());
Chris Craikb565df12015-10-05 13:00:52 -070090 }
91
Chris Craik0b7e8242015-10-28 16:50:44 -070092 static sp<RenderNode> createNode(int left, int top, int right, int bottom, bool onLayer = false) {
Chris Craikb565df12015-10-05 13:00:52 -070093 sp<RenderNode> node = new RenderNode();
94 node->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom);
95 node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
Chris Craik0b7e8242015-10-28 16:50:44 -070096 if (onLayer) {
97 node->mutateStagingProperties().mutateLayerProperties().setType(LayerType::RenderLayer);
98 node->setPropertyFieldsDirty(RenderNode::GENERIC);
99 }
100 return node;
101 }
Chris Craikb565df12015-10-05 13:00:52 -0700102
Chris Craik0b7e8242015-10-28 16:50:44 -0700103 template<class CanvasType>
104 static sp<RenderNode> createNode(int left, int top, int right, int bottom,
105 std::function<void(CanvasType& canvas)> canvasCallback, bool onLayer = false) {
106 sp<RenderNode> node = createNode(left, top, right, bottom, onLayer);
107
108 auto&& props = node->stagingProperties(); // staging, since not sync'd yet
109 CanvasType canvas(props.getWidth(), props.getHeight());
Chris Craikb565df12015-10-05 13:00:52 -0700110 canvasCallback(canvas);
111 node->setStagingDisplayList(canvas.finishRecording());
112 return node;
113 }
114
115 static void syncNodePropertiesAndDisplayList(sp<RenderNode>& node) {
116 node->syncProperties();
117 node->syncDisplayList();
118 }
Chris Craik0a24b142015-10-19 17:10:19 -0700119
Chris Craik0b7e8242015-10-28 16:50:44 -0700120 typedef std::function<void(renderthread::RenderThread& thread)> RtCallback;
Chris Craik0a24b142015-10-19 17:10:19 -0700121
122 class TestTask : public renderthread::RenderTask {
123 public:
124 TestTask(RtCallback rtCallback)
125 : rtCallback(rtCallback) {}
126 virtual ~TestTask() {}
127 virtual void run() override {
128 // RenderState only valid once RenderThread is running, so queried here
129 RenderState& renderState = renderthread::RenderThread::getInstance().renderState();
130
131 renderState.onGLContextCreated();
Chris Craik0b7e8242015-10-28 16:50:44 -0700132 rtCallback(renderthread::RenderThread::getInstance());
Chris Craik0a24b142015-10-19 17:10:19 -0700133 renderState.onGLContextDestroyed();
134 };
135 RtCallback rtCallback;
136 };
137
138 /**
139 * NOTE: requires surfaceflinger to run, otherwise this method will wait indefinitely.
140 */
141 static void runOnRenderThread(RtCallback rtCallback) {
142 TestTask task(rtCallback);
143 renderthread::RenderThread::getInstance().queueAndWait(&task);
144 }
Chris Craikb565df12015-10-05 13:00:52 -0700145}; // class TestUtils
146
147} /* namespace uirenderer */
148} /* namespace android */
149
150#endif /* TEST_UTILS_H */