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