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