• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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