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