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