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