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