HWComposer.cpp revision d8ac4fd17a71b8b523121186b8a03212cd5122fe
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    auto error = hwcDisplay->validate(&numTypes, &numRequests);
459    if (error != HWC2::Error::None && error != HWC2::Error::HasChanges) {
460        ALOGE("prepare: validate failed for display %d: %s (%d)", displayId,
461                to_string(error).c_str(), static_cast<int32_t>(error));
462        return BAD_INDEX;
463    }
464
465    std::unordered_map<std::shared_ptr<HWC2::Layer>, HWC2::Composition>
466        changedTypes;
467    changedTypes.reserve(numTypes);
468    error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
469    if (error != HWC2::Error::None) {
470        ALOGE("prepare: getChangedCompositionTypes failed on display %d: "
471                "%s (%d)", displayId, to_string(error).c_str(),
472                static_cast<int32_t>(error));
473        return BAD_INDEX;
474    }
475
476
477    displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0);
478    std::unordered_map<std::shared_ptr<HWC2::Layer>, HWC2::LayerRequest>
479        layerRequests;
480    layerRequests.reserve(numRequests);
481    error = hwcDisplay->getRequests(&displayData.displayRequests,
482            &layerRequests);
483    if (error != HWC2::Error::None) {
484        ALOGE("prepare: getRequests failed on display %d: %s (%d)", displayId,
485                to_string(error).c_str(), static_cast<int32_t>(error));
486        return BAD_INDEX;
487    }
488
489    displayData.hasClientComposition = false;
490    displayData.hasDeviceComposition = false;
491    for (auto& layer : displayDevice.getVisibleLayersSortedByZ()) {
492        auto hwcLayer = layer->getHwcLayer(displayId);
493
494        if (changedTypes.count(hwcLayer) != 0) {
495            // We pass false so we only update our state and don't call back
496            // into the HWC device
497            validateChange(layer->getCompositionType(displayId),
498                    changedTypes[hwcLayer]);
499            layer->setCompositionType(displayId, changedTypes[hwcLayer], false);
500        }
501
502        switch (layer->getCompositionType(displayId)) {
503            case HWC2::Composition::Client:
504                displayData.hasClientComposition = true;
505                break;
506            case HWC2::Composition::Device:
507            case HWC2::Composition::SolidColor:
508            case HWC2::Composition::Cursor:
509            case HWC2::Composition::Sideband:
510                displayData.hasDeviceComposition = true;
511                break;
512            default:
513                break;
514        }
515
516        if (layerRequests.count(hwcLayer) != 0 &&
517                layerRequests[hwcLayer] ==
518                        HWC2::LayerRequest::ClearClientTarget) {
519            layer->setClearClientTarget(displayId, true);
520        } else {
521            if (layerRequests.count(hwcLayer) != 0) {
522                ALOGE("prepare: Unknown layer request: %s",
523                        to_string(layerRequests[hwcLayer]).c_str());
524            }
525            layer->setClearClientTarget(displayId, false);
526        }
527    }
528
529    error = hwcDisplay->acceptChanges();
530    if (error != HWC2::Error::None) {
531        ALOGE("prepare: acceptChanges failed: %s", to_string(error).c_str());
532        return BAD_INDEX;
533    }
534
535    return NO_ERROR;
536}
537
538bool HWComposer::hasDeviceComposition(int32_t displayId) const {
539    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
540        // Displays without a corresponding HWC display are never composed by
541        // the device
542        return false;
543    }
544    if (!isValidDisplay(displayId)) {
545        ALOGE("hasDeviceComposition: Invalid display %d", displayId);
546        return false;
547    }
548    return mDisplayData[displayId].hasDeviceComposition;
549}
550
551bool HWComposer::hasClientComposition(int32_t displayId) const {
552    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
553        // Displays without a corresponding HWC display are always composed by
554        // the client
555        return true;
556    }
557    if (!isValidDisplay(displayId)) {
558        ALOGE("hasClientComposition: Invalid display %d", displayId);
559        return true;
560    }
561    return mDisplayData[displayId].hasClientComposition;
562}
563
564sp<Fence> HWComposer::getPresentFence(int32_t displayId) const {
565    if (!isValidDisplay(displayId)) {
566        ALOGE("getPresentFence failed for invalid display %d", displayId);
567        return Fence::NO_FENCE;
568    }
569    return mDisplayData[displayId].lastPresentFence;
570}
571
572sp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId,
573        const std::shared_ptr<HWC2::Layer>& layer) const {
574    if (!isValidDisplay(displayId)) {
575        ALOGE("getLayerReleaseFence: Invalid display");
576        return Fence::NO_FENCE;
577    }
578    auto displayFences = mDisplayData[displayId].releaseFences;
579    if (displayFences.count(layer) == 0) {
580        ALOGV("getLayerReleaseFence: Release fence not found");
581        return Fence::NO_FENCE;
582    }
583    return displayFences[layer];
584}
585
586status_t HWComposer::presentAndGetReleaseFences(int32_t displayId) {
587    ATRACE_CALL();
588
589    if (!isValidDisplay(displayId)) {
590        return BAD_INDEX;
591    }
592
593    auto& displayData = mDisplayData[displayId];
594    auto& hwcDisplay = displayData.hwcDisplay;
595    auto error = hwcDisplay->present(&displayData.lastPresentFence);
596    if (error != HWC2::Error::None) {
597        ALOGE("presentAndGetReleaseFences: failed for display %d: %s (%d)",
598              displayId, to_string(error).c_str(), static_cast<int32_t>(error));
599        return UNKNOWN_ERROR;
600    }
601
602    std::unordered_map<std::shared_ptr<HWC2::Layer>, sp<Fence>> releaseFences;
603    error = hwcDisplay->getReleaseFences(&releaseFences);
604    if (error != HWC2::Error::None) {
605        ALOGE("presentAndGetReleaseFences: Failed to get release fences "
606              "for display %d: %s (%d)",
607                displayId, to_string(error).c_str(),
608                static_cast<int32_t>(error));
609        return UNKNOWN_ERROR;
610    }
611
612    displayData.releaseFences = std::move(releaseFences);
613
614    return NO_ERROR;
615}
616
617status_t HWComposer::setPowerMode(int32_t displayId, int32_t intMode) {
618    ALOGV("setPowerMode(%d, %d)", displayId, intMode);
619    if (!isValidDisplay(displayId)) {
620        ALOGE("setPowerMode: Bad display");
621        return BAD_INDEX;
622    }
623    if (displayId >= VIRTUAL_DISPLAY_ID_BASE) {
624        ALOGE("setPowerMode: Virtual display %d passed in, returning",
625                displayId);
626        return BAD_INDEX;
627    }
628
629    auto mode = static_cast<HWC2::PowerMode>(intMode);
630    if (mode == HWC2::PowerMode::Off) {
631        setVsyncEnabled(displayId, HWC2::Vsync::Disable);
632    }
633
634    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
635    switch (mode) {
636        case HWC2::PowerMode::Off:
637        case HWC2::PowerMode::On:
638            ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
639            {
640                auto error = hwcDisplay->setPowerMode(mode);
641                if (error != HWC2::Error::None) {
642                    ALOGE("setPowerMode: Unable to set power mode %s for "
643                            "display %d: %s (%d)", to_string(mode).c_str(),
644                            displayId, to_string(error).c_str(),
645                            static_cast<int32_t>(error));
646                }
647            }
648            break;
649        case HWC2::PowerMode::Doze:
650        case HWC2::PowerMode::DozeSuspend:
651            ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
652            {
653                bool supportsDoze = false;
654                auto error = hwcDisplay->supportsDoze(&supportsDoze);
655                if (error != HWC2::Error::None) {
656                    ALOGE("setPowerMode: Unable to query doze support for "
657                            "display %d: %s (%d)", displayId,
658                            to_string(error).c_str(),
659                            static_cast<int32_t>(error));
660                }
661                if (!supportsDoze) {
662                    mode = HWC2::PowerMode::On;
663                }
664
665                error = hwcDisplay->setPowerMode(mode);
666                if (error != HWC2::Error::None) {
667                    ALOGE("setPowerMode: Unable to set power mode %s for "
668                            "display %d: %s (%d)", to_string(mode).c_str(),
669                            displayId, to_string(error).c_str(),
670                            static_cast<int32_t>(error));
671                }
672            }
673            break;
674        default:
675            ALOGV("setPowerMode: Not calling HWC");
676            break;
677    }
678
679    return NO_ERROR;
680}
681
682status_t HWComposer::setActiveConfig(int32_t displayId, size_t configId) {
683    if (!isValidDisplay(displayId)) {
684        ALOGE("setActiveConfig: Display %d is not valid", displayId);
685        return BAD_INDEX;
686    }
687
688    auto& displayData = mDisplayData[displayId];
689    if (displayData.configMap.count(configId) == 0) {
690        ALOGE("setActiveConfig: Invalid config %zd", configId);
691        return BAD_INDEX;
692    }
693
694    auto error = displayData.hwcDisplay->setActiveConfig(
695            displayData.configMap[configId]);
696    if (error != HWC2::Error::None) {
697        ALOGE("setActiveConfig: Failed to set config %zu on display %d: "
698                "%s (%d)", configId, displayId, to_string(error).c_str(),
699                static_cast<int32_t>(error));
700        return UNKNOWN_ERROR;
701    }
702
703    return NO_ERROR;
704}
705
706status_t HWComposer::setColorTransform(int32_t displayId,
707        const mat4& transform) {
708    if (!isValidDisplay(displayId)) {
709        ALOGE("setColorTransform: Display %d is not valid", displayId);
710        return BAD_INDEX;
711    }
712
713    auto& displayData = mDisplayData[displayId];
714    bool isIdentity = transform == mat4();
715    auto error = displayData.hwcDisplay->setColorTransform(transform,
716            isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY :
717            HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX);
718    if (error != HWC2::Error::None) {
719        ALOGE("setColorTransform: Failed to set transform on display %d: "
720                "%s (%d)", displayId, to_string(error).c_str(),
721                static_cast<int32_t>(error));
722        return UNKNOWN_ERROR;
723    }
724
725    return NO_ERROR;
726}
727
728void HWComposer::disconnectDisplay(int displayId) {
729    LOG_ALWAYS_FATAL_IF(displayId < 0);
730    auto& displayData = mDisplayData[displayId];
731
732    auto displayType = HWC2::DisplayType::Invalid;
733    auto error = displayData.hwcDisplay->getType(&displayType);
734    if (error != HWC2::Error::None) {
735        ALOGE("disconnectDisplay: Failed to determine type of display %d",
736                displayId);
737        return;
738    }
739
740    // If this was a virtual display, add its slot back for reuse by future
741    // virtual displays
742    if (displayType == HWC2::DisplayType::Virtual) {
743        mFreeDisplaySlots.insert(displayId);
744        ++mRemainingHwcVirtualDisplays;
745    }
746
747    auto hwcId = displayData.hwcDisplay->getId();
748    mHwcDisplaySlots.erase(hwcId);
749    displayData.reset();
750}
751
752status_t HWComposer::setOutputBuffer(int32_t displayId,
753        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
754    if (!isValidDisplay(displayId)) {
755        ALOGE("setOutputBuffer: Display %d is not valid", displayId);
756        return BAD_INDEX;
757    }
758
759    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
760    auto displayType = HWC2::DisplayType::Invalid;
761    auto error = hwcDisplay->getType(&displayType);
762    if (error != HWC2::Error::None) {
763        ALOGE("setOutputBuffer: Failed to determine type of display %d",
764                displayId);
765        return NAME_NOT_FOUND;
766    }
767
768    if (displayType != HWC2::DisplayType::Virtual) {
769        ALOGE("setOutputBuffer: Display %d is not virtual", displayId);
770        return INVALID_OPERATION;
771    }
772
773    error = hwcDisplay->setOutputBuffer(buffer, acquireFence);
774    if (error != HWC2::Error::None) {
775        ALOGE("setOutputBuffer: Failed to set buffer on display %d: %s (%d)",
776                displayId, to_string(error).c_str(),
777                static_cast<int32_t>(error));
778        return UNKNOWN_ERROR;
779    }
780
781    return NO_ERROR;
782}
783
784void HWComposer::clearReleaseFences(int32_t displayId) {
785    if (!isValidDisplay(displayId)) {
786        ALOGE("clearReleaseFences: Display %d is not valid", displayId);
787        return;
788    }
789    mDisplayData[displayId].releaseFences.clear();
790}
791
792std::unique_ptr<HdrCapabilities> HWComposer::getHdrCapabilities(
793        int32_t displayId) {
794    if (!isValidDisplay(displayId)) {
795        ALOGE("getHdrCapabilities: Display %d is not valid", displayId);
796        return nullptr;
797    }
798
799    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
800    std::unique_ptr<HdrCapabilities> capabilities;
801    auto error = hwcDisplay->getHdrCapabilities(&capabilities);
802    if (error != HWC2::Error::None) {
803        ALOGE("getOutputCapabilities: Failed to get capabilities on display %d:"
804                " %s (%d)", displayId, to_string(error).c_str(),
805                static_cast<int32_t>(error));
806        return nullptr;
807    }
808
809    return capabilities;
810}
811
812// Converts a PixelFormat to a human-readable string.  Max 11 chars.
813// (Could use a table of prefab String8 objects.)
814/*
815static String8 getFormatStr(PixelFormat format) {
816    switch (format) {
817    case PIXEL_FORMAT_RGBA_8888:    return String8("RGBA_8888");
818    case PIXEL_FORMAT_RGBX_8888:    return String8("RGBx_8888");
819    case PIXEL_FORMAT_RGB_888:      return String8("RGB_888");
820    case PIXEL_FORMAT_RGB_565:      return String8("RGB_565");
821    case PIXEL_FORMAT_BGRA_8888:    return String8("BGRA_8888");
822    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
823                                    return String8("ImplDef");
824    default:
825        String8 result;
826        result.appendFormat("? %08x", format);
827        return result;
828    }
829}
830*/
831
832bool HWComposer::isUsingVrComposer() const {
833    return getComposer()->isUsingVrComposer();
834}
835
836void HWComposer::dump(String8& result) const {
837    // TODO: In order to provide a dump equivalent to HWC1, we need to shadow
838    // all the state going into the layers. This is probably better done in
839    // Layer itself, but it's going to take a bit of work to get there.
840    result.append(mHwcDevice->dump().c_str());
841}
842
843// ---------------------------------------------------------------------------
844
845HWComposer::DisplayData::DisplayData()
846  : hasClientComposition(false),
847    hasDeviceComposition(false),
848    hwcDisplay(),
849    lastPresentFence(Fence::NO_FENCE),
850    outbufHandle(nullptr),
851    outbufAcquireFence(Fence::NO_FENCE),
852    vsyncEnabled(HWC2::Vsync::Disable) {
853    ALOGV("Created new DisplayData");
854}
855
856HWComposer::DisplayData::~DisplayData() {
857}
858
859void HWComposer::DisplayData::reset() {
860    ALOGV("DisplayData reset");
861    *this = DisplayData();
862}
863
864// ---------------------------------------------------------------------------
865}; // namespace android
866