1 /*
2 * Copyright (C) 2014 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
17 #include "tests/common/TestContext.h"
18
19 #include <cutils/trace.h>
20
21 namespace android {
22 namespace uirenderer {
23 namespace test {
24
getDisplayInfo()25 const ui::StaticDisplayInfo& getDisplayInfo() {
26 static ui::StaticDisplayInfo info = [] {
27 ui::StaticDisplayInfo info;
28 #if HWUI_NULL_GPU
29 info.density = 2.f;
30 #else
31 const std::vector<PhysicalDisplayId> ids = SurfaceComposerClient::getPhysicalDisplayIds();
32 LOG_ALWAYS_FATAL_IF(ids.empty(), "%s: No displays", __FUNCTION__);
33
34 const status_t status =
35 SurfaceComposerClient::getStaticDisplayInfo(ids.front().value, &info);
36 LOG_ALWAYS_FATAL_IF(status, "%s: Failed to get display info", __FUNCTION__);
37 #endif
38 return info;
39 }();
40
41 return info;
42 }
43
getActiveDisplayMode()44 const ui::DisplayMode& getActiveDisplayMode() {
45 static ui::DisplayMode config = [] {
46 ui::DisplayMode config;
47 #if HWUI_NULL_GPU
48 config.resolution = ui::Size(1080, 1920);
49 config.xDpi = config.yDpi = 320.f;
50 config.refreshRate = 60.f;
51 #else
52 const std::vector<PhysicalDisplayId> ids = SurfaceComposerClient::getPhysicalDisplayIds();
53 LOG_ALWAYS_FATAL_IF(ids.empty(), "%s: No displays", __FUNCTION__);
54
55 const sp<IBinder> token = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
56 LOG_ALWAYS_FATAL_IF(!token, "%s: No internal display", __FUNCTION__);
57
58 const status_t status = SurfaceComposerClient::getActiveDisplayMode(token, &config);
59 LOG_ALWAYS_FATAL_IF(status, "%s: Failed to get active display config", __FUNCTION__);
60 #endif
61 return config;
62 }();
63
64 return config;
65 }
66
TestContext()67 TestContext::TestContext() {
68 mLooper = new Looper(true);
69 mSurfaceComposerClient = new SurfaceComposerClient();
70
71 constexpr int EVENT_ID = 1;
72 mLooper->addFd(mDisplayEventReceiver.getFd(), EVENT_ID, Looper::EVENT_INPUT, nullptr, nullptr);
73 }
74
~TestContext()75 TestContext::~TestContext() {}
76
surface()77 sp<Surface> TestContext::surface() {
78 if (!mSurface.get()) {
79 createSurface();
80 }
81 return mSurface;
82 }
83
createSurface()84 void TestContext::createSurface() {
85 if (mRenderOffscreen) {
86 createOffscreenSurface();
87 } else {
88 createWindowSurface();
89 }
90 }
91
createWindowSurface()92 void TestContext::createWindowSurface() {
93 const ui::Size& resolution = getActiveDisplayResolution();
94 mSurfaceControl =
95 mSurfaceComposerClient->createSurface(String8("HwuiTest"), resolution.getWidth(),
96 resolution.getHeight(), PIXEL_FORMAT_RGBX_8888);
97
98 SurfaceComposerClient::Transaction t;
99 t.setLayer(mSurfaceControl, 0x7FFFFFF).show(mSurfaceControl).apply();
100 mSurface = mSurfaceControl->getSurface();
101 }
102
createOffscreenSurface()103 void TestContext::createOffscreenSurface() {
104 sp<IGraphicBufferProducer> producer;
105 sp<IGraphicBufferConsumer> consumer;
106 BufferQueue::createBufferQueue(&producer, &consumer);
107 producer->setMaxDequeuedBufferCount(3);
108 producer->setAsyncMode(true);
109 mConsumer = new BufferItemConsumer(consumer, GRALLOC_USAGE_HW_COMPOSER, 4);
110 const ui::Size& resolution = getActiveDisplayResolution();
111 mConsumer->setDefaultBufferSize(resolution.getWidth(), resolution.getHeight());
112 mSurface = new Surface(producer);
113 }
114
waitForVsync()115 void TestContext::waitForVsync() {
116 // Hacky fix for not getting sysprop change callbacks
117 // We just poll the sysprop in vsync since it's when the UI thread is
118 // "idle" and shouldn't burn too much time
119 atrace_update_tags();
120
121 if (mConsumer.get()) {
122 BufferItem buffer;
123 if (mConsumer->acquireBuffer(&buffer, 0, false) == OK) {
124 // We assume the producer is internally ordered enough such that
125 // it is unneccessary to set a release fence
126 mConsumer->releaseBuffer(buffer);
127 }
128 // We running free, go go go!
129 return;
130 }
131 #if !HWUI_NULL_GPU
132 // Request vsync
133 mDisplayEventReceiver.requestNextVsync();
134
135 // Wait
136 mLooper->pollOnce(-1);
137
138 // Drain it
139 DisplayEventReceiver::Event buf[100];
140 while (mDisplayEventReceiver.getEvents(buf, 100) > 0) {
141 }
142 #endif
143 }
144
145 } // namespace test
146 } // namespace uirenderer
147 } // namespace android
148