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