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