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