1 /*
2 * Copyright 2017 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 #define LOG_TAG "HWC2OnFbAdapter"
18
19 //#define LOG_NDEBUG 0
20
21 #include "hwc2onfbadapter/HWC2OnFbAdapter.h"
22
23 #include <algorithm>
24 #include <type_traits>
25
26 #include <inttypes.h>
27 #include <time.h>
28 #include <sys/prctl.h>
29 #include <unistd.h> // for close
30
31 #include <hardware/fb.h>
32 #include <log/log.h>
33 #include <sync/sync.h>
34
35 namespace android {
36
37 namespace {
38
dumpHook(hwc2_device_t * device,uint32_t * outSize,char * outBuffer)39 void dumpHook(hwc2_device_t* device, uint32_t* outSize, char* outBuffer) {
40 auto& adapter = HWC2OnFbAdapter::cast(device);
41 if (outBuffer) {
42 *outSize = adapter.getDebugString().copy(outBuffer, *outSize);
43 } else {
44 adapter.updateDebugString();
45 *outSize = adapter.getDebugString().size();
46 }
47 }
48
registerCallbackHook(hwc2_device_t * device,int32_t descriptor,hwc2_callback_data_t callbackData,hwc2_function_pointer_t pointer)49 int32_t registerCallbackHook(hwc2_device_t* device, int32_t descriptor,
50 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
51 auto& adapter = HWC2OnFbAdapter::cast(device);
52 switch (descriptor) {
53 case HWC2_CALLBACK_HOTPLUG:
54 if (pointer) {
55 reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer)(callbackData, adapter.getDisplayId(),
56 HWC2_CONNECTION_CONNECTED);
57 }
58 break;
59 case HWC2_CALLBACK_REFRESH:
60 break;
61 case HWC2_CALLBACK_VSYNC:
62 adapter.setVsyncCallback(reinterpret_cast<HWC2_PFN_VSYNC>(pointer), callbackData);
63 break;
64 default:
65 return HWC2_ERROR_BAD_PARAMETER;
66 }
67
68 return HWC2_ERROR_NONE;
69 }
70
getMaxVirtualDisplayCountHook(hwc2_device_t *)71 uint32_t getMaxVirtualDisplayCountHook(hwc2_device_t* /*device*/) {
72 return 0;
73 }
74
createVirtualDisplayHook(hwc2_device_t *,uint32_t,uint32_t,int32_t *,hwc2_display_t *)75 int32_t createVirtualDisplayHook(hwc2_device_t* /*device*/, uint32_t /*width*/, uint32_t /*height*/,
76 int32_t* /*format*/, hwc2_display_t* /*outDisplay*/) {
77 return HWC2_ERROR_NO_RESOURCES;
78 }
79
destroyVirtualDisplayHook(hwc2_device_t *,hwc2_display_t)80 int32_t destroyVirtualDisplayHook(hwc2_device_t* /*device*/, hwc2_display_t /*display*/) {
81 return HWC2_ERROR_BAD_DISPLAY;
82 }
83
setOutputBufferHook(hwc2_device_t *,hwc2_display_t,buffer_handle_t,int32_t)84 int32_t setOutputBufferHook(hwc2_device_t* /*device*/, hwc2_display_t /*display*/,
85 buffer_handle_t /*buffer*/, int32_t /*releaseFence*/) {
86 return HWC2_ERROR_BAD_DISPLAY;
87 }
88
getDisplayNameHook(hwc2_device_t * device,hwc2_display_t display,uint32_t * outSize,char * outName)89 int32_t getDisplayNameHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outSize,
90 char* outName) {
91 auto& adapter = HWC2OnFbAdapter::cast(device);
92 if (adapter.getDisplayId() != display) {
93 return HWC2_ERROR_BAD_DISPLAY;
94 }
95
96 const auto& info = adapter.getInfo();
97 if (outName) {
98 *outSize = info.name.copy(outName, *outSize);
99 } else {
100 *outSize = info.name.size();
101 }
102
103 return HWC2_ERROR_NONE;
104 }
105
getDisplayTypeHook(hwc2_device_t * device,hwc2_display_t display,int32_t * outType)106 int32_t getDisplayTypeHook(hwc2_device_t* device, hwc2_display_t display, int32_t* outType) {
107 auto& adapter = HWC2OnFbAdapter::cast(device);
108 if (adapter.getDisplayId() != display) {
109 return HWC2_ERROR_BAD_DISPLAY;
110 }
111
112 *outType = HWC2_DISPLAY_TYPE_PHYSICAL;
113 return HWC2_ERROR_NONE;
114 }
115
getDozeSupportHook(hwc2_device_t * device,hwc2_display_t display,int32_t * outSupport)116 int32_t getDozeSupportHook(hwc2_device_t* device, hwc2_display_t display, int32_t* outSupport) {
117 auto& adapter = HWC2OnFbAdapter::cast(device);
118 if (adapter.getDisplayId() != display) {
119 return HWC2_ERROR_BAD_DISPLAY;
120 }
121
122 *outSupport = 0;
123 return HWC2_ERROR_NONE;
124 }
125
getHdrCapabilitiesHook(hwc2_device_t * device,hwc2_display_t display,uint32_t * outNumTypes,int32_t *,float *,float *,float *)126 int32_t getHdrCapabilitiesHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumTypes,
127 int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
128 float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
129 auto& adapter = HWC2OnFbAdapter::cast(device);
130 if (adapter.getDisplayId() != display) {
131 return HWC2_ERROR_BAD_DISPLAY;
132 }
133
134 *outNumTypes = 0;
135 return HWC2_ERROR_NONE;
136 }
137
setPowerModeHook(hwc2_device_t * device,hwc2_display_t display,int32_t)138 int32_t setPowerModeHook(hwc2_device_t* device, hwc2_display_t display, int32_t /*mode*/) {
139 auto& adapter = HWC2OnFbAdapter::cast(device);
140 if (adapter.getDisplayId() != display) {
141 return HWC2_ERROR_BAD_DISPLAY;
142 }
143
144 // pretend that it works
145 return HWC2_ERROR_NONE;
146 }
147
setVsyncEnabledHook(hwc2_device_t * device,hwc2_display_t display,int32_t enabled)148 int32_t setVsyncEnabledHook(hwc2_device_t* device, hwc2_display_t display, int32_t enabled) {
149 auto& adapter = HWC2OnFbAdapter::cast(device);
150 if (adapter.getDisplayId() != display) {
151 return HWC2_ERROR_BAD_DISPLAY;
152 }
153
154 adapter.enableVsync(enabled == HWC2_VSYNC_ENABLE);
155 return HWC2_ERROR_NONE;
156 }
157
getColorModesHook(hwc2_device_t * device,hwc2_display_t display,uint32_t * outNumModes,int32_t * outModes)158 int32_t getColorModesHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumModes,
159 int32_t* outModes) {
160 auto& adapter = HWC2OnFbAdapter::cast(device);
161 if (adapter.getDisplayId() != display) {
162 return HWC2_ERROR_BAD_DISPLAY;
163 }
164
165 if (outModes) {
166 if (*outNumModes > 0) {
167 outModes[0] = HAL_COLOR_MODE_NATIVE;
168 *outNumModes = 1;
169 }
170 } else {
171 *outNumModes = 1;
172 }
173
174 return HWC2_ERROR_NONE;
175 }
176
setColorModeHook(hwc2_device_t * device,hwc2_display_t display,int32_t mode)177 int32_t setColorModeHook(hwc2_device_t* device, hwc2_display_t display, int32_t mode) {
178 auto& adapter = HWC2OnFbAdapter::cast(device);
179 if (adapter.getDisplayId() != display) {
180 return HWC2_ERROR_BAD_DISPLAY;
181 }
182 if (mode != HAL_COLOR_MODE_NATIVE) {
183 return HWC2_ERROR_BAD_PARAMETER;
184 }
185
186 return HWC2_ERROR_NONE;
187 }
188
setColorTransformHook(hwc2_device_t * device,hwc2_display_t display,const float *,int32_t)189 int32_t setColorTransformHook(hwc2_device_t* device, hwc2_display_t display,
190 const float* /*matrix*/, int32_t /*hint*/) {
191 auto& adapter = HWC2OnFbAdapter::cast(device);
192 if (adapter.getDisplayId() != display) {
193 return HWC2_ERROR_BAD_DISPLAY;
194 }
195
196 // we always force client composition
197 adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
198 return HWC2_ERROR_NONE;
199 }
200
getClientTargetSupportHook(hwc2_device_t * device,hwc2_display_t display,uint32_t width,uint32_t height,int32_t format,int32_t dataspace)201 int32_t getClientTargetSupportHook(hwc2_device_t* device, hwc2_display_t display, uint32_t width,
202 uint32_t height, int32_t format, int32_t dataspace) {
203 auto& adapter = HWC2OnFbAdapter::cast(device);
204 if (adapter.getDisplayId() != display) {
205 return HWC2_ERROR_BAD_DISPLAY;
206 }
207 if (dataspace != HAL_DATASPACE_UNKNOWN) {
208 return HWC2_ERROR_UNSUPPORTED;
209 }
210
211 const auto& info = adapter.getInfo();
212 return (info.width == width && info.height == height && info.format == format)
213 ? HWC2_ERROR_NONE
214 : HWC2_ERROR_UNSUPPORTED;
215 }
216
setClientTargetHook(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t target,int32_t acquireFence,int32_t dataspace,hwc_region_t)217 int32_t setClientTargetHook(hwc2_device_t* device, hwc2_display_t display, buffer_handle_t target,
218 int32_t acquireFence, int32_t dataspace, hwc_region_t /*damage*/) {
219 if (acquireFence >= 0) {
220 sync_wait(acquireFence, -1);
221 close(acquireFence);
222 }
223
224 auto& adapter = HWC2OnFbAdapter::cast(device);
225 if (adapter.getDisplayId() != display) {
226 return HWC2_ERROR_BAD_DISPLAY;
227 }
228 if (dataspace != HAL_DATASPACE_UNKNOWN) {
229 return HWC2_ERROR_BAD_PARAMETER;
230 }
231
232 // no state change
233 adapter.setBuffer(target);
234 return HWC2_ERROR_NONE;
235 }
236
getDisplayConfigsHook(hwc2_device_t * device,hwc2_display_t display,uint32_t * outNumConfigs,hwc2_config_t * outConfigs)237 int32_t getDisplayConfigsHook(hwc2_device_t* device, hwc2_display_t display,
238 uint32_t* outNumConfigs, hwc2_config_t* outConfigs) {
239 auto& adapter = HWC2OnFbAdapter::cast(device);
240 if (adapter.getDisplayId() != display) {
241 return HWC2_ERROR_BAD_DISPLAY;
242 }
243
244 if (outConfigs) {
245 if (*outNumConfigs > 0) {
246 outConfigs[0] = adapter.getConfigId();
247 *outNumConfigs = 1;
248 }
249 } else {
250 *outNumConfigs = 1;
251 }
252
253 return HWC2_ERROR_NONE;
254 }
255
getDisplayAttributeHook(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config,int32_t attribute,int32_t * outValue)256 int32_t getDisplayAttributeHook(hwc2_device_t* device, hwc2_display_t display, hwc2_config_t config,
257 int32_t attribute, int32_t* outValue) {
258 auto& adapter = HWC2OnFbAdapter::cast(device);
259 if (adapter.getDisplayId() != display) {
260 return HWC2_ERROR_BAD_DISPLAY;
261 }
262 if (adapter.getConfigId() != config) {
263 return HWC2_ERROR_BAD_CONFIG;
264 }
265
266 const auto& info = adapter.getInfo();
267 switch (attribute) {
268 case HWC2_ATTRIBUTE_WIDTH:
269 *outValue = int32_t(info.width);
270 break;
271 case HWC2_ATTRIBUTE_HEIGHT:
272 *outValue = int32_t(info.height);
273 break;
274 case HWC2_ATTRIBUTE_VSYNC_PERIOD:
275 *outValue = int32_t(info.vsync_period_ns);
276 break;
277 case HWC2_ATTRIBUTE_DPI_X:
278 *outValue = int32_t(info.xdpi_scaled);
279 break;
280 case HWC2_ATTRIBUTE_DPI_Y:
281 *outValue = int32_t(info.ydpi_scaled);
282 break;
283 default:
284 return HWC2_ERROR_BAD_PARAMETER;
285 }
286
287 return HWC2_ERROR_NONE;
288 }
289
getActiveConfigHook(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t * outConfig)290 int32_t getActiveConfigHook(hwc2_device_t* device, hwc2_display_t display,
291 hwc2_config_t* outConfig) {
292 auto& adapter = HWC2OnFbAdapter::cast(device);
293 if (adapter.getDisplayId() != display) {
294 return HWC2_ERROR_BAD_DISPLAY;
295 }
296
297 *outConfig = adapter.getConfigId();
298 return HWC2_ERROR_NONE;
299 }
300
setActiveConfigHook(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config)301 int32_t setActiveConfigHook(hwc2_device_t* device, hwc2_display_t display, hwc2_config_t config) {
302 auto& adapter = HWC2OnFbAdapter::cast(device);
303 if (adapter.getDisplayId() != display) {
304 return HWC2_ERROR_BAD_DISPLAY;
305 }
306 if (adapter.getConfigId() != config) {
307 return HWC2_ERROR_BAD_CONFIG;
308 }
309
310 return HWC2_ERROR_NONE;
311 }
312
validateDisplayHook(hwc2_device_t * device,hwc2_display_t display,uint32_t * outNumTypes,uint32_t * outNumRequests)313 int32_t validateDisplayHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumTypes,
314 uint32_t* outNumRequests) {
315 auto& adapter = HWC2OnFbAdapter::cast(device);
316 if (adapter.getDisplayId() != display) {
317 return HWC2_ERROR_BAD_DISPLAY;
318 }
319
320 const auto& dirtyLayers = adapter.getDirtyLayers();
321 *outNumTypes = dirtyLayers.size();
322 *outNumRequests = 0;
323
324 if (*outNumTypes > 0) {
325 adapter.setState(HWC2OnFbAdapter::State::VALIDATED_WITH_CHANGES);
326 return HWC2_ERROR_HAS_CHANGES;
327 } else {
328 adapter.setState(HWC2OnFbAdapter::State::VALIDATED);
329 return HWC2_ERROR_NONE;
330 }
331 }
332
getChangedCompositionTypesHook(hwc2_device_t * device,hwc2_display_t display,uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outTypes)333 int32_t getChangedCompositionTypesHook(hwc2_device_t* device, hwc2_display_t display,
334 uint32_t* outNumElements, hwc2_layer_t* outLayers,
335 int32_t* outTypes) {
336 auto& adapter = HWC2OnFbAdapter::cast(device);
337 if (adapter.getDisplayId() != display) {
338 return HWC2_ERROR_BAD_DISPLAY;
339 }
340 if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) {
341 return HWC2_ERROR_NOT_VALIDATED;
342 }
343
344 // request client composition for all layers
345 const auto& dirtyLayers = adapter.getDirtyLayers();
346 if (outLayers && outTypes) {
347 *outNumElements = std::min(*outNumElements, uint32_t(dirtyLayers.size()));
348 auto iter = dirtyLayers.cbegin();
349 for (uint32_t i = 0; i < *outNumElements; i++) {
350 outLayers[i] = *iter++;
351 outTypes[i] = HWC2_COMPOSITION_CLIENT;
352 }
353 } else {
354 *outNumElements = dirtyLayers.size();
355 }
356
357 return HWC2_ERROR_NONE;
358 }
359
getDisplayRequestsHook(hwc2_device_t * device,hwc2_display_t display,int32_t * outDisplayRequests,uint32_t * outNumElements,hwc2_layer_t *,int32_t *)360 int32_t getDisplayRequestsHook(hwc2_device_t* device, hwc2_display_t display,
361 int32_t* outDisplayRequests, uint32_t* outNumElements,
362 hwc2_layer_t* /*outLayers*/, int32_t* /*outLayerRequests*/) {
363 auto& adapter = HWC2OnFbAdapter::cast(device);
364 if (adapter.getDisplayId() != display) {
365 return HWC2_ERROR_BAD_DISPLAY;
366 }
367 if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) {
368 return HWC2_ERROR_NOT_VALIDATED;
369 }
370
371 *outDisplayRequests = 0;
372 *outNumElements = 0;
373 return HWC2_ERROR_NONE;
374 }
375
acceptDisplayChangesHook(hwc2_device_t * device,hwc2_display_t display)376 int32_t acceptDisplayChangesHook(hwc2_device_t* device, hwc2_display_t display) {
377 auto& adapter = HWC2OnFbAdapter::cast(device);
378 if (adapter.getDisplayId() != display) {
379 return HWC2_ERROR_BAD_DISPLAY;
380 }
381 if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) {
382 return HWC2_ERROR_NOT_VALIDATED;
383 }
384
385 adapter.clearDirtyLayers();
386 adapter.setState(HWC2OnFbAdapter::State::VALIDATED);
387 return HWC2_ERROR_NONE;
388 }
389
presentDisplayHook(hwc2_device_t * device,hwc2_display_t display,int32_t * outPresentFence)390 int32_t presentDisplayHook(hwc2_device_t* device, hwc2_display_t display,
391 int32_t* outPresentFence) {
392 auto& adapter = HWC2OnFbAdapter::cast(device);
393 if (adapter.getDisplayId() != display) {
394 return HWC2_ERROR_BAD_DISPLAY;
395 }
396 if (adapter.getState() != HWC2OnFbAdapter::State::VALIDATED) {
397 return HWC2_ERROR_NOT_VALIDATED;
398 }
399
400 adapter.postBuffer();
401 *outPresentFence = -1;
402
403 return HWC2_ERROR_NONE;
404 }
405
getReleaseFencesHook(hwc2_device_t * device,hwc2_display_t display,uint32_t * outNumElements,hwc2_layer_t *,int32_t *)406 int32_t getReleaseFencesHook(hwc2_device_t* device, hwc2_display_t display,
407 uint32_t* outNumElements, hwc2_layer_t* /*outLayers*/,
408 int32_t* /*outFences*/) {
409 auto& adapter = HWC2OnFbAdapter::cast(device);
410 if (adapter.getDisplayId() != display) {
411 return HWC2_ERROR_BAD_DISPLAY;
412 }
413
414 *outNumElements = 0;
415 return HWC2_ERROR_NONE;
416 }
417
createLayerHook(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t * outLayer)418 int32_t createLayerHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t* outLayer) {
419 auto& adapter = HWC2OnFbAdapter::cast(device);
420 if (adapter.getDisplayId() != display) {
421 return HWC2_ERROR_BAD_DISPLAY;
422 }
423
424 *outLayer = adapter.addLayer();
425 adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
426 return HWC2_ERROR_NONE;
427 }
428
destroyLayerHook(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer)429 int32_t destroyLayerHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer) {
430 auto& adapter = HWC2OnFbAdapter::cast(device);
431 if (adapter.getDisplayId() != display) {
432 return HWC2_ERROR_BAD_DISPLAY;
433 }
434
435 if (adapter.removeLayer(layer)) {
436 adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
437 return HWC2_ERROR_NONE;
438 } else {
439 return HWC2_ERROR_BAD_LAYER;
440 }
441 }
442
setCursorPositionHook(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t,int32_t,int32_t)443 int32_t setCursorPositionHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t /*layer*/,
444 int32_t /*x*/, int32_t /*y*/) {
445 auto& adapter = HWC2OnFbAdapter::cast(device);
446 if (adapter.getDisplayId() != display) {
447 return HWC2_ERROR_BAD_DISPLAY;
448 }
449
450 // always an error
451 return HWC2_ERROR_BAD_LAYER;
452 }
453
setLayerBufferHook(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,buffer_handle_t,int32_t acquireFence)454 int32_t setLayerBufferHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer,
455 buffer_handle_t /*buffer*/, int32_t acquireFence) {
456 if (acquireFence >= 0) {
457 sync_wait(acquireFence, -1);
458 close(acquireFence);
459 }
460
461 auto& adapter = HWC2OnFbAdapter::cast(device);
462 if (adapter.getDisplayId() != display) {
463 return HWC2_ERROR_BAD_DISPLAY;
464 }
465 if (!adapter.hasLayer(layer)) {
466 return HWC2_ERROR_BAD_LAYER;
467 }
468
469 // no state change
470 return HWC2_ERROR_NONE;
471 }
472
setLayerSurfaceDamageHook(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t)473 int32_t setLayerSurfaceDamageHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer,
474 hwc_region_t /*damage*/) {
475 auto& adapter = HWC2OnFbAdapter::cast(device);
476 if (adapter.getDisplayId() != display) {
477 return HWC2_ERROR_BAD_DISPLAY;
478 }
479 if (!adapter.hasLayer(layer)) {
480 return HWC2_ERROR_BAD_LAYER;
481 }
482
483 // no state change
484 return HWC2_ERROR_NONE;
485 }
486
setLayerCompositionTypeHook(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t type)487 int32_t setLayerCompositionTypeHook(hwc2_device_t* device, hwc2_display_t display,
488 hwc2_layer_t layer, int32_t type) {
489 auto& adapter = HWC2OnFbAdapter::cast(device);
490 if (adapter.getDisplayId() != display) {
491 return HWC2_ERROR_BAD_DISPLAY;
492 }
493 if (!adapter.markLayerDirty(layer, type != HWC2_COMPOSITION_CLIENT)) {
494 return HWC2_ERROR_BAD_LAYER;
495 }
496
497 adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
498 return HWC2_ERROR_NONE;
499 }
500
501 template <typename... Args>
setLayerStateHook(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,Args...)502 int32_t setLayerStateHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer,
503 Args... /*args*/) {
504 auto& adapter = HWC2OnFbAdapter::cast(device);
505 if (adapter.getDisplayId() != display) {
506 return HWC2_ERROR_BAD_DISPLAY;
507 }
508 if (!adapter.hasLayer(layer)) {
509 return HWC2_ERROR_BAD_LAYER;
510 }
511
512 adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
513 return HWC2_ERROR_NONE;
514 }
515
516 template <typename PFN, typename T>
asFP(T function)517 static hwc2_function_pointer_t asFP(T function) {
518 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
519 return reinterpret_cast<hwc2_function_pointer_t>(function);
520 }
521
getFunctionHook(hwc2_device_t *,int32_t descriptor)522 hwc2_function_pointer_t getFunctionHook(hwc2_device_t* /*device*/, int32_t descriptor) {
523 switch (descriptor) {
524 // global functions
525 case HWC2_FUNCTION_DUMP:
526 return asFP<HWC2_PFN_DUMP>(dumpHook);
527 case HWC2_FUNCTION_REGISTER_CALLBACK:
528 return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
529
530 // virtual display functions
531 case HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT:
532 return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(getMaxVirtualDisplayCountHook);
533 case HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY:
534 return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(createVirtualDisplayHook);
535 case HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY:
536 return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(destroyVirtualDisplayHook);
537 case HWC2_FUNCTION_SET_OUTPUT_BUFFER:
538 return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(setOutputBufferHook);
539
540 // display functions
541 case HWC2_FUNCTION_GET_DISPLAY_NAME:
542 return asFP<HWC2_PFN_GET_DISPLAY_NAME>(getDisplayNameHook);
543 case HWC2_FUNCTION_GET_DISPLAY_TYPE:
544 return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(getDisplayTypeHook);
545 case HWC2_FUNCTION_GET_DOZE_SUPPORT:
546 return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(getDozeSupportHook);
547 case HWC2_FUNCTION_GET_HDR_CAPABILITIES:
548 return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(getHdrCapabilitiesHook);
549 case HWC2_FUNCTION_SET_POWER_MODE:
550 return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook);
551 case HWC2_FUNCTION_SET_VSYNC_ENABLED:
552 return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(setVsyncEnabledHook);
553 case HWC2_FUNCTION_GET_COLOR_MODES:
554 return asFP<HWC2_PFN_GET_COLOR_MODES>(getColorModesHook);
555 case HWC2_FUNCTION_SET_COLOR_MODE:
556 return asFP<HWC2_PFN_SET_COLOR_MODE>(setColorModeHook);
557 case HWC2_FUNCTION_SET_COLOR_TRANSFORM:
558 return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
559 case HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT:
560 return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(getClientTargetSupportHook);
561 case HWC2_FUNCTION_SET_CLIENT_TARGET:
562 return asFP<HWC2_PFN_SET_CLIENT_TARGET>(setClientTargetHook);
563
564 // config functions
565 case HWC2_FUNCTION_GET_DISPLAY_CONFIGS:
566 return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(getDisplayConfigsHook);
567 case HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE:
568 return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(getDisplayAttributeHook);
569 case HWC2_FUNCTION_GET_ACTIVE_CONFIG:
570 return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(getActiveConfigHook);
571 case HWC2_FUNCTION_SET_ACTIVE_CONFIG:
572 return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(setActiveConfigHook);
573
574 // validate/present functions
575 case HWC2_FUNCTION_VALIDATE_DISPLAY:
576 return asFP<HWC2_PFN_VALIDATE_DISPLAY>(validateDisplayHook);
577 case HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES:
578 return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(getChangedCompositionTypesHook);
579 case HWC2_FUNCTION_GET_DISPLAY_REQUESTS:
580 return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(getDisplayRequestsHook);
581 case HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES:
582 return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(acceptDisplayChangesHook);
583 case HWC2_FUNCTION_PRESENT_DISPLAY:
584 return asFP<HWC2_PFN_PRESENT_DISPLAY>(presentDisplayHook);
585 case HWC2_FUNCTION_GET_RELEASE_FENCES:
586 return asFP<HWC2_PFN_GET_RELEASE_FENCES>(getReleaseFencesHook);
587
588 // layer create/destroy
589 case HWC2_FUNCTION_CREATE_LAYER:
590 return asFP<HWC2_PFN_CREATE_LAYER>(createLayerHook);
591 case HWC2_FUNCTION_DESTROY_LAYER:
592 return asFP<HWC2_PFN_DESTROY_LAYER>(destroyLayerHook);
593
594 // layer functions; validateDisplay not required
595 case HWC2_FUNCTION_SET_CURSOR_POSITION:
596 return asFP<HWC2_PFN_SET_CURSOR_POSITION>(setCursorPositionHook);
597 case HWC2_FUNCTION_SET_LAYER_BUFFER:
598 return asFP<HWC2_PFN_SET_LAYER_BUFFER>(setLayerBufferHook);
599 case HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE:
600 return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(setLayerSurfaceDamageHook);
601
602 // layer state functions; validateDisplay required
603 case HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE:
604 return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(setLayerCompositionTypeHook);
605 case HWC2_FUNCTION_SET_LAYER_BLEND_MODE:
606 return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(setLayerStateHook<int32_t>);
607 case HWC2_FUNCTION_SET_LAYER_COLOR:
608 return asFP<HWC2_PFN_SET_LAYER_COLOR>(setLayerStateHook<hwc_color_t>);
609 case HWC2_FUNCTION_SET_LAYER_DATASPACE:
610 return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerStateHook<int32_t>);
611 case HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME:
612 return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(setLayerStateHook<hwc_rect_t>);
613 case HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA:
614 return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(setLayerStateHook<float>);
615 case HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM:
616 return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(setLayerStateHook<buffer_handle_t>);
617 case HWC2_FUNCTION_SET_LAYER_SOURCE_CROP:
618 return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(setLayerStateHook<hwc_frect_t>);
619 case HWC2_FUNCTION_SET_LAYER_TRANSFORM:
620 return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(setLayerStateHook<int32_t>);
621 case HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION:
622 return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(setLayerStateHook<hwc_region_t>);
623 case HWC2_FUNCTION_SET_LAYER_Z_ORDER:
624 return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(setLayerStateHook<uint32_t>);
625
626 default:
627 ALOGE("unknown function descriptor %d", descriptor);
628 return nullptr;
629 }
630 }
631
getCapabilitiesHook(hwc2_device_t *,uint32_t * outCount,int32_t *)632 void getCapabilitiesHook(hwc2_device_t* /*device*/, uint32_t* outCount,
633 int32_t* /*outCapabilities*/) {
634 *outCount = 0;
635 }
636
closeHook(hw_device_t * device)637 int closeHook(hw_device_t* device) {
638 auto& adapter = HWC2OnFbAdapter::cast(device);
639 adapter.close();
640 return 0;
641 }
642
643 } // anonymous namespace
644
HWC2OnFbAdapter(framebuffer_device_t * fbDevice)645 HWC2OnFbAdapter::HWC2OnFbAdapter(framebuffer_device_t* fbDevice)
646 : hwc2_device_t(), mFbDevice(fbDevice) {
647 common.close = closeHook;
648 hwc2_device::getCapabilities = getCapabilitiesHook;
649 hwc2_device::getFunction = getFunctionHook;
650
651 mFbInfo.name = "fbdev";
652 mFbInfo.width = mFbDevice->width;
653 mFbInfo.height = mFbDevice->height;
654 mFbInfo.format = mFbDevice->format;
655 mFbInfo.vsync_period_ns = int(1e9 / mFbDevice->fps);
656 mFbInfo.xdpi_scaled = int(mFbDevice->xdpi * 1000.0f);
657 mFbInfo.ydpi_scaled = int(mFbDevice->ydpi * 1000.0f);
658
659 mVsyncThread.start(0, mFbInfo.vsync_period_ns);
660 }
661
cast(hw_device_t * device)662 HWC2OnFbAdapter& HWC2OnFbAdapter::cast(hw_device_t* device) {
663 return *reinterpret_cast<HWC2OnFbAdapter*>(device);
664 }
665
cast(hwc2_device_t * device)666 HWC2OnFbAdapter& HWC2OnFbAdapter::cast(hwc2_device_t* device) {
667 return *reinterpret_cast<HWC2OnFbAdapter*>(device);
668 }
669
getDisplayId()670 hwc2_display_t HWC2OnFbAdapter::getDisplayId() {
671 return 0;
672 }
673
getConfigId()674 hwc2_config_t HWC2OnFbAdapter::getConfigId() {
675 return 0;
676 }
677
close()678 void HWC2OnFbAdapter::close() {
679 mVsyncThread.stop();
680 framebuffer_close(mFbDevice);
681 }
682
getInfo() const683 const HWC2OnFbAdapter::Info& HWC2OnFbAdapter::getInfo() const {
684 return mFbInfo;
685 }
686
updateDebugString()687 void HWC2OnFbAdapter::updateDebugString() {
688 if (mFbDevice->common.version >= 1 && mFbDevice->dump) {
689 char buffer[4096];
690 mFbDevice->dump(mFbDevice, buffer, sizeof(buffer));
691 buffer[sizeof(buffer) - 1] = '\0';
692
693 mDebugString = buffer;
694 }
695 }
696
getDebugString() const697 const std::string& HWC2OnFbAdapter::getDebugString() const {
698 return mDebugString;
699 }
700
setState(State state)701 void HWC2OnFbAdapter::setState(State state) {
702 mState = state;
703 }
704
getState() const705 HWC2OnFbAdapter::State HWC2OnFbAdapter::getState() const {
706 return mState;
707 }
708
addLayer()709 hwc2_layer_t HWC2OnFbAdapter::addLayer() {
710 hwc2_layer_t id = ++mNextLayerId;
711
712 mLayers.insert(id);
713 mDirtyLayers.insert(id);
714
715 return id;
716 }
717
removeLayer(hwc2_layer_t layer)718 bool HWC2OnFbAdapter::removeLayer(hwc2_layer_t layer) {
719 mDirtyLayers.erase(layer);
720 return mLayers.erase(layer);
721 }
722
hasLayer(hwc2_layer_t layer) const723 bool HWC2OnFbAdapter::hasLayer(hwc2_layer_t layer) const {
724 return mLayers.count(layer) > 0;
725 }
726
markLayerDirty(hwc2_layer_t layer,bool dirty)727 bool HWC2OnFbAdapter::markLayerDirty(hwc2_layer_t layer, bool dirty) {
728 if (mLayers.count(layer) == 0) {
729 return false;
730 }
731
732 if (dirty) {
733 mDirtyLayers.insert(layer);
734 } else {
735 mDirtyLayers.erase(layer);
736 }
737
738 return true;
739 }
740
getDirtyLayers() const741 const std::unordered_set<hwc2_layer_t>& HWC2OnFbAdapter::getDirtyLayers() const {
742 return mDirtyLayers;
743 }
744
clearDirtyLayers()745 void HWC2OnFbAdapter::clearDirtyLayers() {
746 mDirtyLayers.clear();
747 }
748
749 /*
750 * For each frame, SurfaceFlinger
751 *
752 * - peforms GLES composition
753 * - calls eglSwapBuffers
754 * - calls setClientTarget, which maps to setBuffer below
755 * - calls presentDisplay, which maps to postBuffer below
756 *
757 * setBuffer should be a good place to call compositionComplete.
758 *
759 * As for post, it
760 *
761 * - schedules the buffer for presentation on the next vsync
762 * - locks the buffer and blocks all other users trying to lock it
763 *
764 * It does not give us a way to return a present fence, and we need to live
765 * with that. The implication is that, when we are double-buffered,
766 * SurfaceFlinger assumes the front buffer is available for rendering again
767 * immediately after the back buffer is posted. The locking semantics
768 * hopefully are strong enough that the rendering will be blocked.
769 */
setBuffer(buffer_handle_t buffer)770 void HWC2OnFbAdapter::setBuffer(buffer_handle_t buffer) {
771 if (mFbDevice->compositionComplete) {
772 mFbDevice->compositionComplete(mFbDevice);
773 }
774 mBuffer = buffer;
775 }
776
postBuffer()777 bool HWC2OnFbAdapter::postBuffer() {
778 int error = 0;
779 if (mBuffer) {
780 error = mFbDevice->post(mFbDevice, mBuffer);
781 }
782
783 return error == 0;
784 }
785
setVsyncCallback(HWC2_PFN_VSYNC callback,hwc2_callback_data_t data)786 void HWC2OnFbAdapter::setVsyncCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data) {
787 mVsyncThread.setCallback(callback, data);
788 }
789
enableVsync(bool enable)790 void HWC2OnFbAdapter::enableVsync(bool enable) {
791 mVsyncThread.enableCallback(enable);
792 }
793
now()794 int64_t HWC2OnFbAdapter::VsyncThread::now() {
795 struct timespec ts;
796 clock_gettime(CLOCK_MONOTONIC, &ts);
797
798 return int64_t(ts.tv_sec) * 1'000'000'000 + ts.tv_nsec;
799 }
800
sleepUntil(int64_t t)801 bool HWC2OnFbAdapter::VsyncThread::sleepUntil(int64_t t) {
802 struct timespec ts;
803 ts.tv_sec = t / 1'000'000'000;
804 ts.tv_nsec = t % 1'000'000'000;
805
806 while (true) {
807 int error = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, nullptr);
808 if (error) {
809 if (error == EINTR) {
810 continue;
811 }
812 return false;
813 } else {
814 return true;
815 }
816 }
817 }
818
start(int64_t firstVsync,int64_t period)819 void HWC2OnFbAdapter::VsyncThread::start(int64_t firstVsync, int64_t period) {
820 mNextVsync = firstVsync;
821 mPeriod = period;
822 mStarted = true;
823 mThread = std::thread(&VsyncThread::vsyncLoop, this);
824 }
825
stop()826 void HWC2OnFbAdapter::VsyncThread::stop() {
827 {
828 std::lock_guard<std::mutex> lock(mMutex);
829 mStarted = false;
830 }
831 mCondition.notify_all();
832 mThread.join();
833 }
834
setCallback(HWC2_PFN_VSYNC callback,hwc2_callback_data_t data)835 void HWC2OnFbAdapter::VsyncThread::setCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data) {
836 std::lock_guard<std::mutex> lock(mMutex);
837 mCallback = callback;
838 mCallbackData = data;
839 }
840
enableCallback(bool enable)841 void HWC2OnFbAdapter::VsyncThread::enableCallback(bool enable) {
842 {
843 std::lock_guard<std::mutex> lock(mMutex);
844 mCallbackEnabled = enable;
845 }
846 mCondition.notify_all();
847 }
848
vsyncLoop()849 void HWC2OnFbAdapter::VsyncThread::vsyncLoop() {
850 prctl(PR_SET_NAME, "VsyncThread", 0, 0, 0);
851
852 std::unique_lock<std::mutex> lock(mMutex);
853 if (!mStarted) {
854 return;
855 }
856
857 while (true) {
858 if (!mCallbackEnabled) {
859 mCondition.wait(lock, [this] { return mCallbackEnabled || !mStarted; });
860 if (!mStarted) {
861 break;
862 }
863 }
864
865 lock.unlock();
866
867 // adjust mNextVsync if necessary
868 int64_t t = now();
869 if (mNextVsync < t) {
870 int64_t n = (t - mNextVsync + mPeriod - 1) / mPeriod;
871 mNextVsync += mPeriod * n;
872 }
873 bool fire = sleepUntil(mNextVsync);
874
875 lock.lock();
876
877 if (fire) {
878 ALOGV("VsyncThread(%" PRId64 ")", mNextVsync);
879 if (mCallback) {
880 mCallback(mCallbackData, getDisplayId(), mNextVsync);
881 }
882 mNextVsync += mPeriod;
883 }
884 }
885 }
886
887 } // namespace android
888