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