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