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