1 /*
2 * Copyright 2015 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_NDEBUG 0
18
19 #undef LOG_TAG
20 #define LOG_TAG "HWC2"
21 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
22
23 #include "HWC2.h"
24
25 #include "FloatRect.h"
26
27 #include <ui/Fence.h>
28 #include <ui/GraphicBuffer.h>
29 #include <ui/Region.h>
30
31 #include <android/configuration.h>
32
33 #include <algorithm>
34 #include <inttypes.h>
35
36 extern "C" {
hotplug_hook(hwc2_callback_data_t callbackData,hwc2_display_t displayId,int32_t intConnected)37 static void hotplug_hook(hwc2_callback_data_t callbackData,
38 hwc2_display_t displayId, int32_t intConnected) {
39 auto device = static_cast<HWC2::Device*>(callbackData);
40 auto display = device->getDisplayById(displayId);
41 if (display) {
42 auto connected = static_cast<HWC2::Connection>(intConnected);
43 device->callHotplug(std::move(display), connected);
44 } else {
45 ALOGE("Hotplug callback called with unknown display %" PRIu64,
46 displayId);
47 }
48 }
49
refresh_hook(hwc2_callback_data_t callbackData,hwc2_display_t displayId)50 static void refresh_hook(hwc2_callback_data_t callbackData,
51 hwc2_display_t displayId) {
52 auto device = static_cast<HWC2::Device*>(callbackData);
53 auto display = device->getDisplayById(displayId);
54 if (display) {
55 device->callRefresh(std::move(display));
56 } else {
57 ALOGE("Refresh callback called with unknown display %" PRIu64,
58 displayId);
59 }
60 }
61
vsync_hook(hwc2_callback_data_t callbackData,hwc2_display_t displayId,int64_t timestamp)62 static void vsync_hook(hwc2_callback_data_t callbackData,
63 hwc2_display_t displayId, int64_t timestamp) {
64 auto device = static_cast<HWC2::Device*>(callbackData);
65 auto display = device->getDisplayById(displayId);
66 if (display) {
67 device->callVsync(std::move(display), timestamp);
68 } else {
69 ALOGE("Vsync callback called with unknown display %" PRIu64,
70 displayId);
71 }
72 }
73 }
74
75 using android::Fence;
76 using android::FloatRect;
77 using android::GraphicBuffer;
78 using android::HdrCapabilities;
79 using android::Rect;
80 using android::Region;
81 using android::sp;
82
83 namespace HWC2 {
84
85 // Device methods
86
Device(hwc2_device_t * device)87 Device::Device(hwc2_device_t* device)
88 : mHwcDevice(device),
89 mCreateVirtualDisplay(nullptr),
90 mDestroyVirtualDisplay(nullptr),
91 mDump(nullptr),
92 mGetMaxVirtualDisplayCount(nullptr),
93 mRegisterCallback(nullptr),
94 mAcceptDisplayChanges(nullptr),
95 mCreateLayer(nullptr),
96 mDestroyLayer(nullptr),
97 mGetActiveConfig(nullptr),
98 mGetChangedCompositionTypes(nullptr),
99 mGetColorModes(nullptr),
100 mGetDisplayAttribute(nullptr),
101 mGetDisplayConfigs(nullptr),
102 mGetDisplayName(nullptr),
103 mGetDisplayRequests(nullptr),
104 mGetDisplayType(nullptr),
105 mGetDozeSupport(nullptr),
106 mGetHdrCapabilities(nullptr),
107 mGetReleaseFences(nullptr),
108 mPresentDisplay(nullptr),
109 mSetActiveConfig(nullptr),
110 mSetClientTarget(nullptr),
111 mSetColorMode(nullptr),
112 mSetColorTransform(nullptr),
113 mSetOutputBuffer(nullptr),
114 mSetPowerMode(nullptr),
115 mSetVsyncEnabled(nullptr),
116 mValidateDisplay(nullptr),
117 mSetCursorPosition(nullptr),
118 mSetLayerBuffer(nullptr),
119 mSetLayerSurfaceDamage(nullptr),
120 mSetLayerBlendMode(nullptr),
121 mSetLayerColor(nullptr),
122 mSetLayerCompositionType(nullptr),
123 mSetLayerDataspace(nullptr),
124 mSetLayerDisplayFrame(nullptr),
125 mSetLayerPlaneAlpha(nullptr),
126 mSetLayerSidebandStream(nullptr),
127 mSetLayerSourceCrop(nullptr),
128 mSetLayerTransform(nullptr),
129 mSetLayerVisibleRegion(nullptr),
130 mSetLayerZOrder(nullptr),
131 mCapabilities(),
132 mDisplays(),
133 mHotplug(),
134 mPendingHotplugs(),
135 mRefresh(),
136 mPendingRefreshes(),
137 mVsync(),
138 mPendingVsyncs()
139 {
140 loadCapabilities();
141 loadFunctionPointers();
142 registerCallbacks();
143 }
144
~Device()145 Device::~Device()
146 {
147 if (mHwcDevice == nullptr) {
148 return;
149 }
150
151 for (auto element : mDisplays) {
152 auto display = element.second.lock();
153 if (!display) {
154 ALOGE("~Device: Found a display (%" PRId64 " that has already been"
155 " destroyed", element.first);
156 continue;
157 }
158
159 DisplayType displayType = HWC2::DisplayType::Invalid;
160 auto error = display->getType(&displayType);
161 if (error != Error::None) {
162 ALOGE("~Device: Failed to determine type of display %" PRIu64
163 ": %s (%d)", display->getId(), to_string(error).c_str(),
164 static_cast<int32_t>(error));
165 continue;
166 }
167
168 if (displayType == HWC2::DisplayType::Physical) {
169 error = display->setVsyncEnabled(HWC2::Vsync::Disable);
170 if (error != Error::None) {
171 ALOGE("~Device: Failed to disable vsync for display %" PRIu64
172 ": %s (%d)", display->getId(), to_string(error).c_str(),
173 static_cast<int32_t>(error));
174 }
175 }
176 }
177
178 hwc2_close(mHwcDevice);
179 }
180
181 // Required by HWC2 device
182
dump() const183 std::string Device::dump() const
184 {
185 uint32_t numBytes = 0;
186 mDump(mHwcDevice, &numBytes, nullptr);
187
188 std::vector<char> buffer(numBytes);
189 mDump(mHwcDevice, &numBytes, buffer.data());
190
191 return std::string(buffer.data(), buffer.size());
192 }
193
getMaxVirtualDisplayCount() const194 uint32_t Device::getMaxVirtualDisplayCount() const
195 {
196 return mGetMaxVirtualDisplayCount(mHwcDevice);
197 }
198
createVirtualDisplay(uint32_t width,uint32_t height,android_pixel_format_t * format,std::shared_ptr<Display> * outDisplay)199 Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
200 android_pixel_format_t* format, std::shared_ptr<Display>* outDisplay)
201 {
202 ALOGI("Creating virtual display");
203
204 hwc2_display_t displayId = 0;
205 int32_t intFormat = static_cast<int32_t>(*format);
206 int32_t intError = mCreateVirtualDisplay(mHwcDevice, width, height,
207 &intFormat, &displayId);
208 auto error = static_cast<Error>(intError);
209 if (error != Error::None) {
210 return error;
211 }
212
213 ALOGI("Created virtual display");
214 *format = static_cast<android_pixel_format_t>(intFormat);
215 *outDisplay = getDisplayById(displayId);
216 if (!*outDisplay) {
217 ALOGE("Failed to get display by id");
218 return Error::BadDisplay;
219 }
220 (*outDisplay)->setVirtual();
221 return Error::None;
222 }
223
registerHotplugCallback(HotplugCallback hotplug)224 void Device::registerHotplugCallback(HotplugCallback hotplug)
225 {
226 ALOGV("registerHotplugCallback");
227 mHotplug = hotplug;
228 for (auto& pending : mPendingHotplugs) {
229 auto& display = pending.first;
230 auto connected = pending.second;
231 ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(),
232 to_string(connected).c_str());
233 mHotplug(std::move(display), connected);
234 }
235 }
236
registerRefreshCallback(RefreshCallback refresh)237 void Device::registerRefreshCallback(RefreshCallback refresh)
238 {
239 mRefresh = refresh;
240 for (auto& pending : mPendingRefreshes) {
241 mRefresh(std::move(pending));
242 }
243 }
244
registerVsyncCallback(VsyncCallback vsync)245 void Device::registerVsyncCallback(VsyncCallback vsync)
246 {
247 mVsync = vsync;
248 for (auto& pending : mPendingVsyncs) {
249 auto& display = pending.first;
250 auto timestamp = pending.second;
251 mVsync(std::move(display), timestamp);
252 }
253 }
254
255 // For use by Device callbacks
256
callHotplug(std::shared_ptr<Display> display,Connection connected)257 void Device::callHotplug(std::shared_ptr<Display> display, Connection connected)
258 {
259 if (connected == Connection::Connected) {
260 if (!display->isConnected()) {
261 display->loadConfigs();
262 display->setConnected(true);
263 }
264 } else {
265 display->setConnected(false);
266 mDisplays.erase(display->getId());
267 }
268
269 if (mHotplug) {
270 mHotplug(std::move(display), connected);
271 } else {
272 ALOGV("callHotplug called, but no valid callback registered, storing");
273 mPendingHotplugs.emplace_back(std::move(display), connected);
274 }
275 }
276
callRefresh(std::shared_ptr<Display> display)277 void Device::callRefresh(std::shared_ptr<Display> display)
278 {
279 if (mRefresh) {
280 mRefresh(std::move(display));
281 } else {
282 ALOGV("callRefresh called, but no valid callback registered, storing");
283 mPendingRefreshes.emplace_back(std::move(display));
284 }
285 }
286
callVsync(std::shared_ptr<Display> display,nsecs_t timestamp)287 void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp)
288 {
289 if (mVsync) {
290 mVsync(std::move(display), timestamp);
291 } else {
292 ALOGV("callVsync called, but no valid callback registered, storing");
293 mPendingVsyncs.emplace_back(std::move(display), timestamp);
294 }
295 }
296
297 // Other Device methods
298
getDisplayById(hwc2_display_t id)299 std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) {
300 if (mDisplays.count(id) != 0) {
301 auto strongDisplay = mDisplays[id].lock();
302 ALOGE_IF(!strongDisplay, "Display %" PRId64 " is in mDisplays but is no"
303 " longer alive", id);
304 return strongDisplay;
305 }
306
307 auto display = std::make_shared<Display>(*this, id);
308 mDisplays.emplace(id, display);
309 return display;
310 }
311
312 // Device initialization methods
313
loadCapabilities()314 void Device::loadCapabilities()
315 {
316 static_assert(sizeof(Capability) == sizeof(int32_t),
317 "Capability size has changed");
318 uint32_t numCapabilities = 0;
319 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, nullptr);
320 std::vector<Capability> capabilities(numCapabilities);
321 auto asInt = reinterpret_cast<int32_t*>(capabilities.data());
322 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, asInt);
323 for (auto capability : capabilities) {
324 mCapabilities.emplace(capability);
325 }
326 }
327
hasCapability(HWC2::Capability capability) const328 bool Device::hasCapability(HWC2::Capability capability) const
329 {
330 return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
331 capability) != mCapabilities.cend();
332 }
333
loadFunctionPointers()334 void Device::loadFunctionPointers()
335 {
336 // For all of these early returns, we log an error message inside
337 // loadFunctionPointer specifying which function failed to load
338
339 // Display function pointers
340 if (!loadFunctionPointer(FunctionDescriptor::CreateVirtualDisplay,
341 mCreateVirtualDisplay)) return;
342 if (!loadFunctionPointer(FunctionDescriptor::DestroyVirtualDisplay,
343 mDestroyVirtualDisplay)) return;
344 if (!loadFunctionPointer(FunctionDescriptor::Dump, mDump)) return;
345 if (!loadFunctionPointer(FunctionDescriptor::GetMaxVirtualDisplayCount,
346 mGetMaxVirtualDisplayCount)) return;
347 if (!loadFunctionPointer(FunctionDescriptor::RegisterCallback,
348 mRegisterCallback)) return;
349
350 // Device function pointers
351 if (!loadFunctionPointer(FunctionDescriptor::AcceptDisplayChanges,
352 mAcceptDisplayChanges)) return;
353 if (!loadFunctionPointer(FunctionDescriptor::CreateLayer,
354 mCreateLayer)) return;
355 if (!loadFunctionPointer(FunctionDescriptor::DestroyLayer,
356 mDestroyLayer)) return;
357 if (!loadFunctionPointer(FunctionDescriptor::GetActiveConfig,
358 mGetActiveConfig)) return;
359 if (!loadFunctionPointer(FunctionDescriptor::GetChangedCompositionTypes,
360 mGetChangedCompositionTypes)) return;
361 if (!loadFunctionPointer(FunctionDescriptor::GetColorModes,
362 mGetColorModes)) return;
363 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayAttribute,
364 mGetDisplayAttribute)) return;
365 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayConfigs,
366 mGetDisplayConfigs)) return;
367 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayName,
368 mGetDisplayName)) return;
369 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayRequests,
370 mGetDisplayRequests)) return;
371 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayType,
372 mGetDisplayType)) return;
373 if (!loadFunctionPointer(FunctionDescriptor::GetDozeSupport,
374 mGetDozeSupport)) return;
375 if (!loadFunctionPointer(FunctionDescriptor::GetHdrCapabilities,
376 mGetHdrCapabilities)) return;
377 if (!loadFunctionPointer(FunctionDescriptor::GetReleaseFences,
378 mGetReleaseFences)) return;
379 if (!loadFunctionPointer(FunctionDescriptor::PresentDisplay,
380 mPresentDisplay)) return;
381 if (!loadFunctionPointer(FunctionDescriptor::SetActiveConfig,
382 mSetActiveConfig)) return;
383 if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget,
384 mSetClientTarget)) return;
385 if (!loadFunctionPointer(FunctionDescriptor::SetColorMode,
386 mSetColorMode)) return;
387 if (!loadFunctionPointer(FunctionDescriptor::SetColorTransform,
388 mSetColorTransform)) return;
389 if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer,
390 mSetOutputBuffer)) return;
391 if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode,
392 mSetPowerMode)) return;
393 if (!loadFunctionPointer(FunctionDescriptor::SetVsyncEnabled,
394 mSetVsyncEnabled)) return;
395 if (!loadFunctionPointer(FunctionDescriptor::ValidateDisplay,
396 mValidateDisplay)) return;
397
398 // Layer function pointers
399 if (!loadFunctionPointer(FunctionDescriptor::SetCursorPosition,
400 mSetCursorPosition)) return;
401 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBuffer,
402 mSetLayerBuffer)) return;
403 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSurfaceDamage,
404 mSetLayerSurfaceDamage)) return;
405 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBlendMode,
406 mSetLayerBlendMode)) return;
407 if (!loadFunctionPointer(FunctionDescriptor::SetLayerColor,
408 mSetLayerColor)) return;
409 if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType,
410 mSetLayerCompositionType)) return;
411 if (!loadFunctionPointer(FunctionDescriptor::SetLayerDataspace,
412 mSetLayerDataspace)) return;
413 if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame,
414 mSetLayerDisplayFrame)) return;
415 if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha,
416 mSetLayerPlaneAlpha)) return;
417 if (hasCapability(Capability::SidebandStream)) {
418 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
419 mSetLayerSidebandStream)) return;
420 }
421 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop,
422 mSetLayerSourceCrop)) return;
423 if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform,
424 mSetLayerTransform)) return;
425 if (!loadFunctionPointer(FunctionDescriptor::SetLayerVisibleRegion,
426 mSetLayerVisibleRegion)) return;
427 if (!loadFunctionPointer(FunctionDescriptor::SetLayerZOrder,
428 mSetLayerZOrder)) return;
429 }
430
registerCallbacks()431 void Device::registerCallbacks()
432 {
433 registerCallback<HWC2_PFN_HOTPLUG>(Callback::Hotplug, hotplug_hook);
434 registerCallback<HWC2_PFN_REFRESH>(Callback::Refresh, refresh_hook);
435 registerCallback<HWC2_PFN_VSYNC>(Callback::Vsync, vsync_hook);
436 }
437
438
439 // For use by Display
440
destroyVirtualDisplay(hwc2_display_t display)441 void Device::destroyVirtualDisplay(hwc2_display_t display)
442 {
443 ALOGI("Destroying virtual display");
444 int32_t intError = mDestroyVirtualDisplay(mHwcDevice, display);
445 auto error = static_cast<Error>(intError);
446 ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
447 " %s (%d)", display, to_string(error).c_str(), intError);
448 mDisplays.erase(display);
449 }
450
451 // Display methods
452
Display(Device & device,hwc2_display_t id)453 Display::Display(Device& device, hwc2_display_t id)
454 : mDevice(device),
455 mId(id),
456 mIsConnected(false),
457 mIsVirtual(false)
458 {
459 ALOGV("Created display %" PRIu64, id);
460 }
461
~Display()462 Display::~Display()
463 {
464 ALOGV("Destroyed display %" PRIu64, mId);
465 if (mIsVirtual) {
466 mDevice.destroyVirtualDisplay(mId);
467 }
468 }
469
Config(Display & display,hwc2_config_t id)470 Display::Config::Config(Display& display, hwc2_config_t id)
471 : mDisplay(display),
472 mId(id),
473 mWidth(-1),
474 mHeight(-1),
475 mVsyncPeriod(-1),
476 mDpiX(-1),
477 mDpiY(-1) {}
478
Builder(Display & display,hwc2_config_t id)479 Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
480 : mConfig(new Config(display, id)) {}
481
getDefaultDensity()482 float Display::Config::Builder::getDefaultDensity() {
483 // Default density is based on TVs: 1080p displays get XHIGH density, lower-
484 // resolution displays get TV density. Maybe eventually we'll need to update
485 // it for 4k displays, though hopefully those will just report accurate DPI
486 // information to begin with. This is also used for virtual displays and
487 // older HWC implementations, so be careful about orientation.
488
489 auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
490 if (longDimension >= 1080) {
491 return ACONFIGURATION_DENSITY_XHIGH;
492 } else {
493 return ACONFIGURATION_DENSITY_TV;
494 }
495 }
496
497 // Required by HWC2 display
498
acceptChanges()499 Error Display::acceptChanges()
500 {
501 int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId);
502 return static_cast<Error>(intError);
503 }
504
createLayer(std::shared_ptr<Layer> * outLayer)505 Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
506 {
507 hwc2_layer_t layerId = 0;
508 int32_t intError = mDevice.mCreateLayer(mDevice.mHwcDevice, mId, &layerId);
509 auto error = static_cast<Error>(intError);
510 if (error != Error::None) {
511 return error;
512 }
513
514 auto layer = std::make_shared<Layer>(shared_from_this(), layerId);
515 mLayers.emplace(layerId, layer);
516 *outLayer = std::move(layer);
517 return Error::None;
518 }
519
getActiveConfig(std::shared_ptr<const Display::Config> * outConfig) const520 Error Display::getActiveConfig(
521 std::shared_ptr<const Display::Config>* outConfig) const
522 {
523 ALOGV("[%" PRIu64 "] getActiveConfig", mId);
524 hwc2_config_t configId = 0;
525 int32_t intError = mDevice.mGetActiveConfig(mDevice.mHwcDevice, mId,
526 &configId);
527 auto error = static_cast<Error>(intError);
528
529 if (error != Error::None) {
530 return error;
531 }
532
533 if (mConfigs.count(configId) != 0) {
534 *outConfig = mConfigs.at(configId);
535 } else {
536 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
537 configId);
538 // Return no error, but the caller needs to check for a null pointer to
539 // detect this case
540 *outConfig = nullptr;
541 }
542
543 return Error::None;
544 }
545
getChangedCompositionTypes(std::unordered_map<std::shared_ptr<Layer>,Composition> * outTypes)546 Error Display::getChangedCompositionTypes(
547 std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
548 {
549 uint32_t numElements = 0;
550 int32_t intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice,
551 mId, &numElements, nullptr, nullptr);
552 auto error = static_cast<Error>(intError);
553 if (error != Error::None) {
554 return error;
555 }
556
557 std::vector<hwc2_layer_t> layerIds(numElements);
558 std::vector<int32_t> types(numElements);
559 intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, mId,
560 &numElements, layerIds.data(), types.data());
561 error = static_cast<Error>(intError);
562 if (error != Error::None) {
563 return error;
564 }
565
566 outTypes->clear();
567 outTypes->reserve(numElements);
568 for (uint32_t element = 0; element < numElements; ++element) {
569 auto layer = getLayerById(layerIds[element]);
570 if (layer) {
571 auto type = static_cast<Composition>(types[element]);
572 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
573 layer->getId(), to_string(type).c_str());
574 outTypes->emplace(layer, type);
575 } else {
576 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
577 " on display %" PRIu64, layerIds[element], mId);
578 }
579 }
580
581 return Error::None;
582 }
583
getColorModes(std::vector<android_color_mode_t> * outModes) const584 Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
585 {
586 uint32_t numModes = 0;
587 int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId,
588 &numModes, nullptr);
589 auto error = static_cast<Error>(intError);
590 if (error != Error::None) {
591 return error;
592 }
593
594 std::vector<int32_t> modes(numModes);
595 intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, &numModes,
596 modes.data());
597 error = static_cast<Error>(intError);
598 if (error != Error::None) {
599 return error;
600 }
601
602 outModes->resize(numModes);
603 for (size_t i = 0; i < numModes; i++) {
604 (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]);
605 }
606 return Error::None;
607 }
608
getConfigs() const609 std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
610 {
611 std::vector<std::shared_ptr<const Config>> configs;
612 for (const auto& element : mConfigs) {
613 configs.emplace_back(element.second);
614 }
615 return configs;
616 }
617
getName(std::string * outName) const618 Error Display::getName(std::string* outName) const
619 {
620 uint32_t size;
621 int32_t intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
622 nullptr);
623 auto error = static_cast<Error>(intError);
624 if (error != Error::None) {
625 return error;
626 }
627
628 std::vector<char> rawName(size);
629 intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
630 rawName.data());
631 error = static_cast<Error>(intError);
632 if (error != Error::None) {
633 return error;
634 }
635
636 *outName = std::string(rawName.cbegin(), rawName.cend());
637 return Error::None;
638 }
639
getRequests(HWC2::DisplayRequest * outDisplayRequests,std::unordered_map<std::shared_ptr<Layer>,LayerRequest> * outLayerRequests)640 Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
641 std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
642 outLayerRequests)
643 {
644 int32_t intDisplayRequests = 0;
645 uint32_t numElements = 0;
646 int32_t intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
647 &intDisplayRequests, &numElements, nullptr, nullptr);
648 auto error = static_cast<Error>(intError);
649 if (error != Error::None) {
650 return error;
651 }
652
653 std::vector<hwc2_layer_t> layerIds(numElements);
654 std::vector<int32_t> layerRequests(numElements);
655 intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
656 &intDisplayRequests, &numElements, layerIds.data(),
657 layerRequests.data());
658 error = static_cast<Error>(intError);
659 if (error != Error::None) {
660 return error;
661 }
662
663 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
664 outLayerRequests->clear();
665 outLayerRequests->reserve(numElements);
666 for (uint32_t element = 0; element < numElements; ++element) {
667 auto layer = getLayerById(layerIds[element]);
668 if (layer) {
669 auto layerRequest =
670 static_cast<LayerRequest>(layerRequests[element]);
671 outLayerRequests->emplace(layer, layerRequest);
672 } else {
673 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
674 PRIu64, layerIds[element], mId);
675 }
676 }
677
678 return Error::None;
679 }
680
getType(DisplayType * outType) const681 Error Display::getType(DisplayType* outType) const
682 {
683 int32_t intType = 0;
684 int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId,
685 &intType);
686 auto error = static_cast<Error>(intError);
687 if (error != Error::None) {
688 return error;
689 }
690
691 *outType = static_cast<DisplayType>(intType);
692 return Error::None;
693 }
694
supportsDoze(bool * outSupport) const695 Error Display::supportsDoze(bool* outSupport) const
696 {
697 int32_t intSupport = 0;
698 int32_t intError = mDevice.mGetDozeSupport(mDevice.mHwcDevice, mId,
699 &intSupport);
700 auto error = static_cast<Error>(intError);
701 if (error != Error::None) {
702 return error;
703 }
704 *outSupport = static_cast<bool>(intSupport);
705 return Error::None;
706 }
707
getHdrCapabilities(std::unique_ptr<HdrCapabilities> * outCapabilities) const708 Error Display::getHdrCapabilities(
709 std::unique_ptr<HdrCapabilities>* outCapabilities) const
710 {
711 uint32_t numTypes = 0;
712 float maxLuminance = -1.0f;
713 float maxAverageLuminance = -1.0f;
714 float minLuminance = -1.0f;
715 int32_t intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId,
716 &numTypes, nullptr, &maxLuminance, &maxAverageLuminance,
717 &minLuminance);
718 auto error = static_cast<HWC2::Error>(intError);
719 if (error != Error::None) {
720 return error;
721 }
722
723 std::vector<int32_t> types(numTypes);
724 intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, &numTypes,
725 types.data(), &maxLuminance, &maxAverageLuminance, &minLuminance);
726 error = static_cast<HWC2::Error>(intError);
727 if (error != Error::None) {
728 return error;
729 }
730
731 *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types),
732 maxLuminance, maxAverageLuminance, minLuminance);
733 return Error::None;
734 }
735
getReleaseFences(std::unordered_map<std::shared_ptr<Layer>,sp<Fence>> * outFences) const736 Error Display::getReleaseFences(
737 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
738 {
739 uint32_t numElements = 0;
740 int32_t intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId,
741 &numElements, nullptr, nullptr);
742 auto error = static_cast<Error>(intError);
743 if (error != Error::None) {
744 return error;
745 }
746
747 std::vector<hwc2_layer_t> layerIds(numElements);
748 std::vector<int32_t> fenceFds(numElements);
749 intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, &numElements,
750 layerIds.data(), fenceFds.data());
751 error = static_cast<Error>(intError);
752 if (error != Error::None) {
753 return error;
754 }
755
756 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences;
757 releaseFences.reserve(numElements);
758 for (uint32_t element = 0; element < numElements; ++element) {
759 auto layer = getLayerById(layerIds[element]);
760 if (layer) {
761 sp<Fence> fence(new Fence(fenceFds[element]));
762 releaseFences.emplace(std::move(layer), fence);
763 } else {
764 ALOGE("getReleaseFences: invalid layer %" PRIu64
765 " found on display %" PRIu64, layerIds[element], mId);
766 return Error::BadLayer;
767 }
768 }
769
770 *outFences = std::move(releaseFences);
771 return Error::None;
772 }
773
present(sp<Fence> * outRetireFence)774 Error Display::present(sp<Fence>* outRetireFence)
775 {
776 int32_t retireFenceFd = 0;
777 int32_t intError = mDevice.mPresentDisplay(mDevice.mHwcDevice, mId,
778 &retireFenceFd);
779 auto error = static_cast<Error>(intError);
780 if (error != Error::None) {
781 return error;
782 }
783
784 *outRetireFence = new Fence(retireFenceFd);
785 return Error::None;
786 }
787
setActiveConfig(const std::shared_ptr<const Config> & config)788 Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
789 {
790 if (config->getDisplayId() != mId) {
791 ALOGE("setActiveConfig received config %u for the wrong display %"
792 PRIu64 " (expected %" PRIu64 ")", config->getId(),
793 config->getDisplayId(), mId);
794 return Error::BadConfig;
795 }
796 int32_t intError = mDevice.mSetActiveConfig(mDevice.mHwcDevice, mId,
797 config->getId());
798 return static_cast<Error>(intError);
799 }
800
setClientTarget(buffer_handle_t target,const sp<Fence> & acquireFence,android_dataspace_t dataspace)801 Error Display::setClientTarget(buffer_handle_t target,
802 const sp<Fence>& acquireFence, android_dataspace_t dataspace)
803 {
804 // TODO: Properly encode client target surface damage
805 int32_t fenceFd = acquireFence->dup();
806 int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
807 fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
808 return static_cast<Error>(intError);
809 }
810
setColorMode(android_color_mode_t mode)811 Error Display::setColorMode(android_color_mode_t mode)
812 {
813 int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode);
814 return static_cast<Error>(intError);
815 }
816
setColorTransform(const android::mat4 & matrix,android_color_transform_t hint)817 Error Display::setColorTransform(const android::mat4& matrix,
818 android_color_transform_t hint)
819 {
820 int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId,
821 matrix.asArray(), static_cast<int32_t>(hint));
822 return static_cast<Error>(intError);
823 }
824
setOutputBuffer(const sp<GraphicBuffer> & buffer,const sp<Fence> & releaseFence)825 Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
826 const sp<Fence>& releaseFence)
827 {
828 int32_t fenceFd = releaseFence->dup();
829 auto handle = buffer->getNativeBuffer()->handle;
830 int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle,
831 fenceFd);
832 close(fenceFd);
833 return static_cast<Error>(intError);
834 }
835
setPowerMode(PowerMode mode)836 Error Display::setPowerMode(PowerMode mode)
837 {
838 auto intMode = static_cast<int32_t>(mode);
839 int32_t intError = mDevice.mSetPowerMode(mDevice.mHwcDevice, mId, intMode);
840 return static_cast<Error>(intError);
841 }
842
setVsyncEnabled(Vsync enabled)843 Error Display::setVsyncEnabled(Vsync enabled)
844 {
845 auto intEnabled = static_cast<int32_t>(enabled);
846 int32_t intError = mDevice.mSetVsyncEnabled(mDevice.mHwcDevice, mId,
847 intEnabled);
848 return static_cast<Error>(intError);
849 }
850
validate(uint32_t * outNumTypes,uint32_t * outNumRequests)851 Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
852 {
853 uint32_t numTypes = 0;
854 uint32_t numRequests = 0;
855 int32_t intError = mDevice.mValidateDisplay(mDevice.mHwcDevice, mId,
856 &numTypes, &numRequests);
857 auto error = static_cast<Error>(intError);
858 if (error != Error::None && error != Error::HasChanges) {
859 return error;
860 }
861
862 *outNumTypes = numTypes;
863 *outNumRequests = numRequests;
864 return error;
865 }
866
867 // For use by Device
868
getAttribute(hwc2_config_t configId,Attribute attribute)869 int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
870 {
871 int32_t value = 0;
872 int32_t intError = mDevice.mGetDisplayAttribute(mDevice.mHwcDevice, mId,
873 configId, static_cast<int32_t>(attribute), &value);
874 auto error = static_cast<Error>(intError);
875 if (error != Error::None) {
876 ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
877 configId, to_string(attribute).c_str(),
878 to_string(error).c_str(), intError);
879 return -1;
880 }
881 return value;
882 }
883
loadConfig(hwc2_config_t configId)884 void Display::loadConfig(hwc2_config_t configId)
885 {
886 ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
887
888 auto config = Config::Builder(*this, configId)
889 .setWidth(getAttribute(configId, Attribute::Width))
890 .setHeight(getAttribute(configId, Attribute::Height))
891 .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
892 .setDpiX(getAttribute(configId, Attribute::DpiX))
893 .setDpiY(getAttribute(configId, Attribute::DpiY))
894 .build();
895 mConfigs.emplace(configId, std::move(config));
896 }
897
loadConfigs()898 void Display::loadConfigs()
899 {
900 ALOGV("[%" PRIu64 "] loadConfigs", mId);
901
902 uint32_t numConfigs = 0;
903 int32_t intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId,
904 &numConfigs, nullptr);
905 auto error = static_cast<Error>(intError);
906 if (error != Error::None) {
907 ALOGE("[%" PRIu64 "] getDisplayConfigs [1] failed: %s (%d)", mId,
908 to_string(error).c_str(), intError);
909 return;
910 }
911
912 std::vector<hwc2_config_t> configIds(numConfigs);
913 intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, &numConfigs,
914 configIds.data());
915 error = static_cast<Error>(intError);
916 if (error != Error::None) {
917 ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
918 to_string(error).c_str(), intError);
919 return;
920 }
921
922 for (auto configId : configIds) {
923 loadConfig(configId);
924 }
925 }
926
927 // For use by Layer
928
destroyLayer(hwc2_layer_t layerId)929 void Display::destroyLayer(hwc2_layer_t layerId)
930 {
931 int32_t intError = mDevice.mDestroyLayer(mDevice.mHwcDevice, mId, layerId);
932 auto error = static_cast<Error>(intError);
933 ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
934 " failed: %s (%d)", mId, layerId, to_string(error).c_str(),
935 intError);
936 mLayers.erase(layerId);
937 }
938
939 // Other Display methods
940
getLayerById(hwc2_layer_t id) const941 std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const
942 {
943 if (mLayers.count(id) == 0) {
944 return nullptr;
945 }
946
947 auto layer = mLayers.at(id).lock();
948 return layer;
949 }
950
951 // Layer methods
952
Layer(const std::shared_ptr<Display> & display,hwc2_layer_t id)953 Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id)
954 : mDisplay(display),
955 mDisplayId(display->getId()),
956 mDevice(display->getDevice()),
957 mId(id)
958 {
959 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id,
960 display->getId());
961 }
962
~Layer()963 Layer::~Layer()
964 {
965 auto display = mDisplay.lock();
966 if (display) {
967 display->destroyLayer(mId);
968 }
969 }
970
setCursorPosition(int32_t x,int32_t y)971 Error Layer::setCursorPosition(int32_t x, int32_t y)
972 {
973 int32_t intError = mDevice.mSetCursorPosition(mDevice.mHwcDevice,
974 mDisplayId, mId, x, y);
975 return static_cast<Error>(intError);
976 }
977
setBuffer(buffer_handle_t buffer,const sp<Fence> & acquireFence)978 Error Layer::setBuffer(buffer_handle_t buffer,
979 const sp<Fence>& acquireFence)
980 {
981 int32_t fenceFd = acquireFence->dup();
982 int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
983 mId, buffer, fenceFd);
984 return static_cast<Error>(intError);
985 }
986
setSurfaceDamage(const Region & damage)987 Error Layer::setSurfaceDamage(const Region& damage)
988 {
989 // We encode default full-screen damage as INVALID_RECT upstream, but as 0
990 // rects for HWC
991 int32_t intError = 0;
992 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
993 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
994 mDisplayId, mId, {0, nullptr});
995 } else {
996 size_t rectCount = 0;
997 auto rectArray = damage.getArray(&rectCount);
998
999 std::vector<hwc_rect_t> hwcRects;
1000 for (size_t rect = 0; rect < rectCount; ++rect) {
1001 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1002 rectArray[rect].right, rectArray[rect].bottom});
1003 }
1004
1005 hwc_region_t hwcRegion = {};
1006 hwcRegion.numRects = rectCount;
1007 hwcRegion.rects = hwcRects.data();
1008
1009 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
1010 mDisplayId, mId, hwcRegion);
1011 }
1012
1013 return static_cast<Error>(intError);
1014 }
1015
setBlendMode(BlendMode mode)1016 Error Layer::setBlendMode(BlendMode mode)
1017 {
1018 auto intMode = static_cast<int32_t>(mode);
1019 int32_t intError = mDevice.mSetLayerBlendMode(mDevice.mHwcDevice,
1020 mDisplayId, mId, intMode);
1021 return static_cast<Error>(intError);
1022 }
1023
setColor(hwc_color_t color)1024 Error Layer::setColor(hwc_color_t color)
1025 {
1026 int32_t intError = mDevice.mSetLayerColor(mDevice.mHwcDevice, mDisplayId,
1027 mId, color);
1028 return static_cast<Error>(intError);
1029 }
1030
setCompositionType(Composition type)1031 Error Layer::setCompositionType(Composition type)
1032 {
1033 auto intType = static_cast<int32_t>(type);
1034 int32_t intError = mDevice.mSetLayerCompositionType(mDevice.mHwcDevice,
1035 mDisplayId, mId, intType);
1036 return static_cast<Error>(intError);
1037 }
1038
setDataspace(android_dataspace_t dataspace)1039 Error Layer::setDataspace(android_dataspace_t dataspace)
1040 {
1041 auto intDataspace = static_cast<int32_t>(dataspace);
1042 int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice,
1043 mDisplayId, mId, intDataspace);
1044 return static_cast<Error>(intError);
1045 }
1046
setDisplayFrame(const Rect & frame)1047 Error Layer::setDisplayFrame(const Rect& frame)
1048 {
1049 hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom};
1050 int32_t intError = mDevice.mSetLayerDisplayFrame(mDevice.mHwcDevice,
1051 mDisplayId, mId, hwcRect);
1052 return static_cast<Error>(intError);
1053 }
1054
setPlaneAlpha(float alpha)1055 Error Layer::setPlaneAlpha(float alpha)
1056 {
1057 int32_t intError = mDevice.mSetLayerPlaneAlpha(mDevice.mHwcDevice,
1058 mDisplayId, mId, alpha);
1059 return static_cast<Error>(intError);
1060 }
1061
setSidebandStream(const native_handle_t * stream)1062 Error Layer::setSidebandStream(const native_handle_t* stream)
1063 {
1064 if (!mDevice.hasCapability(Capability::SidebandStream)) {
1065 ALOGE("Attempted to call setSidebandStream without checking that the "
1066 "device supports sideband streams");
1067 return Error::Unsupported;
1068 }
1069 int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
1070 mDisplayId, mId, stream);
1071 return static_cast<Error>(intError);
1072 }
1073
setSourceCrop(const FloatRect & crop)1074 Error Layer::setSourceCrop(const FloatRect& crop)
1075 {
1076 hwc_frect_t hwcRect{crop.left, crop.top, crop.right, crop.bottom};
1077 int32_t intError = mDevice.mSetLayerSourceCrop(mDevice.mHwcDevice,
1078 mDisplayId, mId, hwcRect);
1079 return static_cast<Error>(intError);
1080 }
1081
setTransform(Transform transform)1082 Error Layer::setTransform(Transform transform)
1083 {
1084 auto intTransform = static_cast<int32_t>(transform);
1085 int32_t intError = mDevice.mSetLayerTransform(mDevice.mHwcDevice,
1086 mDisplayId, mId, intTransform);
1087 return static_cast<Error>(intError);
1088 }
1089
setVisibleRegion(const Region & region)1090 Error Layer::setVisibleRegion(const Region& region)
1091 {
1092 size_t rectCount = 0;
1093 auto rectArray = region.getArray(&rectCount);
1094
1095 std::vector<hwc_rect_t> hwcRects;
1096 for (size_t rect = 0; rect < rectCount; ++rect) {
1097 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1098 rectArray[rect].right, rectArray[rect].bottom});
1099 }
1100
1101 hwc_region_t hwcRegion = {};
1102 hwcRegion.numRects = rectCount;
1103 hwcRegion.rects = hwcRects.data();
1104
1105 int32_t intError = mDevice.mSetLayerVisibleRegion(mDevice.mHwcDevice,
1106 mDisplayId, mId, hwcRegion);
1107 return static_cast<Error>(intError);
1108 }
1109
setZOrder(uint32_t z)1110 Error Layer::setZOrder(uint32_t z)
1111 {
1112 int32_t intError = mDevice.mSetLayerZOrder(mDevice.mHwcDevice, mDisplayId,
1113 mId, z);
1114 return static_cast<Error>(intError);
1115 }
1116
1117 } // namespace HWC2
1118