HWComposer.cpp revision 3c085a07a84bc03aefb2c0caf24a1ae1a9f5f90c
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
321int HWComposer::getActiveConfigIndex(int32_t displayId) const {
322    if (!isValidDisplay(displayId)) {
323        ALOGV("getActiveConfigIndex: Attempted to access invalid display %d", displayId);
324        return -1;
325    }
326    int index;
327    auto error = mDisplayData[displayId].hwcDisplay->getActiveConfigIndex(&index);
328    if (error == HWC2::Error::BadConfig) {
329        ALOGE("getActiveConfigIndex: No config active, returning -1");
330        return -1;
331    } else if (error != HWC2::Error::None) {
332        ALOGE("getActiveConfigIndex failed for display %d: %s (%d)", displayId,
333              to_string(error).c_str(), static_cast<int32_t>(error));
334        return -1;
335    } else if (index < 0) {
336        ALOGE("getActiveConfigIndex returned an unknown config for display %d", displayId);
337        return -1;
338    }
339
340    return index;
341}
342
343std::vector<ui::ColorMode> HWComposer::getColorModes(int32_t displayId) const {
344    RETURN_IF_INVALID_DISPLAY(displayId, {});
345
346    std::vector<ui::ColorMode> modes;
347    auto error = mDisplayData[displayId].hwcDisplay->getColorModes(&modes);
348    RETURN_IF_HWC_ERROR(error, displayId, {});
349    return modes;
350}
351
352status_t HWComposer::setActiveColorMode(int32_t displayId, ui::ColorMode mode,
353        ui::RenderIntent renderIntent) {
354    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
355
356    auto& displayData = mDisplayData[displayId];
357    auto error = displayData.hwcDisplay->setColorMode(mode, renderIntent);
358    RETURN_IF_HWC_ERROR_FOR(("setColorMode(" + decodeColorMode(mode) + ", " +
359                             decodeRenderIntent(renderIntent) + ")")
360                                    .c_str(),
361                            error, displayId, UNKNOWN_ERROR);
362
363    return NO_ERROR;
364}
365
366
367void HWComposer::setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled) {
368    if (displayId < 0 || displayId >= HWC_DISPLAY_VIRTUAL) {
369        ALOGD("setVsyncEnabled: Ignoring for virtual display %d", displayId);
370        return;
371    }
372
373    RETURN_IF_INVALID_DISPLAY(displayId);
374
375    // NOTE: we use our own internal lock here because we have to call
376    // into the HWC with the lock held, and we want to make sure
377    // that even if HWC blocks (which it shouldn't), it won't
378    // affect other threads.
379    Mutex::Autolock _l(mVsyncLock);
380    auto& displayData = mDisplayData[displayId];
381    if (enabled != displayData.vsyncEnabled) {
382        ATRACE_CALL();
383        auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
384        RETURN_IF_HWC_ERROR(error, displayId);
385
386        displayData.vsyncEnabled = enabled;
387
388        char tag[16];
389        snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", displayId);
390        ATRACE_INT(tag, enabled == HWC2::Vsync::Enable ? 1 : 0);
391    }
392}
393
394status_t HWComposer::setClientTarget(int32_t displayId, uint32_t slot,
395        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
396        ui::Dataspace dataspace) {
397    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
398
399    ALOGV("setClientTarget for display %d", displayId);
400    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
401    auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
402    RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
403    return NO_ERROR;
404}
405
406status_t HWComposer::prepare(DisplayDevice& displayDevice) {
407    ATRACE_CALL();
408
409    Mutex::Autolock _l(mDisplayLock);
410    auto displayId = displayDevice.getHwcDisplayId();
411    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
412        ALOGV("Skipping HWComposer prepare for non-HWC display");
413        return NO_ERROR;
414    }
415
416    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
417
418    auto& displayData = mDisplayData[displayId];
419    auto& hwcDisplay = displayData.hwcDisplay;
420    if (!hwcDisplay->isConnected()) {
421        return NO_ERROR;
422    }
423
424    uint32_t numTypes = 0;
425    uint32_t numRequests = 0;
426
427    HWC2::Error error = HWC2::Error::None;
428
429    // First try to skip validate altogether when there is no client
430    // composition.  When there is client composition, since we haven't
431    // rendered to the client target yet, we should not attempt to skip
432    // validate.
433    //
434    // displayData.hasClientComposition hasn't been updated for this frame.
435    // The check below is incorrect.  We actually rely on HWC here to fall
436    // back to validate when there is any client layer.
437    displayData.validateWasSkipped = false;
438    if (!displayData.hasClientComposition) {
439        sp<android::Fence> outPresentFence;
440        uint32_t state = UINT32_MAX;
441        error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
442        if (error != HWC2::Error::HasChanges) {
443            RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
444        }
445        if (state == 1) { //Present Succeeded.
446            std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
447            error = hwcDisplay->getReleaseFences(&releaseFences);
448            displayData.releaseFences = std::move(releaseFences);
449            displayData.lastPresentFence = outPresentFence;
450            displayData.validateWasSkipped = true;
451            displayData.presentError = error;
452            return NO_ERROR;
453        }
454        // Present failed but Validate ran.
455    } else {
456        error = hwcDisplay->validate(&numTypes, &numRequests);
457    }
458    ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
459    if (error != HWC2::Error::HasChanges) {
460        RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX);
461    }
462
463    std::unordered_map<HWC2::Layer*, HWC2::Composition> changedTypes;
464    changedTypes.reserve(numTypes);
465    error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
466    RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX);
467
468    displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0);
469    std::unordered_map<HWC2::Layer*, HWC2::LayerRequest> layerRequests;
470    layerRequests.reserve(numRequests);
471    error = hwcDisplay->getRequests(&displayData.displayRequests,
472            &layerRequests);
473    RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
474
475    displayData.hasClientComposition = false;
476    displayData.hasDeviceComposition = false;
477    for (auto& layer : displayDevice.getVisibleLayersSortedByZ()) {
478        auto hwcLayer = layer->getHwcLayer(displayId);
479
480        if (changedTypes.count(hwcLayer) != 0) {
481            // We pass false so we only update our state and don't call back
482            // into the HWC device
483            validateChange(layer->getCompositionType(displayId),
484                    changedTypes[hwcLayer]);
485            layer->setCompositionType(displayId, changedTypes[hwcLayer], false);
486        }
487
488        switch (layer->getCompositionType(displayId)) {
489            case HWC2::Composition::Client:
490                displayData.hasClientComposition = true;
491                break;
492            case HWC2::Composition::Device:
493            case HWC2::Composition::SolidColor:
494            case HWC2::Composition::Cursor:
495            case HWC2::Composition::Sideband:
496                displayData.hasDeviceComposition = true;
497                break;
498            default:
499                break;
500        }
501
502        if (layerRequests.count(hwcLayer) != 0 &&
503                layerRequests[hwcLayer] ==
504                        HWC2::LayerRequest::ClearClientTarget) {
505            layer->setClearClientTarget(displayId, true);
506        } else {
507            if (layerRequests.count(hwcLayer) != 0) {
508                LOG_DISPLAY_ERROR(displayId,
509                                  ("Unknown layer request " + to_string(layerRequests[hwcLayer]))
510                                          .c_str());
511            }
512            layer->setClearClientTarget(displayId, false);
513        }
514    }
515
516    error = hwcDisplay->acceptChanges();
517    RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
518
519    return NO_ERROR;
520}
521
522bool HWComposer::hasDeviceComposition(int32_t displayId) const {
523    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
524        // Displays without a corresponding HWC display are never composed by
525        // the device
526        return false;
527    }
528
529    RETURN_IF_INVALID_DISPLAY(displayId, false);
530    return mDisplayData[displayId].hasDeviceComposition;
531}
532
533bool HWComposer::hasFlipClientTargetRequest(int32_t displayId) const {
534    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
535        // Displays without a corresponding HWC display are never composed by
536        // the device
537        return false;
538    }
539
540    RETURN_IF_INVALID_DISPLAY(displayId, false);
541    return ((static_cast<uint32_t>(mDisplayData[displayId].displayRequests) &
542             static_cast<uint32_t>(HWC2::DisplayRequest::FlipClientTarget)) != 0);
543}
544
545bool HWComposer::hasClientComposition(int32_t displayId) const {
546    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
547        // Displays without a corresponding HWC display are always composed by
548        // the client
549        return true;
550    }
551
552    RETURN_IF_INVALID_DISPLAY(displayId, true);
553    return mDisplayData[displayId].hasClientComposition;
554}
555
556sp<Fence> HWComposer::getPresentFence(int32_t displayId) const {
557    RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
558    return mDisplayData[displayId].lastPresentFence;
559}
560
561sp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId,
562        HWC2::Layer* layer) const {
563    RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
564    auto displayFences = mDisplayData[displayId].releaseFences;
565    if (displayFences.count(layer) == 0) {
566        ALOGV("getLayerReleaseFence: Release fence not found");
567        return Fence::NO_FENCE;
568    }
569    return displayFences[layer];
570}
571
572status_t HWComposer::presentAndGetReleaseFences(int32_t displayId) {
573    ATRACE_CALL();
574
575    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
576
577    auto& displayData = mDisplayData[displayId];
578    auto& hwcDisplay = displayData.hwcDisplay;
579
580    if (displayData.validateWasSkipped) {
581        // explicitly flush all pending commands
582        auto error = mHwcDevice->flushCommands();
583        RETURN_IF_HWC_ERROR_FOR("flushCommands", error, displayId, UNKNOWN_ERROR);
584        RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR);
585        return NO_ERROR;
586    }
587
588    auto error = hwcDisplay->present(&displayData.lastPresentFence);
589    RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR);
590
591    std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
592    error = hwcDisplay->getReleaseFences(&releaseFences);
593    RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR);
594
595    displayData.releaseFences = std::move(releaseFences);
596
597    return NO_ERROR;
598}
599
600status_t HWComposer::setPowerMode(int32_t displayId, int32_t intMode) {
601    ALOGV("setPowerMode(%d, %d)", displayId, intMode);
602    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
603
604    if (displayId >= VIRTUAL_DISPLAY_ID_BASE) {
605        LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
606        return INVALID_OPERATION;
607    }
608
609    auto mode = static_cast<HWC2::PowerMode>(intMode);
610    if (mode == HWC2::PowerMode::Off) {
611        setVsyncEnabled(displayId, HWC2::Vsync::Disable);
612    }
613
614    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
615    switch (mode) {
616        case HWC2::PowerMode::Off:
617        case HWC2::PowerMode::On:
618            ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
619            {
620                auto error = hwcDisplay->setPowerMode(mode);
621                if (error != HWC2::Error::None) {
622                    LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(),
623                                  error, displayId);
624                }
625            }
626            break;
627        case HWC2::PowerMode::Doze:
628        case HWC2::PowerMode::DozeSuspend:
629            ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
630            {
631                bool supportsDoze = false;
632                auto error = hwcDisplay->supportsDoze(&supportsDoze);
633                if (error != HWC2::Error::None) {
634                    LOG_HWC_ERROR("supportsDoze", error, displayId);
635                }
636
637                if (!supportsDoze) {
638                    mode = HWC2::PowerMode::On;
639                }
640
641                error = hwcDisplay->setPowerMode(mode);
642                if (error != HWC2::Error::None) {
643                    LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(),
644                                  error, displayId);
645                }
646            }
647            break;
648        default:
649            ALOGV("setPowerMode: Not calling HWC");
650            break;
651    }
652
653    return NO_ERROR;
654}
655
656status_t HWComposer::setActiveConfig(int32_t displayId, size_t configId) {
657    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
658
659    auto& displayData = mDisplayData[displayId];
660    if (displayData.configMap.count(configId) == 0) {
661        LOG_DISPLAY_ERROR(displayId, ("Invalid config " + std::to_string(configId)).c_str());
662        return BAD_INDEX;
663    }
664
665    auto error = displayData.hwcDisplay->setActiveConfig(displayData.configMap[configId]);
666    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
667    return NO_ERROR;
668}
669
670status_t HWComposer::setColorTransform(int32_t displayId,
671        const mat4& transform) {
672    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
673
674    auto& displayData = mDisplayData[displayId];
675    bool isIdentity = transform == mat4();
676    auto error = displayData.hwcDisplay->setColorTransform(transform,
677            isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY :
678            HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX);
679    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
680    return NO_ERROR;
681}
682
683void HWComposer::disconnectDisplay(int displayId) {
684    LOG_ALWAYS_FATAL_IF(displayId < 0);
685    auto& displayData = mDisplayData[displayId];
686
687    auto displayType = HWC2::DisplayType::Invalid;
688    auto error = displayData.hwcDisplay->getType(&displayType);
689    RETURN_IF_HWC_ERROR_FOR("getType", error, displayId);
690
691    // If this was a virtual display, add its slot back for reuse by future
692    // virtual displays
693    if (displayType == HWC2::DisplayType::Virtual) {
694        mFreeDisplaySlots.insert(displayId);
695        ++mRemainingHwcVirtualDisplays;
696    }
697
698    auto hwcId = displayData.hwcDisplay->getId();
699    mHwcDisplaySlots.erase(hwcId);
700    displayData.reset();
701
702    mHwcDevice->destroyDisplay(hwcId);
703}
704
705status_t HWComposer::setOutputBuffer(int32_t displayId,
706        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
707    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
708
709    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
710    auto displayType = HWC2::DisplayType::Invalid;
711    auto error = hwcDisplay->getType(&displayType);
712    RETURN_IF_HWC_ERROR_FOR("getType", error, displayId, NAME_NOT_FOUND);
713
714    if (displayType != HWC2::DisplayType::Virtual) {
715        LOG_DISPLAY_ERROR(displayId, "Invalid operation on physical display");
716        return INVALID_OPERATION;
717    }
718
719    error = hwcDisplay->setOutputBuffer(buffer, acquireFence);
720    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
721    return NO_ERROR;
722}
723
724void HWComposer::clearReleaseFences(int32_t displayId) {
725    RETURN_IF_INVALID_DISPLAY(displayId);
726    mDisplayData[displayId].releaseFences.clear();
727}
728
729status_t HWComposer::getHdrCapabilities(
730        int32_t displayId, HdrCapabilities* outCapabilities) {
731    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
732
733    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
734    auto error = hwcDisplay->getHdrCapabilities(outCapabilities);
735    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
736    return NO_ERROR;
737}
738
739int32_t HWComposer::getSupportedPerFrameMetadata(int32_t displayId) const {
740    RETURN_IF_INVALID_DISPLAY(displayId, 0);
741
742    int32_t supportedMetadata;
743    auto error = mDisplayData[displayId].hwcDisplay->getSupportedPerFrameMetadata(
744            &supportedMetadata);
745    RETURN_IF_HWC_ERROR(error, displayId, 0);
746    return supportedMetadata;
747}
748
749std::vector<ui::RenderIntent> HWComposer::getRenderIntents(int32_t displayId,
750        ui::ColorMode colorMode) const {
751    RETURN_IF_INVALID_DISPLAY(displayId, {});
752
753    std::vector<ui::RenderIntent> renderIntents;
754    auto error = mDisplayData[displayId].hwcDisplay->getRenderIntents(colorMode, &renderIntents);
755    RETURN_IF_HWC_ERROR(error, displayId, {});
756    return renderIntents;
757}
758
759mat4 HWComposer::getDataspaceSaturationMatrix(int32_t displayId, ui::Dataspace dataspace) {
760    RETURN_IF_INVALID_DISPLAY(displayId, {});
761
762    mat4 matrix;
763    auto error = mDisplayData[displayId].hwcDisplay->getDataspaceSaturationMatrix(dataspace,
764            &matrix);
765    RETURN_IF_HWC_ERROR(error, displayId, {});
766    return matrix;
767}
768
769// Converts a PixelFormat to a human-readable string.  Max 11 chars.
770// (Could use a table of prefab String8 objects.)
771/*
772static String8 getFormatStr(PixelFormat format) {
773    switch (format) {
774    case PIXEL_FORMAT_RGBA_8888:    return String8("RGBA_8888");
775    case PIXEL_FORMAT_RGBX_8888:    return String8("RGBx_8888");
776    case PIXEL_FORMAT_RGB_888:      return String8("RGB_888");
777    case PIXEL_FORMAT_RGB_565:      return String8("RGB_565");
778    case PIXEL_FORMAT_BGRA_8888:    return String8("BGRA_8888");
779    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
780                                    return String8("ImplDef");
781    default:
782        String8 result;
783        result.appendFormat("? %08x", format);
784        return result;
785    }
786}
787*/
788
789bool HWComposer::isUsingVrComposer() const {
790    return getComposer()->isUsingVrComposer();
791}
792
793void HWComposer::dump(String8& result) const {
794    // TODO: In order to provide a dump equivalent to HWC1, we need to shadow
795    // all the state going into the layers. This is probably better done in
796    // Layer itself, but it's going to take a bit of work to get there.
797    result.append(mHwcDevice->dump().c_str());
798}
799
800std::optional<hwc2_display_t>
801HWComposer::getHwcDisplayId(int32_t displayId) const {
802    if (!isValidDisplay(displayId)) {
803        return {};
804    }
805    return mDisplayData[displayId].hwcDisplay->getId();
806}
807
808// ---------------------------------------------------------------------------
809
810HWComposer::DisplayData::DisplayData()
811  : hasClientComposition(false),
812    hasDeviceComposition(false),
813    hwcDisplay(nullptr),
814    lastPresentFence(Fence::NO_FENCE),
815    outbufHandle(nullptr),
816    outbufAcquireFence(Fence::NO_FENCE),
817    vsyncEnabled(HWC2::Vsync::Disable) {
818    ALOGV("Created new DisplayData");
819}
820
821HWComposer::DisplayData::~DisplayData() {
822}
823
824void HWComposer::DisplayData::reset() {
825    ALOGV("DisplayData reset");
826    *this = DisplayData();
827}
828
829// ---------------------------------------------------------------------------
830}; // namespace android
831