HWComposer.cpp revision 56a9e5d33ce9a60f042288ef8b62952d44ffec4c
1/*
2 * Copyright (C) 2010 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 "HWComposer"
21#define ATRACE_TAG ATRACE_TAG_GRAPHICS
22
23#include <inttypes.h>
24#include <math.h>
25#include <stdint.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/types.h>
30
31#include <utils/Errors.h>
32#include <utils/misc.h>
33#include <utils/NativeHandle.h>
34#include <utils/String8.h>
35#include <utils/Thread.h>
36#include <utils/Trace.h>
37#include <utils/Vector.h>
38
39#include <ui/DebugUtils.h>
40#include <ui/GraphicBuffer.h>
41
42#include <hardware/hardware.h>
43#include <hardware/hwcomposer.h>
44
45#include <android/configuration.h>
46
47#include <cutils/properties.h>
48#include <log/log.h>
49
50#include "HWComposer.h"
51#include "HWC2.h"
52#include "ComposerHal.h"
53
54#include "../Layer.h"           // needed only for debugging
55#include "../SurfaceFlinger.h"
56
57#define LOG_DISPLAY_ERROR(displayId, msg) \
58    ALOGE("%s failed for display %d: %s", __FUNCTION__, displayId, msg)
59
60#define LOG_HWC_ERROR(what, error, displayId)                                     \
61    ALOGE("%s: %s failed for display %d: %s (%d)", __FUNCTION__, what, displayId, \
62          to_string(error).c_str(), static_cast<int32_t>(error))
63
64#define RETURN_IF_INVALID_DISPLAY(displayId, ...)            \
65    do {                                                     \
66        if (!isValidDisplay(displayId)) {                    \
67            LOG_DISPLAY_ERROR(displayId, "Invalid display"); \
68            return __VA_ARGS__;                              \
69        }                                                    \
70    } while (false)
71
72#define RETURN_IF_HWC_ERROR_FOR(what, error, displayId, ...) \
73    do {                                                     \
74        if (error != HWC2::Error::None) {                    \
75            LOG_HWC_ERROR(what, error, displayId);           \
76            return __VA_ARGS__;                              \
77        }                                                    \
78    } while (false)
79
80#define RETURN_IF_HWC_ERROR(error, displayId, ...) \
81    RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__)
82
83namespace android {
84
85#define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION
86
87// ---------------------------------------------------------------------------
88
89HWComposer::HWComposer(std::unique_ptr<android::Hwc2::Composer> composer)
90      : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}
91
92HWComposer::~HWComposer() = default;
93
94void HWComposer::registerCallback(HWC2::ComposerCallback* callback,
95                                  int32_t sequenceId) {
96    mHwcDevice->registerCallback(callback, sequenceId);
97}
98
99bool HWComposer::hasCapability(HWC2::Capability capability) const
100{
101    return mHwcDevice->getCapabilities().count(capability) > 0;
102}
103
104bool HWComposer::isValidDisplay(int32_t displayId) const {
105    return static_cast<size_t>(displayId) < mDisplayData.size() &&
106            mDisplayData[displayId].hwcDisplay;
107}
108
109void HWComposer::validateChange(HWC2::Composition from, HWC2::Composition to) {
110    bool valid = true;
111    switch (from) {
112        case HWC2::Composition::Client:
113            valid = false;
114            break;
115        case HWC2::Composition::Device:
116        case HWC2::Composition::SolidColor:
117            valid = (to == HWC2::Composition::Client);
118            break;
119        case HWC2::Composition::Cursor:
120        case HWC2::Composition::Sideband:
121            valid = (to == HWC2::Composition::Client ||
122                    to == HWC2::Composition::Device);
123            break;
124        default:
125            break;
126    }
127
128    if (!valid) {
129        ALOGE("Invalid layer type change: %s --> %s", to_string(from).c_str(),
130                to_string(to).c_str());
131    }
132}
133
134void HWComposer::onHotplug(hwc2_display_t displayId, int32_t displayType,
135                           HWC2::Connection connection) {
136    if (displayType >= HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
137        ALOGE("Invalid display type of %d", displayType);
138        return;
139    }
140
141    ALOGV("hotplug: %" PRIu64 ", %s %s", displayId,
142            displayType == DisplayDevice::DISPLAY_PRIMARY ? "primary" : "external",
143            to_string(connection).c_str());
144    mHwcDevice->onHotplug(displayId, connection);
145    // Disconnect is handled through HWComposer::disconnectDisplay via
146    // SurfaceFlinger's onHotplugReceived callback handling
147    if (connection == HWC2::Connection::Connected) {
148        mDisplayData[displayType].hwcDisplay = mHwcDevice->getDisplayById(displayId);
149        mHwcDisplaySlots[displayId] = displayType;
150    }
151}
152
153bool HWComposer::onVsync(hwc2_display_t displayId, int64_t timestamp,
154                         int32_t* outDisplay) {
155    auto display = mHwcDevice->getDisplayById(displayId);
156    if (!display) {
157        ALOGE("onVsync Failed to find display %" PRIu64, displayId);
158        return false;
159    }
160    auto displayType = HWC2::DisplayType::Invalid;
161    auto error = display->getType(&displayType);
162    if (error != HWC2::Error::None) {
163        ALOGE("onVsync: Failed to determine type of display %" PRIu64,
164                display->getId());
165        return false;
166    }
167
168    if (displayType == HWC2::DisplayType::Virtual) {
169        ALOGE("Virtual display %" PRIu64 " passed to vsync callback",
170                display->getId());
171        return false;
172    }
173
174    if (mHwcDisplaySlots.count(display->getId()) == 0) {
175        ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback",
176                display->getId());
177        return false;
178    }
179
180    int32_t disp = mHwcDisplaySlots[display->getId()];
181    {
182        Mutex::Autolock _l(mLock);
183
184        // There have been reports of HWCs that signal several vsync events
185        // with the same timestamp when turning the display off and on. This
186        // is a bug in the HWC implementation, but filter the extra events
187        // out here so they don't cause havoc downstream.
188        if (timestamp == mLastHwVSync[disp]) {
189            ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
190                    timestamp);
191            return false;
192        }
193
194        mLastHwVSync[disp] = timestamp;
195    }
196
197    if (outDisplay) {
198        *outDisplay = disp;
199    }
200
201    char tag[16];
202    snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
203    ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
204
205    return true;
206}
207
208status_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
209        ui::PixelFormat* format, int32_t *outId) {
210    if (mRemainingHwcVirtualDisplays == 0) {
211        ALOGE("allocateVirtualDisplay: No remaining virtual displays");
212        return NO_MEMORY;
213    }
214
215    if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
216        (width > SurfaceFlinger::maxVirtualDisplaySize ||
217         height > SurfaceFlinger::maxVirtualDisplaySize)) {
218        ALOGE("createVirtualDisplay: Can't create a virtual display with"
219                      " a dimension > %" PRIu64 " (tried %u x %u)",
220              SurfaceFlinger::maxVirtualDisplaySize, width, height);
221        return INVALID_OPERATION;
222    }
223
224    HWC2::Display* display;
225    auto error = mHwcDevice->createVirtualDisplay(width, height, format,
226            &display);
227    if (error != HWC2::Error::None) {
228        ALOGE("allocateVirtualDisplay: Failed to create HWC virtual display");
229        return NO_MEMORY;
230    }
231
232    size_t displaySlot = 0;
233    if (!mFreeDisplaySlots.empty()) {
234        displaySlot = *mFreeDisplaySlots.begin();
235        mFreeDisplaySlots.erase(displaySlot);
236    } else if (mDisplayData.size() < INT32_MAX) {
237        // Don't bother allocating a slot larger than we can return
238        displaySlot = mDisplayData.size();
239        mDisplayData.resize(displaySlot + 1);
240    } else {
241        ALOGE("allocateVirtualDisplay: Unable to allocate a display slot");
242        return NO_MEMORY;
243    }
244
245    mDisplayData[displaySlot].hwcDisplay = display;
246
247    --mRemainingHwcVirtualDisplays;
248    *outId = static_cast<int32_t>(displaySlot);
249
250    return NO_ERROR;
251}
252
253HWC2::Layer* HWComposer::createLayer(int32_t displayId) {
254    RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
255
256    auto display = mDisplayData[displayId].hwcDisplay;
257    HWC2::Layer* layer;
258    auto error = display->createLayer(&layer);
259    RETURN_IF_HWC_ERROR(error, displayId, nullptr);
260    return layer;
261}
262
263void HWComposer::destroyLayer(int32_t displayId, HWC2::Layer* layer) {
264    RETURN_IF_INVALID_DISPLAY(displayId);
265
266    auto display = mDisplayData[displayId].hwcDisplay;
267    auto error = display->destroyLayer(layer);
268    RETURN_IF_HWC_ERROR(error, displayId);
269}
270
271nsecs_t HWComposer::getRefreshTimestamp(int32_t displayId) const {
272    // this returns the last refresh timestamp.
273    // if the last one is not available, we estimate it based on
274    // the refresh period and whatever closest timestamp we have.
275    Mutex::Autolock _l(mLock);
276    nsecs_t now = systemTime(CLOCK_MONOTONIC);
277    auto vsyncPeriod = getActiveConfig(displayId)->getVsyncPeriod();
278    return now - ((now - mLastHwVSync[displayId]) % vsyncPeriod);
279}
280
281bool HWComposer::isConnected(int32_t displayId) const {
282    RETURN_IF_INVALID_DISPLAY(displayId, false);
283    return mDisplayData[displayId].hwcDisplay->isConnected();
284}
285
286std::vector<std::shared_ptr<const HWC2::Display::Config>>
287        HWComposer::getConfigs(int32_t displayId) const {
288    RETURN_IF_INVALID_DISPLAY(displayId, {});
289
290    auto& displayData = mDisplayData[displayId];
291    auto configs = mDisplayData[displayId].hwcDisplay->getConfigs();
292    if (displayData.configMap.empty()) {
293        for (size_t i = 0; i < configs.size(); ++i) {
294            displayData.configMap[i] = configs[i];
295        }
296    }
297    return configs;
298}
299
300std::shared_ptr<const HWC2::Display::Config>
301        HWComposer::getActiveConfig(int32_t displayId) const {
302    RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
303
304    std::shared_ptr<const HWC2::Display::Config> config;
305    auto error = mDisplayData[displayId].hwcDisplay->getActiveConfig(&config);
306    if (error == HWC2::Error::BadConfig) {
307        LOG_DISPLAY_ERROR(displayId, "No active config");
308        return nullptr;
309    }
310
311    RETURN_IF_HWC_ERROR(error, displayId, nullptr);
312
313    if (!config) {
314        LOG_DISPLAY_ERROR(displayId, "Unknown config");
315        return nullptr;
316    }
317
318    return config;
319}
320
321std::vector<ui::ColorMode> HWComposer::getColorModes(int32_t displayId) const {
322    RETURN_IF_INVALID_DISPLAY(displayId, {});
323
324    std::vector<ui::ColorMode> modes;
325    auto error = mDisplayData[displayId].hwcDisplay->getColorModes(&modes);
326    RETURN_IF_HWC_ERROR(error, displayId, {});
327    return modes;
328}
329
330status_t HWComposer::setActiveColorMode(int32_t displayId, ui::ColorMode mode,
331        ui::RenderIntent renderIntent) {
332    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
333
334    auto& displayData = mDisplayData[displayId];
335    auto error = displayData.hwcDisplay->setColorMode(mode, renderIntent);
336    RETURN_IF_HWC_ERROR_FOR(("setColorMode(" + decodeColorMode(mode) + ", " +
337                             decodeRenderIntent(renderIntent) + ")")
338                                    .c_str(),
339                            error, displayId, UNKNOWN_ERROR);
340
341    return NO_ERROR;
342}
343
344
345void HWComposer::setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled) {
346    if (displayId < 0 || displayId >= HWC_DISPLAY_VIRTUAL) {
347        ALOGD("setVsyncEnabled: Ignoring for virtual display %d", displayId);
348        return;
349    }
350
351    RETURN_IF_INVALID_DISPLAY(displayId);
352
353    // NOTE: we use our own internal lock here because we have to call
354    // into the HWC with the lock held, and we want to make sure
355    // that even if HWC blocks (which it shouldn't), it won't
356    // affect other threads.
357    Mutex::Autolock _l(mVsyncLock);
358    auto& displayData = mDisplayData[displayId];
359    if (enabled != displayData.vsyncEnabled) {
360        ATRACE_CALL();
361        auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
362        RETURN_IF_HWC_ERROR(error, displayId);
363
364        displayData.vsyncEnabled = enabled;
365
366        char tag[16];
367        snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", displayId);
368        ATRACE_INT(tag, enabled == HWC2::Vsync::Enable ? 1 : 0);
369    }
370}
371
372status_t HWComposer::setClientTarget(int32_t displayId, uint32_t slot,
373        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
374        ui::Dataspace dataspace) {
375    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
376
377    ALOGV("setClientTarget for display %d", displayId);
378    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
379    auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
380    RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
381    return NO_ERROR;
382}
383
384status_t HWComposer::prepare(DisplayDevice& displayDevice) {
385    ATRACE_CALL();
386
387    Mutex::Autolock _l(mDisplayLock);
388    auto displayId = displayDevice.getHwcDisplayId();
389    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
390        ALOGV("Skipping HWComposer prepare for non-HWC display");
391        return NO_ERROR;
392    }
393
394    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
395
396    auto& displayData = mDisplayData[displayId];
397    auto& hwcDisplay = displayData.hwcDisplay;
398    if (!hwcDisplay->isConnected()) {
399        return NO_ERROR;
400    }
401
402    uint32_t numTypes = 0;
403    uint32_t numRequests = 0;
404
405    HWC2::Error error = HWC2::Error::None;
406
407    // First try to skip validate altogether when there is no client
408    // composition.  When there is client composition, since we haven't
409    // rendered to the client target yet, we should not attempt to skip
410    // validate.
411    //
412    // displayData.hasClientComposition hasn't been updated for this frame.
413    // The check below is incorrect.  We actually rely on HWC here to fall
414    // back to validate when there is any client layer.
415    displayData.validateWasSkipped = false;
416    if (!displayData.hasClientComposition) {
417        sp<android::Fence> outPresentFence;
418        uint32_t state = UINT32_MAX;
419        error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
420        if (error != HWC2::Error::HasChanges) {
421            RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
422        }
423        if (state == 1) { //Present Succeeded.
424            std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
425            error = hwcDisplay->getReleaseFences(&releaseFences);
426            displayData.releaseFences = std::move(releaseFences);
427            displayData.lastPresentFence = outPresentFence;
428            displayData.validateWasSkipped = true;
429            displayData.presentError = error;
430            return NO_ERROR;
431        }
432        // Present failed but Validate ran.
433    } else {
434        error = hwcDisplay->validate(&numTypes, &numRequests);
435    }
436    ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
437    if (error != HWC2::Error::HasChanges) {
438        RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX);
439    }
440
441    std::unordered_map<HWC2::Layer*, HWC2::Composition> changedTypes;
442    changedTypes.reserve(numTypes);
443    error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
444    RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX);
445
446    displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0);
447    std::unordered_map<HWC2::Layer*, HWC2::LayerRequest> layerRequests;
448    layerRequests.reserve(numRequests);
449    error = hwcDisplay->getRequests(&displayData.displayRequests,
450            &layerRequests);
451    RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
452
453    displayData.hasClientComposition = false;
454    displayData.hasDeviceComposition = false;
455    for (auto& layer : displayDevice.getVisibleLayersSortedByZ()) {
456        auto hwcLayer = layer->getHwcLayer(displayId);
457
458        if (changedTypes.count(hwcLayer) != 0) {
459            // We pass false so we only update our state and don't call back
460            // into the HWC device
461            validateChange(layer->getCompositionType(displayId),
462                    changedTypes[hwcLayer]);
463            layer->setCompositionType(displayId, changedTypes[hwcLayer], false);
464        }
465
466        switch (layer->getCompositionType(displayId)) {
467            case HWC2::Composition::Client:
468                displayData.hasClientComposition = true;
469                break;
470            case HWC2::Composition::Device:
471            case HWC2::Composition::SolidColor:
472            case HWC2::Composition::Cursor:
473            case HWC2::Composition::Sideband:
474                displayData.hasDeviceComposition = true;
475                break;
476            default:
477                break;
478        }
479
480        if (layerRequests.count(hwcLayer) != 0 &&
481                layerRequests[hwcLayer] ==
482                        HWC2::LayerRequest::ClearClientTarget) {
483            layer->setClearClientTarget(displayId, true);
484        } else {
485            if (layerRequests.count(hwcLayer) != 0) {
486                LOG_DISPLAY_ERROR(displayId,
487                                  ("Unknown layer request " + to_string(layerRequests[hwcLayer]))
488                                          .c_str());
489            }
490            layer->setClearClientTarget(displayId, false);
491        }
492    }
493
494    error = hwcDisplay->acceptChanges();
495    RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
496
497    return NO_ERROR;
498}
499
500bool HWComposer::hasDeviceComposition(int32_t displayId) const {
501    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
502        // Displays without a corresponding HWC display are never composed by
503        // the device
504        return false;
505    }
506
507    RETURN_IF_INVALID_DISPLAY(displayId, false);
508    return mDisplayData[displayId].hasDeviceComposition;
509}
510
511bool HWComposer::hasFlipClientTargetRequest(int32_t displayId) const {
512    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
513        // Displays without a corresponding HWC display are never composed by
514        // the device
515        return false;
516    }
517
518    RETURN_IF_INVALID_DISPLAY(displayId, false);
519    return ((static_cast<uint32_t>(mDisplayData[displayId].displayRequests) &
520             static_cast<uint32_t>(HWC2::DisplayRequest::FlipClientTarget)) != 0);
521}
522
523bool HWComposer::hasClientComposition(int32_t displayId) const {
524    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
525        // Displays without a corresponding HWC display are always composed by
526        // the client
527        return true;
528    }
529
530    RETURN_IF_INVALID_DISPLAY(displayId, true);
531    return mDisplayData[displayId].hasClientComposition;
532}
533
534sp<Fence> HWComposer::getPresentFence(int32_t displayId) const {
535    RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
536    return mDisplayData[displayId].lastPresentFence;
537}
538
539sp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId,
540        HWC2::Layer* layer) const {
541    RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
542    auto displayFences = mDisplayData[displayId].releaseFences;
543    if (displayFences.count(layer) == 0) {
544        ALOGV("getLayerReleaseFence: Release fence not found");
545        return Fence::NO_FENCE;
546    }
547    return displayFences[layer];
548}
549
550status_t HWComposer::presentAndGetReleaseFences(int32_t displayId) {
551    ATRACE_CALL();
552
553    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
554
555    auto& displayData = mDisplayData[displayId];
556    auto& hwcDisplay = displayData.hwcDisplay;
557
558    if (displayData.validateWasSkipped) {
559        // explicitly flush all pending commands
560        auto error = mHwcDevice->flushCommands();
561        RETURN_IF_HWC_ERROR_FOR("flushCommands", error, displayId, UNKNOWN_ERROR);
562        RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR);
563        return NO_ERROR;
564    }
565
566    auto error = hwcDisplay->present(&displayData.lastPresentFence);
567    RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR);
568
569    std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
570    error = hwcDisplay->getReleaseFences(&releaseFences);
571    RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR);
572
573    displayData.releaseFences = std::move(releaseFences);
574
575    return NO_ERROR;
576}
577
578status_t HWComposer::setPowerMode(int32_t displayId, int32_t intMode) {
579    ALOGV("setPowerMode(%d, %d)", displayId, intMode);
580    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
581
582    if (displayId >= VIRTUAL_DISPLAY_ID_BASE) {
583        LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
584        return INVALID_OPERATION;
585    }
586
587    auto mode = static_cast<HWC2::PowerMode>(intMode);
588    if (mode == HWC2::PowerMode::Off) {
589        setVsyncEnabled(displayId, HWC2::Vsync::Disable);
590    }
591
592    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
593    switch (mode) {
594        case HWC2::PowerMode::Off:
595        case HWC2::PowerMode::On:
596            ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
597            {
598                auto error = hwcDisplay->setPowerMode(mode);
599                LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error, displayId);
600            }
601            break;
602        case HWC2::PowerMode::Doze:
603        case HWC2::PowerMode::DozeSuspend:
604            ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
605            {
606                bool supportsDoze = false;
607                auto error = hwcDisplay->supportsDoze(&supportsDoze);
608                LOG_HWC_ERROR("supportsDoze", error, displayId);
609
610                if (!supportsDoze) {
611                    mode = HWC2::PowerMode::On;
612                }
613
614                error = hwcDisplay->setPowerMode(mode);
615                LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error, displayId);
616            }
617            break;
618        default:
619            ALOGV("setPowerMode: Not calling HWC");
620            break;
621    }
622
623    return NO_ERROR;
624}
625
626status_t HWComposer::setActiveConfig(int32_t displayId, size_t configId) {
627    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
628
629    auto& displayData = mDisplayData[displayId];
630    if (displayData.configMap.count(configId) == 0) {
631        LOG_DISPLAY_ERROR(displayId, ("Invalid config " + std::to_string(configId)).c_str());
632        return BAD_INDEX;
633    }
634
635    auto error = displayData.hwcDisplay->setActiveConfig(displayData.configMap[configId]);
636    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
637    return NO_ERROR;
638}
639
640status_t HWComposer::setColorTransform(int32_t displayId,
641        const mat4& transform) {
642    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
643
644    auto& displayData = mDisplayData[displayId];
645    bool isIdentity = transform == mat4();
646    auto error = displayData.hwcDisplay->setColorTransform(transform,
647            isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY :
648            HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX);
649    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
650    return NO_ERROR;
651}
652
653void HWComposer::disconnectDisplay(int displayId) {
654    LOG_ALWAYS_FATAL_IF(displayId < 0);
655    auto& displayData = mDisplayData[displayId];
656
657    auto displayType = HWC2::DisplayType::Invalid;
658    auto error = displayData.hwcDisplay->getType(&displayType);
659    RETURN_IF_HWC_ERROR_FOR("getType", error, displayId);
660
661    // If this was a virtual display, add its slot back for reuse by future
662    // virtual displays
663    if (displayType == HWC2::DisplayType::Virtual) {
664        mFreeDisplaySlots.insert(displayId);
665        ++mRemainingHwcVirtualDisplays;
666    }
667
668    auto hwcId = displayData.hwcDisplay->getId();
669    mHwcDisplaySlots.erase(hwcId);
670    displayData.reset();
671
672    mHwcDevice->destroyDisplay(hwcId);
673}
674
675status_t HWComposer::setOutputBuffer(int32_t displayId,
676        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
677    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
678
679    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
680    auto displayType = HWC2::DisplayType::Invalid;
681    auto error = hwcDisplay->getType(&displayType);
682    RETURN_IF_HWC_ERROR_FOR("getType", error, displayId, NAME_NOT_FOUND);
683
684    if (displayType != HWC2::DisplayType::Virtual) {
685        LOG_DISPLAY_ERROR(displayId, "Invalid operation on physical display");
686        return INVALID_OPERATION;
687    }
688
689    error = hwcDisplay->setOutputBuffer(buffer, acquireFence);
690    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
691    return NO_ERROR;
692}
693
694void HWComposer::clearReleaseFences(int32_t displayId) {
695    RETURN_IF_INVALID_DISPLAY(displayId);
696    mDisplayData[displayId].releaseFences.clear();
697}
698
699status_t HWComposer::getHdrCapabilities(
700        int32_t displayId, HdrCapabilities* outCapabilities) {
701    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
702
703    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
704    auto error = hwcDisplay->getHdrCapabilities(outCapabilities);
705    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
706    return NO_ERROR;
707}
708
709int32_t HWComposer::getSupportedPerFrameMetadata(int32_t displayId) const {
710    RETURN_IF_INVALID_DISPLAY(displayId, 0);
711
712    int32_t supportedMetadata;
713    auto error = mDisplayData[displayId].hwcDisplay->getSupportedPerFrameMetadata(
714            &supportedMetadata);
715    RETURN_IF_HWC_ERROR(error, displayId, 0);
716    return supportedMetadata;
717}
718
719std::vector<ui::RenderIntent> HWComposer::getRenderIntents(int32_t displayId,
720        ui::ColorMode colorMode) const {
721    RETURN_IF_INVALID_DISPLAY(displayId, {});
722
723    std::vector<ui::RenderIntent> renderIntents;
724    auto error = mDisplayData[displayId].hwcDisplay->getRenderIntents(colorMode, &renderIntents);
725    RETURN_IF_HWC_ERROR(error, displayId, {});
726    return renderIntents;
727}
728
729mat4 HWComposer::getDataspaceSaturationMatrix(int32_t displayId, ui::Dataspace dataspace) {
730    RETURN_IF_INVALID_DISPLAY(displayId, {});
731
732    mat4 matrix;
733    auto error = mDisplayData[displayId].hwcDisplay->getDataspaceSaturationMatrix(dataspace,
734            &matrix);
735    RETURN_IF_HWC_ERROR(error, displayId, {});
736    return matrix;
737}
738
739// Converts a PixelFormat to a human-readable string.  Max 11 chars.
740// (Could use a table of prefab String8 objects.)
741/*
742static String8 getFormatStr(PixelFormat format) {
743    switch (format) {
744    case PIXEL_FORMAT_RGBA_8888:    return String8("RGBA_8888");
745    case PIXEL_FORMAT_RGBX_8888:    return String8("RGBx_8888");
746    case PIXEL_FORMAT_RGB_888:      return String8("RGB_888");
747    case PIXEL_FORMAT_RGB_565:      return String8("RGB_565");
748    case PIXEL_FORMAT_BGRA_8888:    return String8("BGRA_8888");
749    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
750                                    return String8("ImplDef");
751    default:
752        String8 result;
753        result.appendFormat("? %08x", format);
754        return result;
755    }
756}
757*/
758
759bool HWComposer::isUsingVrComposer() const {
760    return getComposer()->isUsingVrComposer();
761}
762
763void HWComposer::dump(String8& result) const {
764    // TODO: In order to provide a dump equivalent to HWC1, we need to shadow
765    // all the state going into the layers. This is probably better done in
766    // Layer itself, but it's going to take a bit of work to get there.
767    result.append(mHwcDevice->dump().c_str());
768}
769
770std::optional<hwc2_display_t>
771HWComposer::getHwcDisplayId(int32_t displayId) const {
772    if (!isValidDisplay(displayId)) {
773        return {};
774    }
775    return mDisplayData[displayId].hwcDisplay->getId();
776}
777
778// ---------------------------------------------------------------------------
779
780HWComposer::DisplayData::DisplayData()
781  : hasClientComposition(false),
782    hasDeviceComposition(false),
783    hwcDisplay(nullptr),
784    lastPresentFence(Fence::NO_FENCE),
785    outbufHandle(nullptr),
786    outbufAcquireFence(Fence::NO_FENCE),
787    vsyncEnabled(HWC2::Vsync::Disable) {
788    ALOGV("Created new DisplayData");
789}
790
791HWComposer::DisplayData::~DisplayData() {
792}
793
794void HWComposer::DisplayData::reset() {
795    ALOGV("DisplayData reset");
796    *this = DisplayData();
797}
798
799// ---------------------------------------------------------------------------
800}; // namespace android
801