• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "Device.h"
18 
19 #include <android-base/properties.h>
20 
21 #include "GuestComposer.h"
22 #include "HostComposer.h"
23 
24 namespace android {
25 namespace {
26 
27 template <typename PFN, typename T>
asFP(T function)28 static hwc2_function_pointer_t asFP(T function) {
29   static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
30   return reinterpret_cast<hwc2_function_pointer_t>(function);
31 }
32 
CloseHook(hw_device_t * dev)33 static int CloseHook(hw_device_t* dev) {
34   Device* device = Device::fromDevice(dev);
35   delete device;
36   return 0;
37 }
38 
IsCuttlefish()39 bool IsCuttlefish() {
40   return android::base::GetProperty("ro.hardware.vulkan", "") == "pastel";
41 }
42 
43 }  // namespace
44 
Device()45 Device::Device() {
46   DEBUG_LOG("%s", __FUNCTION__);
47 
48   common.tag = HARDWARE_DEVICE_TAG;
49   common.version = HWC_DEVICE_API_VERSION_2_0;
50   common.close = CloseHook;
51   hwc2_device_t::getCapabilities = getCapabilitiesHook;
52   hwc2_device_t::getFunction = getFunctionHook;
53 }
54 
init()55 HWC2::Error Device::init() {
56   DEBUG_LOG("%s", __FUNCTION__);
57 
58   if (IsCuttlefish()) {
59     mComposer = std::make_unique<GuestComposer>();
60   } else {
61     mComposer = std::make_unique<HostComposer>();
62   }
63 
64   HWC2::Error error = mComposer->init(
65       [this](bool connected, uint32_t id, uint32_t width, uint32_t height,
66              uint32_t dpiX, uint32_t dpiY, uint32_t refreshRate) {
67         handleHotplug(connected, id, width, height, dpiX, dpiY, refreshRate);
68       });
69 
70   if (error != HWC2::Error::None) {
71     ALOGE("%s failed to initialize Composer", __FUNCTION__);
72     return HWC2::Error::NoResources;
73   }
74 
75   return HWC2::Error::None;
76 }
77 
~Device()78 Device::~Device() {
79   DEBUG_LOG("%s", __FUNCTION__);
80 
81   HWC2::Error error = HWC2::Error::None;
82 
83   error = destroyDisplays();
84   if (error != HWC2::Error::None) {
85     ALOGE("%s failed to destroy displays", __FUNCTION__);
86   }
87 }
88 
createDisplays()89 HWC2::Error Device::createDisplays() {
90   DEBUG_LOG("%s", __FUNCTION__);
91 
92   std::unique_lock<std::mutex> lock(mStateMutex);
93 
94   if (!mComposer) {
95     ALOGE("%s composer not initialized!", __FUNCTION__);
96     return HWC2::Error::NoResources;
97   }
98 
99   auto addDisplayLockedFn = [this](std::unique_ptr<Display> display) {
100     auto displayId = display->getId();
101     DEBUG_LOG("%s: adding display:%" PRIu64, __FUNCTION__, displayId);
102     mDisplays.emplace(displayId, std::move(display));
103     return HWC2::Error::None;
104   };
105 
106   HWC2::Error error = mComposer->createDisplays(this, addDisplayLockedFn);
107   if (error != HWC2::Error::None) {
108     ALOGE("%s composer failed to create displays", __FUNCTION__);
109     return error;
110   }
111 
112   return HWC2::Error::None;
113 }
114 
createDisplay(uint32_t displayId,uint32_t width,uint32_t height,uint32_t dpiX,uint32_t dpiY,uint32_t refreshRate)115 HWC2::Error Device::createDisplay(uint32_t displayId, uint32_t width,
116                                   uint32_t height, uint32_t dpiX, uint32_t dpiY,
117                                   uint32_t refreshRate) {
118   if (!mComposer) {
119     ALOGE("%s composer not initialized!", __FUNCTION__);
120     return HWC2::Error::NoResources;
121   }
122 
123   auto addDisplayLockedFn = [this](std::unique_ptr<Display> display) {
124     auto displayId = display->getId();
125     DEBUG_LOG("%s: adding display:%" PRIu64, __FUNCTION__, displayId);
126     mDisplays.emplace(displayId, std::move(display));
127     return HWC2::Error::None;
128   };
129 
130   HWC2::Error error =
131       mComposer->createDisplay(this, displayId, width, height, dpiX, dpiY,
132                                refreshRate, addDisplayLockedFn);
133   if (error != HWC2::Error::None) {
134     ALOGE("%s composer failed to create displays", __FUNCTION__);
135     return error;
136   }
137 
138   return HWC2::Error::None;
139 }
140 
destroyDisplays()141 HWC2::Error Device::destroyDisplays() {
142   DEBUG_LOG("%s", __FUNCTION__);
143 
144   std::unique_lock<std::mutex> lock(mStateMutex);
145 
146   if (!mComposer) {
147     ALOGE("%s composer not initialized!", __FUNCTION__);
148     return HWC2::Error::NoResources;
149   }
150 
151   for (auto& [displayId, displayPtr] : mDisplays) {
152     HWC2::Error error = mComposer->onDisplayDestroy(displayPtr.get());
153     if (error != HWC2::Error::None) {
154       ALOGE("%s composer failed to destroy displays", __FUNCTION__);
155       return error;
156     }
157 
158     displayPtr.reset();
159   }
160 
161   mDisplays.clear();
162 
163   return HWC2::Error::None;
164 }
165 
getCapabilities(uint32_t * outCount,int32_t * outCapabilities)166 void Device::getCapabilities(uint32_t* outCount, int32_t* outCapabilities) {
167   DEBUG_LOG("%s", __FUNCTION__);
168 
169   if (outCapabilities == nullptr) {
170     *outCount = mCapabilities.size();
171     return;
172   }
173 
174   auto capabilityIter = mCapabilities.cbegin();
175   for (size_t i = 0; i < *outCount; ++i) {
176     if (capabilityIter == mCapabilities.cend()) {
177       return;
178     }
179     outCapabilities[i] = static_cast<int32_t>(*capabilityIter);
180     ++capabilityIter;
181   }
182 }
183 
184 /*static*/
getCapabilitiesHook(hwc2_device_t * dev,uint32_t * outCount,int32_t * outCapabilities)185 void Device::getCapabilitiesHook(hwc2_device_t* dev, uint32_t* outCount,
186                                  int32_t* outCapabilities) {
187   DEBUG_LOG("%s", __FUNCTION__);
188 
189   Device* device = Device::fromDevice(dev);
190   device->getCapabilities(outCount, outCapabilities);
191 }
192 
getFunction(int32_t desc)193 hwc2_function_pointer_t Device::getFunction(int32_t desc) {
194   const auto func = static_cast<HWC2::FunctionDescriptor>(desc);
195   const auto funcString = to_string(func);
196   DEBUG_LOG("%s(%s)", __FUNCTION__, funcString.c_str());
197 
198   switch (func) {
199     // Device functions.
200     case HWC2::FunctionDescriptor::CreateVirtualDisplay:
201       return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
202           DeviceHook<int32_t, decltype(&Device::createVirtualDisplay),
203                      &Device::createVirtualDisplay, uint32_t, uint32_t,
204                      int32_t*, hwc2_display_t*>);
205     case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
206       return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
207           DeviceHook<int32_t, decltype(&Device::destroyVirtualDisplay),
208                      &Device::destroyVirtualDisplay, hwc2_display_t>);
209     case HWC2::FunctionDescriptor::Dump:
210       return asFP<HWC2_PFN_DUMP>(DeviceHook<void, decltype(&Device::dump),
211                                             &Device::dump, uint32_t*, char*>);
212     case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
213       return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
214           DeviceHook<uint32_t, decltype(&Device::getMaxVirtualDisplayCount),
215                      &Device::getMaxVirtualDisplayCount>);
216     case HWC2::FunctionDescriptor::RegisterCallback:
217       return asFP<HWC2_PFN_REGISTER_CALLBACK>(
218           DeviceHook<int32_t, decltype(&Device::registerCallback),
219                      &Device::registerCallback, int32_t, hwc2_callback_data_t,
220                      hwc2_function_pointer_t>);
221 
222     // Display functions
223     case HWC2::FunctionDescriptor::AcceptDisplayChanges:
224       return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
225           displayHook<decltype(&Display::acceptChanges),
226                       &Display::acceptChanges>);
227     case HWC2::FunctionDescriptor::CreateLayer:
228       return asFP<HWC2_PFN_CREATE_LAYER>(
229           displayHook<decltype(&Display::createLayer), &Display::createLayer,
230                       hwc2_layer_t*>);
231     case HWC2::FunctionDescriptor::DestroyLayer:
232       return asFP<HWC2_PFN_DESTROY_LAYER>(
233           displayHook<decltype(&Display::destroyLayer), &Display::destroyLayer,
234                       hwc2_layer_t>);
235     case HWC2::FunctionDescriptor::GetActiveConfig:
236       return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(
237           displayHook<decltype(&Display::getActiveConfig),
238                       &Display::getActiveConfig, hwc2_config_t*>);
239     case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
240       return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
241           displayHook<decltype(&Display::getChangedCompositionTypes),
242                       &Display::getChangedCompositionTypes, uint32_t*,
243                       hwc2_layer_t*, int32_t*>);
244     case HWC2::FunctionDescriptor::GetColorModes:
245       return asFP<HWC2_PFN_GET_COLOR_MODES>(
246           displayHook<decltype(&Display::getColorModes),
247                       &Display::getColorModes, uint32_t*, int32_t*>);
248     case HWC2::FunctionDescriptor::GetDisplayAttribute:
249       return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
250           displayHook<decltype(&Display::getDisplayAttribute),
251                       &Display::getDisplayAttribute, hwc2_config_t, int32_t,
252                       int32_t*>);
253     case HWC2::FunctionDescriptor::GetDisplayConfigs:
254       return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(
255           displayHook<decltype(&Display::getConfigs), &Display::getConfigs,
256                       uint32_t*, hwc2_config_t*>);
257     case HWC2::FunctionDescriptor::GetDisplayName:
258       return asFP<HWC2_PFN_GET_DISPLAY_NAME>(
259           displayHook<decltype(&Display::getName), &Display::getName, uint32_t*,
260                       char*>);
261     case HWC2::FunctionDescriptor::GetDisplayRequests:
262       return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(
263           displayHook<decltype(&Display::getRequests), &Display::getRequests,
264                       int32_t*, uint32_t*, hwc2_layer_t*, int32_t*>);
265     case HWC2::FunctionDescriptor::GetDisplayType:
266       return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(
267           displayHook<decltype(&Display::getType), &Display::getType,
268                       int32_t*>);
269     case HWC2::FunctionDescriptor::GetDozeSupport:
270       return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(
271           displayHook<decltype(&Display::getDozeSupport),
272                       &Display::getDozeSupport, int32_t*>);
273     case HWC2::FunctionDescriptor::GetHdrCapabilities:
274       return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(
275           displayHook<decltype(&Display::getHdrCapabilities),
276                       &Display::getHdrCapabilities, uint32_t*, int32_t*, float*,
277                       float*, float*>);
278     case HWC2::FunctionDescriptor::GetReleaseFences:
279       return asFP<HWC2_PFN_GET_RELEASE_FENCES>(
280           displayHook<decltype(&Display::getReleaseFences),
281                       &Display::getReleaseFences, uint32_t*, hwc2_layer_t*,
282                       int32_t*>);
283     case HWC2::FunctionDescriptor::PresentDisplay:
284       return asFP<HWC2_PFN_PRESENT_DISPLAY>(
285           displayHook<decltype(&Display::present), &Display::present,
286                       int32_t*>);
287     case HWC2::FunctionDescriptor::SetActiveConfig:
288       return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(
289           displayHook<decltype(&Display::setActiveConfig),
290                       &Display::setActiveConfig, hwc2_config_t>);
291     case HWC2::FunctionDescriptor::SetClientTarget:
292       return asFP<HWC2_PFN_SET_CLIENT_TARGET>(
293           displayHook<decltype(&Display::setClientTarget),
294                       &Display::setClientTarget, buffer_handle_t, int32_t,
295                       int32_t, hwc_region_t>);
296     case HWC2::FunctionDescriptor::SetColorMode:
297       return asFP<HWC2_PFN_SET_COLOR_MODE>(
298           displayHook<decltype(&Display::setColorMode), &Display::setColorMode,
299                       int32_t>);
300     case HWC2::FunctionDescriptor::SetColorTransform:
301       return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(
302           displayHook<decltype(&Display::setColorTransform),
303                       &Display::setColorTransform, const float*, int32_t>);
304     case HWC2::FunctionDescriptor::SetOutputBuffer:
305       return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
306           displayHook<decltype(&Display::setOutputBuffer),
307                       &Display::setOutputBuffer, buffer_handle_t, int32_t>);
308     case HWC2::FunctionDescriptor::SetPowerMode:
309       return asFP<HWC2_PFN_SET_POWER_MODE>(
310           displayHook<decltype(&Display::setPowerMode), &Display::setPowerMode,
311                       int32_t>);
312     case HWC2::FunctionDescriptor::SetVsyncEnabled:
313       return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(
314           displayHook<decltype(&Display::setVsyncEnabled),
315                       &Display::setVsyncEnabled, int32_t>);
316     case HWC2::FunctionDescriptor::ValidateDisplay:
317       return asFP<HWC2_PFN_VALIDATE_DISPLAY>(
318           displayHook<decltype(&Display::validate), &Display::validate,
319                       uint32_t*, uint32_t*>);
320     case HWC2::FunctionDescriptor::GetClientTargetSupport:
321       return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
322           displayHook<decltype(&Display::getClientTargetSupport),
323                       &Display::getClientTargetSupport, uint32_t, uint32_t,
324                       int32_t, int32_t>);
325     case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
326       return asFP<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
327           displayHook<decltype(&Display::getDisplayIdentificationData),
328                       &Display::getDisplayIdentificationData, uint8_t*,
329                       uint32_t*, uint8_t*>);
330     case HWC2::FunctionDescriptor::GetDisplayCapabilities:
331       return asFP<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
332           displayHook<decltype(&Display::getDisplayCapabilities),
333                       &Display::getDisplayCapabilities, uint32_t*, uint32_t*>);
334     case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
335       return asFP<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(
336           displayHook<decltype(&Display::getDisplayBrightnessSupport),
337                       &Display::getDisplayBrightnessSupport, bool*>);
338     case HWC2::FunctionDescriptor::SetDisplayBrightness:
339       return asFP<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(
340           displayHook<decltype(&Display::setDisplayBrightness),
341                       &Display::setDisplayBrightness, float>);
342 
343     // Layer functions
344     case HWC2::FunctionDescriptor::SetCursorPosition:
345       return asFP<HWC2_PFN_SET_CURSOR_POSITION>(
346           layerHook<decltype(&Layer::setCursorPosition),
347                     &Layer::setCursorPosition, int32_t, int32_t>);
348     case HWC2::FunctionDescriptor::SetLayerBuffer:
349       return asFP<HWC2_PFN_SET_LAYER_BUFFER>(
350           layerHook<decltype(&Layer::setBuffer), &Layer::setBuffer,
351                     buffer_handle_t, int32_t>);
352     case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
353       return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
354           layerHook<decltype(&Layer::setSurfaceDamage),
355                     &Layer::setSurfaceDamage, hwc_region_t>);
356     case HWC2::FunctionDescriptor::SetLayerBlendMode:
357       return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(
358           layerHook<decltype(&Layer::setBlendMode), &Layer::setBlendMode,
359                     int32_t>);
360     case HWC2::FunctionDescriptor::SetLayerColor:
361       return asFP<HWC2_PFN_SET_LAYER_COLOR>(
362           layerHook<decltype(&Layer::setColor), &Layer::setColor, hwc_color_t>);
363     case HWC2::FunctionDescriptor::SetLayerCompositionType:
364       return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
365           layerHook<decltype(&Layer::setCompositionType),
366                     &Layer::setCompositionType, int32_t>);
367     case HWC2::FunctionDescriptor::SetLayerDataspace:
368       return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(
369           layerHook<decltype(&Layer::setDataspace), &Layer::setDataspace,
370                     int32_t>);
371     case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
372       return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
373           layerHook<decltype(&Layer::setDisplayFrame), &Layer::setDisplayFrame,
374                     hwc_rect_t>);
375     case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
376       return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
377           layerHook<decltype(&Layer::setPlaneAlpha), &Layer::setPlaneAlpha,
378                     float>);
379     case HWC2::FunctionDescriptor::SetLayerSidebandStream:
380       return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
381           layerHook<decltype(&Layer::setSidebandStream),
382                     &Layer::setSidebandStream, const native_handle_t*>);
383     case HWC2::FunctionDescriptor::SetLayerSourceCrop:
384       return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
385           layerHook<decltype(&Layer::setSourceCrop), &Layer::setSourceCrop,
386                     hwc_frect_t>);
387     case HWC2::FunctionDescriptor::SetLayerTransform:
388       return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(
389           layerHook<decltype(&Layer::setTransform), &Layer::setTransform,
390                     int32_t>);
391     case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
392       return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
393           layerHook<decltype(&Layer::setVisibleRegion),
394                     &Layer::setVisibleRegion, hwc_region_t>);
395     case HWC2::FunctionDescriptor::SetLayerZOrder:
396       return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(
397           displayHook<decltype(&Display::updateLayerZ), &Display::updateLayerZ,
398                       hwc2_layer_t, uint32_t>);
399 
400     default:
401       ALOGE("GetFunction: Unknown function descriptor: %d",
402             static_cast<int32_t>(desc));
403       return nullptr;
404   }
405 }
406 
407 /*static*/
getFunctionHook(hwc2_device_t * dev,int32_t desc)408 hwc2_function_pointer_t Device::getFunctionHook(hwc2_device_t* dev,
409                                                 int32_t desc) {
410   Device* device = Device::fromDevice(dev);
411   return device->getFunction(desc);
412 }
413 
414 // Device functions
415 
createVirtualDisplay(uint32_t,uint32_t,int32_t *,hwc2_display_t *)416 HWC2::Error Device::createVirtualDisplay(uint32_t /*width*/,
417                                          uint32_t /*height*/,
418                                          int32_t* /*format*/,
419                                          hwc2_display_t* /*outDisplay*/) {
420   DEBUG_LOG("%s", __FUNCTION__);
421   // TODO: VirtualDisplay support
422   return HWC2::Error::None;
423 }
424 
destroyVirtualDisplay(hwc2_display_t)425 HWC2::Error Device::destroyVirtualDisplay(hwc2_display_t /*displayId*/) {
426   DEBUG_LOG("%s", __FUNCTION__);
427   // TODO: VirtualDisplay support
428   return HWC2::Error::None;
429 }
430 
dump(uint32_t *,char *)431 void Device::dump(uint32_t* /*outSize*/, char* /*outBuffer*/) {
432   DEBUG_LOG("%s", __FUNCTION__);
433   // TODO:
434   return;
435 }
436 
getMaxVirtualDisplayCount()437 uint32_t Device::getMaxVirtualDisplayCount() {
438   DEBUG_LOG("%s", __FUNCTION__);
439   // TODO: VirtualDisplay support
440   return 0;
441 }
442 
IsHandledCallback(HWC2::Callback descriptor)443 static bool IsHandledCallback(HWC2::Callback descriptor) {
444   switch (descriptor) {
445     case HWC2::Callback::Hotplug: {
446       return true;
447     }
448     case HWC2::Callback::Refresh: {
449       return true;
450     }
451     case HWC2::Callback::Vsync: {
452       return true;
453     }
454     case HWC2::Callback::Vsync_2_4: {
455       return false;
456     }
457     case HWC2::Callback::VsyncPeriodTimingChanged: {
458       return false;
459     }
460     case HWC2::Callback::Invalid: {
461       return false;
462     }
463     case HWC2::Callback::SeamlessPossible: {
464       return false;
465     }
466   }
467   return false;
468 }
469 
registerCallback(int32_t desc,hwc2_callback_data_t callbackData,hwc2_function_pointer_t pointer)470 HWC2::Error Device::registerCallback(int32_t desc,
471                                      hwc2_callback_data_t callbackData,
472                                      hwc2_function_pointer_t pointer) {
473   const auto callbackType = static_cast<HWC2::Callback>(desc);
474   const auto callbackTypeString = to_string(callbackType);
475   DEBUG_LOG("%s callback %s", __FUNCTION__, callbackTypeString.c_str());
476 
477   if (!IsHandledCallback(callbackType)) {
478     ALOGE("%s unhandled callback: %s", __FUNCTION__,
479           callbackTypeString.c_str());
480     return HWC2::Error::BadParameter;
481   }
482 
483   std::unique_lock<std::mutex> lock(mStateMutex);
484 
485   if (pointer != nullptr) {
486     mCallbacks[callbackType] = {callbackData, pointer};
487   } else {
488     mCallbacks.erase(callbackType);
489     return HWC2::Error::None;
490   }
491 
492   if (callbackType == HWC2::Callback::Hotplug) {
493     // Callback without the state lock held
494     lock.unlock();
495     auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
496     auto hotplugConnect = static_cast<int32_t>(HWC2::Connection::Connected);
497     for (const auto& [displayId, display] : mDisplays) {
498       ALOGI("%s hotplug connecting display:%" PRIu64, __FUNCTION__, displayId);
499       hotplug(callbackData, displayId, hotplugConnect);
500     }
501   }
502 
503   return HWC2::Error::None;
504 }
505 
handleHotplug(bool connected,uint32_t id,uint32_t width,uint32_t height,uint32_t dpiX,uint32_t dpiY,uint32_t refreshRate)506 bool Device::handleHotplug(bool connected, uint32_t id, uint32_t width,
507                            uint32_t height, uint32_t dpiX, uint32_t dpiY,
508                            uint32_t refreshRate) {
509   std::unique_lock<std::mutex> lock(mStateMutex);
510   if (mCallbacks[HWC2::Callback::Hotplug].pointer == nullptr) {
511     return false;
512   }
513   auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(
514       mCallbacks[HWC2::Callback::Hotplug].pointer);
515   auto hotplugConnect = static_cast<int32_t>(HWC2::Connection::Connected);
516   auto hotplugDisconnect = static_cast<int32_t>(HWC2::Connection::Disconnected);
517   Display* display = getDisplay(id);
518   if (display) {
519     // if existed, disconnect first
520     ALOGD("callback hotplugDisconnect display %" PRIu32, id);
521     hotplug(mCallbacks[HWC2::Callback::Hotplug].data, id, hotplugDisconnect);
522     display->lock();
523     mComposer->onDisplayDestroy(display);
524     display->unlock();
525   }
526   if (connected) {
527     createDisplay(id, width, height, dpiX, dpiY, refreshRate);
528     ALOGD("callback hotplugConnect display %" PRIu32 " width %" PRIu32
529           " height %" PRIu32 " dpiX %" PRIu32 " dpiY %" PRIu32
530           "fps %" PRIu32, id, width, height, dpiX, dpiY, refreshRate);
531     hotplug(mCallbacks[HWC2::Callback::Hotplug].data, id, hotplugConnect);
532   };
533 
534   return true;
535 }
536 
getDisplay(hwc2_display_t id)537 Display* Device::getDisplay(hwc2_display_t id) {
538   auto display = mDisplays.find(id);
539   if (display == mDisplays.end()) {
540     ALOGW("Failed to get display for id=%d", (uint32_t)id);
541     return nullptr;
542   }
543   return display->second.get();
544 }
545 
OpenDevice(const struct hw_module_t * module,const char * name,struct hw_device_t ** dev)546 static int OpenDevice(const struct hw_module_t* module, const char* name,
547                       struct hw_device_t** dev) {
548   DEBUG_LOG("%s ", __FUNCTION__);
549 
550   if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
551     ALOGE("Invalid module name- %s", name);
552     return -EINVAL;
553   }
554 
555   std::unique_ptr<Device> device = std::make_unique<Device>();
556   HWC2::Error error = device->init();
557   if (error != HWC2::Error::None) {
558     ALOGE("%s: failed to initialize device", __FUNCTION__);
559     return -EINVAL;
560   }
561 
562   error = device->createDisplays();
563   if (error != HWC2::Error::None) {
564     ALOGE("%s: failed to initialize device displays.", __FUNCTION__);
565     return -EINVAL;
566   }
567 
568   device->common.module = const_cast<hw_module_t*>(module);
569   *dev = &device.release()->common;
570   return 0;
571 }
572 
573 }  // namespace android
574 
575 static struct hw_module_methods_t hwc2_module_methods = {
576     .open = android::OpenDevice,
577 };
578 
579 hw_module_t HAL_MODULE_INFO_SYM = {
580     .tag = HARDWARE_MODULE_TAG,
581     .version_major = 2,
582     .version_minor = 3,
583     .id = HWC_HARDWARE_MODULE_ID,
584     .name = "goldfish HWC2 module",
585     .author = "The Android Open Source Project",
586     .methods = &hwc2_module_methods,
587     .dso = NULL,
588     .reserved = {0},
589 };
590