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