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