1 /*
2 * Copyright 2024 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 <apex/display.h>
18 #include <utils/Errors.h>
19
20 namespace android::display::impl {
21
22 /**
23 * Implementation of ADisplayConfig
24 */
25 struct DisplayConfigImpl {
26 /**
27 * The width in pixels of the display configuration.
28 */
29 int32_t width{1080};
30
31 /**
32 * The height in pixels of the display configuration.
33 */
34
35 int32_t height{1920};
36
37 /**
38 * The refresh rate of the display configuration, in frames per second.
39 */
40 float fps{60.0};
41
42 /**
43 * The vsync offset at which surfaceflinger runs, in nanoseconds.
44 */
45 int64_t sfOffset{0};
46
47 /**
48 * The vsync offset at which applications run, in nanoseconds.
49 */
50 int64_t appOffset{0};
51 };
52
53 // DisplayConfigImpl allocation is not managed through C++ memory apis, so
54 // preventing calling the destructor here.
55 static_assert(std::is_trivially_destructible<DisplayConfigImpl>::value);
56
57 /**
58 * Implementation of ADisplay
59 */
60 struct DisplayImpl {
61 /**
62 * The type of the display, i.e. whether it is an internal or external
63 * display.
64 */
65 ADisplayType type;
66
67 /**
68 * The preferred WCG dataspace
69 */
70 ADataSpace wcgDataspace;
71
72 /**
73 * The preferred WCG pixel format
74 */
75 AHardwareBuffer_Format wcgPixelFormat;
76
77 /**
78 * The config for this display.
79 */
80 DisplayConfigImpl config;
81 };
82
83 // DisplayImpl allocation is not managed through C++ memory apis, so
84 // preventing calling the destructor here.
85 static_assert(std::is_trivially_destructible<DisplayImpl>::value);
86
87 } // namespace android::display::impl
88
89 using namespace android;
90 using namespace android::display::impl;
91
92 namespace android {
93
ADisplay_acquirePhysicalDisplays(ADisplay *** outDisplays)94 int ADisplay_acquirePhysicalDisplays(ADisplay*** outDisplays) {
95 // This is running on host, so there are no physical displays available.
96 // Create 1 fake display instead.
97 DisplayImpl** const impls =
98 reinterpret_cast<DisplayImpl**>(malloc(sizeof(DisplayImpl*) + sizeof(DisplayImpl)));
99 DisplayImpl* const displayData = reinterpret_cast<DisplayImpl*>(impls + 1);
100
101 displayData[0] =
102 DisplayImpl{ADisplayType::DISPLAY_TYPE_INTERNAL, ADataSpace::ADATASPACE_UNKNOWN,
103 AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
104 DisplayConfigImpl()};
105 impls[0] = displayData;
106 *outDisplays = reinterpret_cast<ADisplay**>(impls);
107 return 1;
108 }
109
ADisplay_release(ADisplay ** displays)110 void ADisplay_release(ADisplay** displays) {
111 if (displays == nullptr) {
112 return;
113 }
114 free(displays);
115 }
116
ADisplay_getMaxSupportedFps(ADisplay * display)117 float ADisplay_getMaxSupportedFps(ADisplay* display) {
118 DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
119 return impl->config.fps;
120 }
121
ADisplay_getDisplayType(ADisplay * display)122 ADisplayType ADisplay_getDisplayType(ADisplay* display) {
123 return reinterpret_cast<DisplayImpl*>(display)->type;
124 }
125
ADisplay_getPreferredWideColorFormat(ADisplay * display,ADataSpace * outDataspace,AHardwareBuffer_Format * outPixelFormat)126 void ADisplay_getPreferredWideColorFormat(ADisplay* display, ADataSpace* outDataspace,
127 AHardwareBuffer_Format* outPixelFormat) {
128 DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
129 *outDataspace = impl->wcgDataspace;
130 *outPixelFormat = impl->wcgPixelFormat;
131 }
132
ADisplay_getCurrentConfig(ADisplay * display,ADisplayConfig ** outConfig)133 int ADisplay_getCurrentConfig(ADisplay* display, ADisplayConfig** outConfig) {
134 DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
135 *outConfig = reinterpret_cast<ADisplayConfig*>(&impl->config);
136 return OK;
137 }
138
ADisplayConfig_getWidth(ADisplayConfig * config)139 int32_t ADisplayConfig_getWidth(ADisplayConfig* config) {
140 return reinterpret_cast<DisplayConfigImpl*>(config)->width;
141 }
142
ADisplayConfig_getHeight(ADisplayConfig * config)143 int32_t ADisplayConfig_getHeight(ADisplayConfig* config) {
144 return reinterpret_cast<DisplayConfigImpl*>(config)->height;
145 }
146
ADisplayConfig_getFps(ADisplayConfig * config)147 float ADisplayConfig_getFps(ADisplayConfig* config) {
148 return reinterpret_cast<DisplayConfigImpl*>(config)->fps;
149 }
150
ADisplayConfig_getCompositorOffsetNanos(ADisplayConfig * config)151 int64_t ADisplayConfig_getCompositorOffsetNanos(ADisplayConfig* config) {
152 return reinterpret_cast<DisplayConfigImpl*>(config)->sfOffset;
153 }
154
ADisplayConfig_getAppVsyncOffsetNanos(ADisplayConfig * config)155 int64_t ADisplayConfig_getAppVsyncOffsetNanos(ADisplayConfig* config) {
156 return reinterpret_cast<DisplayConfigImpl*>(config)->appOffset;
157 }
158
159 } // namespace android
160