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