1a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian/*
2a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian * Copyright (C) 2010 The Android Open Source Project
3a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian *
4a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian * you may not use this file except in compliance with the License.
6a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian * You may obtain a copy of the License at
7a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian *
8a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian *
10a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian * Unless required by applicable law or agreed to in writing, software
11a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian * See the License for the specific language governing permissions and
14a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian * limitations under the License.
15a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian */
16a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza// #define LOG_NDEBUG 0
189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#undef LOG_TAG
209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#define LOG_TAG "HWComposer"
212965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian#define ATRACE_TAG ATRACE_TAG_GRAPHICS
222965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian
2392dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn#include <inttypes.h>
2492dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn#include <math.h>
25a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include <stdint.h>
26f1352df47fe20aed23c216a78923c7d248f2bb91Mathias Agopian#include <stdio.h>
27f1352df47fe20aed23c216a78923c7d248f2bb91Mathias Agopian#include <stdlib.h>
28f1352df47fe20aed23c216a78923c7d248f2bb91Mathias Agopian#include <string.h>
29a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include <sys/types.h>
30a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
31a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include <utils/Errors.h>
32da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian#include <utils/misc.h>
33399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <utils/NativeHandle.h>
348372785879d329f592f6883620b5a32d80d74691Mathias Agopian#include <utils/String8.h>
353eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian#include <utils/Thread.h>
362965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian#include <utils/Trace.h>
3722da60c3e64cd57535cbba063c07127814a2b52fMathias Agopian#include <utils/Vector.h>
38a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
39921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBuffer.h>
40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
41a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include <hardware/hardware.h>
423eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian#include <hardware/hwcomposer.h>
43a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
441c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall#include <android/configuration.h>
451c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall
46e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian#include <cutils/properties.h>
477823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h>
48a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
49a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "HWComposer.h"
509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#include "HWC2.h"
5187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar#include "ComposerHal.h"
5233ceeb32582739dd74e404593d9ddf8adf5100bbMathias Agopian
5333ceeb32582739dd74e404593d9ddf8adf5100bbMathias Agopian#include "../Layer.h"           // needed only for debugging
5433ceeb32582739dd74e404593d9ddf8adf5100bbMathias Agopian#include "../SurfaceFlinger.h"
55a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
56a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopiannamespace android {
575880cc573823148237eac9ab7bc586b8e4eb7160Jesse Hall
587296051995fbaea919480a6cc2dabb729dabc95bJesse Hall#define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION
599eb1eb5bb55740982ceae9966fc536824edc302aJesse Hall
603e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian// ---------------------------------------------------------------------------
613e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
623cfac28462910d3f976aebac54ac7301aca7e434Steven ThomasHWComposer::HWComposer(bool useVrComposer)
6323429778c41bb54cbbc0067f2151049488554bcfLogan Chien    : mHwcDevice(),
649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mDisplayData(2),
659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mFreeDisplaySlots(),
669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mHwcDisplaySlots(),
679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mCBContext(),
689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mVSyncCounts(),
6915b27e0e63dc1528ab2ddf1875f4d5a029059e5aChia-I Wu      mRemainingHwcVirtualDisplays(0)
70a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
71bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian    for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {
72bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian        mLastHwVSync[i] = 0;
73bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian        mVSyncCounts[i] = 0;
74bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian    }
75bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian
76d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    mHwcDevice = std::make_unique<HWC2::Device>(useVrComposer);
77d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    mRemainingHwcVirtualDisplays = mHwcDevice->getMaxVirtualDisplayCount();
789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
79bbd164a3c790a0649dffd2f015e6f47692c72e1cJesse Hall
809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWComposer::~HWComposer() {}
81b685c542836b93c99cd85053e07696406ea37adbJesse Hall
82d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomasvoid HWComposer::registerCallback(HWC2::ComposerCallback* callback,
83d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas                                  int32_t sequenceId) {
84d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    mHwcDevice->registerCallback(callback, sequenceId);
859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
879f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stozabool HWComposer::hasCapability(HWC2::Capability capability) const
889f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza{
899f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    return mHwcDevice->getCapabilities().count(capability) > 0;
909f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza}
919f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool HWComposer::isValidDisplay(int32_t displayId) const {
939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return static_cast<size_t>(displayId) < mDisplayData.size() &&
949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mDisplayData[displayId].hwcDisplay;
959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::validateChange(HWC2::Composition from, HWC2::Composition to) {
989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    bool valid = true;
999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    switch (from) {
1009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::Composition::Client:
1019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            valid = false;
1029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
1039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::Composition::Device:
1049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::Composition::SolidColor:
1059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            valid = (to == HWC2::Composition::Client);
1069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
1079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::Composition::Cursor:
1089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::Composition::Sideband:
1099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            valid = (to == HWC2::Composition::Client ||
1109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to == HWC2::Composition::Device);
1119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
1129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        default:
1139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
1149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!valid) {
1179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Invalid layer type change: %s --> %s", to_string(from).c_str(),
1189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(to).c_str());
1199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
1219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
122d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomasvoid HWComposer::onHotplug(hwc2_display_t displayId,
123d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas                           HWC2::Connection connection) {
124d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    ALOGV("hotplug: %" PRIu64 ", %s", displayId,
125d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas            to_string(connection).c_str());
126d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    mHwcDevice->onHotplug(displayId, connection);
1279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!mDisplayData[0].hwcDisplay) {
128d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        ALOGE_IF(connection != HWC2::Connection::Connected, "Assumed primary"
1299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " display would be connected");
130d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        mDisplayData[0].hwcDisplay = mHwcDevice->getDisplayById(displayId);
131d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        mHwcDisplaySlots[displayId] = 0;
1329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
1339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Disconnect is handled through HWComposer::disconnectDisplay via
1349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // SurfaceFlinger's onHotplugReceived callback handling
135d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        if (connection == HWC2::Connection::Connected) {
136d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas            mDisplayData[1].hwcDisplay = mHwcDevice->getDisplayById(displayId);
137d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas            mHwcDisplaySlots[displayId] = 1;
1389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
139b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    }
1401bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall}
1411bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall
142d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomasbool HWComposer::onVsync(hwc2_display_t displayId, int64_t timestamp,
143d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas                         int32_t* outDisplay) {
144d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    auto display = mHwcDevice->getDisplayById(displayId);
145d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    if (!display) {
146d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        ALOGE("onVsync Failed to find display %" PRIu64, displayId);
147d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        return false;
148d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    }
1499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto displayType = HWC2::DisplayType::Invalid;
1509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = display->getType(&displayType);
1519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
152d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        ALOGE("onVsync: Failed to determine type of display %" PRIu64,
1539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                display->getId());
154d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        return false;
155bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian    }
156d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
1579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayType == HWC2::DisplayType::Virtual) {
1589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Virtual display %" PRIu64 " passed to vsync callback",
1599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                display->getId());
160d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        return false;
1611bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall    }
1621bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall
1639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcDisplaySlots.count(display->getId()) == 0) {
1649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback",
1659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                display->getId());
166d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        return false;
1671bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall    }
1681bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall
1699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    int32_t disp = mHwcDisplaySlots[display->getId()];
1709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    {
1719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock _l(mLock);
1721604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
1739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // There have been reports of HWCs that signal several vsync events
1749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // with the same timestamp when turning the display off and on. This
1759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // is a bug in the HWC implementation, but filter the extra events
1769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // out here so they don't cause havoc downstream.
1779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (timestamp == mLastHwVSync[disp]) {
1789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
1799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    timestamp);
180d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas            return false;
1811bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall        }
1827f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
1839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mLastHwVSync[disp] = timestamp;
1841bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall    }
1851bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall
186d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    if (outDisplay) {
187d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        *outDisplay = disp;
188d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    }
189d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas
1909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    char tag[16];
1919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
1929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
1939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
194d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    return true;
1951bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall}
1961bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall
1979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
1985cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza        android_pixel_format_t* format, int32_t *outId) {
1999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mRemainingHwcVirtualDisplays == 0) {
2009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("allocateVirtualDisplay: No remaining virtual displays");
2019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return NO_MEMORY;
2021c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall    }
2031c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall
204c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard    if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
205c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard        (width > SurfaceFlinger::maxVirtualDisplaySize ||
206c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard         height > SurfaceFlinger::maxVirtualDisplaySize)) {
207e29055f5fe4a2bc0f3f75d952ff417462dc607ccFabien Sanglard        ALOGE("createVirtualDisplay: Can't create a virtual display with"
208c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard                      " a dimension > %" PRIu64 " (tried %u x %u)",
209c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard              SurfaceFlinger::maxVirtualDisplaySize, width, height);
210e29055f5fe4a2bc0f3f75d952ff417462dc607ccFabien Sanglard        return INVALID_OPERATION;
211e29055f5fe4a2bc0f3f75d952ff417462dc607ccFabien Sanglard    }
212e29055f5fe4a2bc0f3f75d952ff417462dc607ccFabien Sanglard
213d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    HWC2::Display* display;
2145cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza    auto error = mHwcDevice->createVirtualDisplay(width, height, format,
2155cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza            &display);
2169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
2179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("allocateVirtualDisplay: Failed to create HWC virtual display");
2189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return NO_MEMORY;
2199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
2209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    size_t displaySlot = 0;
2229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!mFreeDisplaySlots.empty()) {
2239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        displaySlot = *mFreeDisplaySlots.begin();
2249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mFreeDisplaySlots.erase(displaySlot);
2259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else if (mDisplayData.size() < INT32_MAX) {
2269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Don't bother allocating a slot larger than we can return
2279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        displaySlot = mDisplayData.size();
2289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mDisplayData.resize(displaySlot + 1);
2299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
2309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("allocateVirtualDisplay: Unable to allocate a display slot");
231e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        return NO_MEMORY;
232e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian    }
2339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mDisplayData[displaySlot].hwcDisplay = display;
2359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    --mRemainingHwcVirtualDisplays;
2379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    *outId = static_cast<int32_t>(displaySlot);
2389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return NO_ERROR;
240e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian}
241e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian
242d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven ThomasHWC2::Layer* HWComposer::createLayer(int32_t displayId) {
2439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
2449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Failed to create layer on invalid display %d", displayId);
2459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
246e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian    }
2479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto display = mDisplayData[displayId].hwcDisplay;
248d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    HWC2::Layer* layer;
2499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = display->createLayer(&layer);
2509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
2519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Failed to create layer on display %d: %s (%d)", displayId,
2529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
2539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
254e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian    }
2559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return layer;
256e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian}
257e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian
258d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomasvoid HWComposer::destroyLayer(int32_t displayId, HWC2::Layer* layer) {
259d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    if (!isValidDisplay(displayId)) {
260d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        ALOGE("Failed to destroy layer on invalid display %d", displayId);
261d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        return;
262d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    }
263d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    auto display = mDisplayData[displayId].hwcDisplay;
264d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    auto error = display->destroyLayer(layer);
265d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    if (error != HWC2::Error::None) {
266d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        ALOGE("Failed to destroy layer on display %d: %s (%d)", displayId,
267d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas                to_string(error).c_str(), static_cast<int32_t>(error));
268d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    }
269d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas}
270d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas
271df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglardnsecs_t HWComposer::getRefreshTimestamp(int32_t displayId) const {
272d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // this returns the last refresh timestamp.
273d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // if the last one is not available, we estimate it based on
274d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // the refresh period and whatever closest timestamp we have.
275d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    Mutex::Autolock _l(mLock);
276d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    nsecs_t now = systemTime(CLOCK_MONOTONIC);
277df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard    auto vsyncPeriod = getActiveConfig(displayId)->getVsyncPeriod();
278df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard    return now - ((now - mLastHwVSync[displayId]) % vsyncPeriod);
2792ec3e0748bff8d75baade2ddda9fbfa21a3b7d3fJamie Gennis}
2802ec3e0748bff8d75baade2ddda9fbfa21a3b7d3fJamie Gennis
281df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglardbool HWComposer::isConnected(int32_t displayId) const {
282df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard    if (!isValidDisplay(displayId)) {
283df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard        ALOGE("isConnected: Attempted to access invalid display %d", displayId);
2849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return false;
28519e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall    }
286df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard    return mDisplayData[displayId].hwcDisplay->isConnected();
2873eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian}
2883eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian
2899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastd::vector<std::shared_ptr<const HWC2::Display::Config>>
2909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        HWComposer::getConfigs(int32_t displayId) const {
2919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
2929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getConfigs: Attempted to access invalid display %d", displayId);
2939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return {};
2949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
2959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayData = mDisplayData[displayId];
2969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto configs = mDisplayData[displayId].hwcDisplay->getConfigs();
2979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayData.configMap.empty()) {
2989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (size_t i = 0; i < configs.size(); ++i) {
2999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayData.configMap[i] = configs[i];
3009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
3019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
3029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return configs;
3037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
3047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
3059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastd::shared_ptr<const HWC2::Display::Config>
3069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        HWComposer::getActiveConfig(int32_t displayId) const {
3079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
308b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard        ALOGV("getActiveConfigs: Attempted to access invalid display %d",
3099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId);
3109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
3119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
3129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    std::shared_ptr<const HWC2::Display::Config> config;
3139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = mDisplayData[displayId].hwcDisplay->getActiveConfig(&config);
3149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error == HWC2::Error::BadConfig) {
315b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard        ALOGE("getActiveConfig: No config active, returning null");
3169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
3179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else if (error != HWC2::Error::None) {
3189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getActiveConfig failed for display %d: %s (%d)", displayId,
3199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
3209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
3219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else if (!config) {
3229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getActiveConfig returned an unknown config for display %d",
3239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId);
3249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
3259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
3267f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
3279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return config;
328f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian}
329f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian
33028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstd::vector<android_color_mode_t> HWComposer::getColorModes(int32_t displayId) const {
33128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::vector<android_color_mode_t> modes;
332fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter
333fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    if (!isValidDisplay(displayId)) {
334fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter        ALOGE("getColorModes: Attempted to access invalid display %d",
335fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter                displayId);
336fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter        return modes;
337fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    }
338fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter
339d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    auto error = mDisplayData[displayId].hwcDisplay->getColorModes(&modes);
340fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    if (error != HWC2::Error::None) {
341fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter        ALOGE("getColorModes failed for display %d: %s (%d)", displayId,
342fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter                to_string(error).c_str(), static_cast<int32_t>(error));
34328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return std::vector<android_color_mode_t>();
344fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    }
345fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter
346fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    return modes;
347fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter}
348fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter
34928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t HWComposer::setActiveColorMode(int32_t displayId, android_color_mode_t mode) {
35028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (!isValidDisplay(displayId)) {
35128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGE("setActiveColorMode: Display %d is not valid", displayId);
35228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return BAD_INDEX;
35328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
35428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
35528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    auto& displayData = mDisplayData[displayId];
35628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    auto error = displayData.hwcDisplay->setColorMode(mode);
35728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (error != HWC2::Error::None) {
35828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGE("setActiveConfig: Failed to set color mode %d on display %d: "
35928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                "%s (%d)", mode, displayId, to_string(error).c_str(),
36028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                static_cast<int32_t>(error));
36128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return UNKNOWN_ERROR;
36228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
36328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
36428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
36528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
36628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
36728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
368df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglardvoid HWComposer::setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled) {
369df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard    if (displayId < 0 || displayId >= HWC_DISPLAY_VIRTUAL) {
370df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard        ALOGD("setVsyncEnabled: Ignoring for virtual display %d", displayId);
371620685c2e684082c82657732d1e35cefd0c79006Andy McFadden        return;
372620685c2e684082c82657732d1e35cefd0c79006Andy McFadden    }
3739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
374df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard    if (!isValidDisplay(displayId)) {
375df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard        ALOGE("setVsyncEnabled: Attempted to access invalid display %d",
376df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard               displayId);
37781cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian        return;
37881cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian    }
3793a77871383bc1a03cc866686d81628493d14de7cMathias Agopian
3809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // NOTE: we use our own internal lock here because we have to call
3819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // into the HWC with the lock held, and we want to make sure
3829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // that even if HWC blocks (which it shouldn't), it won't
3839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // affect other threads.
3849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mVsyncLock);
385df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard    auto& displayData = mDisplayData[displayId];
3869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (enabled != displayData.vsyncEnabled) {
3879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ATRACE_CALL();
3889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
3899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (error == HWC2::Error::None) {
3909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayData.vsyncEnabled = enabled;
3919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
3929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            char tag[16];
393df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard            snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", displayId);
3949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ATRACE_INT(tag, enabled == HWC2::Vsync::Enable ? 1 : 0);
3959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        } else {
3969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("setVsyncEnabled: Failed to set vsync to %s on %d/%" PRIu64
397df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard                    ": %s (%d)", to_string(enabled).c_str(), displayId,
398df0b7059646db0734f614e0dd651e0ac6ce82211Fabien Sanglard                    mDisplayData[displayId].hwcDisplay->getId(),
3999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
4009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
4013a77871383bc1a03cc866686d81628493d14de7cMathias Agopian    }
40231d2843b45ebdb69ec3355111b7567363fd2a6b7Mathias Agopian}
40331d2843b45ebdb69ec3355111b7567363fd2a6b7Mathias Agopian
40406d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wustatus_t HWComposer::setClientTarget(int32_t displayId, uint32_t slot,
4059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
4069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        android_dataspace_t dataspace) {
4079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
4081e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian        return BAD_INDEX;
409e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian    }
4101e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian
4119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setClientTarget for display %d", displayId);
4129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
4131f42e3a02c4f9a1ba1916a2f0e47082bedb73e41Daniel Nicoara    auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
4149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
4159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Failed to set client target for display %d: %s (%d)", displayId,
4169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
4179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_VALUE;
4189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
4199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
420a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    return NO_ERROR;
421a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
422a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
4239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::prepare(DisplayDevice& displayDevice) {
4249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
4259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mDisplayLock);
4279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto displayId = displayDevice.getHwcDisplayId();
428ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
429ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        ALOGV("Skipping HWComposer prepare for non-HWC display");
430ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        return NO_ERROR;
431ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    }
4329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
433da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        return BAD_INDEX;
434da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
4359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayData = mDisplayData[displayId];
4379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcDisplay = displayData.hwcDisplay;
4389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!hwcDisplay->isConnected()) {
439da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        return NO_ERROR;
440da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
441da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
4429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    uint32_t numTypes = 0;
4439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    uint32_t numRequests = 0;
444249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard
445249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard    HWC2::Error error = HWC2::Error::None;
446249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard
447249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard    // First try to skip validate altogether if the HWC supports it.
448249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard    displayData.validateWasSkipped = false;
449269c2361096cb8a17ea5fedbd20f800cd1b65d05Fabien Sanglard    if (hasCapability(HWC2::Capability::SkipValidate) &&
450269c2361096cb8a17ea5fedbd20f800cd1b65d05Fabien Sanglard            !displayData.hasClientComposition) {
451249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        sp<android::Fence> outPresentFence;
452249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        uint32_t state = UINT32_MAX;
453249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
454249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        if (error != HWC2::Error::None && error != HWC2::Error::HasChanges) {
455249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard            ALOGV("skipValidate: Failed to Present or Validate");
456249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard            return UNKNOWN_ERROR;
457249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        }
458249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        if (state == 1) { //Present Succeeded.
459d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas            std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
460249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard            error = hwcDisplay->getReleaseFences(&releaseFences);
461249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard            displayData.releaseFences = std::move(releaseFences);
462249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard            displayData.lastPresentFence = outPresentFence;
463249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard            displayData.validateWasSkipped = true;
464249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard            displayData.presentError = error;
465249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard            return NO_ERROR;
466249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        }
467249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        // Present failed but Validate ran.
468249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard    } else {
469249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        error = hwcDisplay->validate(&numTypes, &numRequests);
470249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard    }
471249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard    ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
4729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None && error != HWC2::Error::HasChanges) {
4739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("prepare: validate failed for display %d: %s (%d)", displayId,
4749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
4759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
476da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
477da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
478d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    std::unordered_map<HWC2::Layer*, HWC2::Composition> changedTypes;
4799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    changedTypes.reserve(numTypes);
4809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
4819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
4829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("prepare: getChangedCompositionTypes failed on display %d: "
4839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                "%s (%d)", displayId, to_string(error).c_str(),
4849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                static_cast<int32_t>(error));
4859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
4869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
487da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
4889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0);
490d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    std::unordered_map<HWC2::Layer*, HWC2::LayerRequest> layerRequests;
4919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    layerRequests.reserve(numRequests);
4929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcDisplay->getRequests(&displayData.displayRequests,
4939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            &layerRequests);
4949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
4959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("prepare: getRequests failed on display %d: %s (%d)", displayId,
4969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
4979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
498f435863467ab407f2a482604beed5fa6f0144c62Mathias Agopian    }
499db27621e22559a1b16414f890677ef04242fbc3bJesse Hall
5009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    displayData.hasClientComposition = false;
5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    displayData.hasDeviceComposition = false;
5029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : displayDevice.getVisibleLayersSortedByZ()) {
5039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto hwcLayer = layer->getHwcLayer(displayId);
5049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (changedTypes.count(hwcLayer) != 0) {
5069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // We pass false so we only update our state and don't call back
5079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // into the HWC device
5089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            validateChange(layer->getCompositionType(displayId),
5099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    changedTypes[hwcLayer]);
5109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setCompositionType(displayId, changedTypes[hwcLayer], false);
5119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
5129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        switch (layer->getCompositionType(displayId)) {
5149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            case HWC2::Composition::Client:
5159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayData.hasClientComposition = true;
5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                break;
5179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            case HWC2::Composition::Device:
5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            case HWC2::Composition::SolidColor:
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            case HWC2::Composition::Cursor:
5209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            case HWC2::Composition::Sideband:
5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayData.hasDeviceComposition = true;
5229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                break;
5239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            default:
5249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                break;
5259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
5269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (layerRequests.count(hwcLayer) != 0 &&
5289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                layerRequests[hwcLayer] ==
5299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        HWC2::LayerRequest::ClearClientTarget) {
5309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setClearClientTarget(displayId, true);
5319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        } else {
5329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layerRequests.count(hwcLayer) != 0) {
5339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGE("prepare: Unknown layer request: %s",
5349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        to_string(layerRequests[hwcLayer]).c_str());
5359c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            }
5369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setClearClientTarget(displayId, false);
5379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        }
5389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    }
5399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcDisplay->acceptChanges();
5419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
5429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("prepare: acceptChanges failed: %s", to_string(error).c_str());
5439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
5449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return NO_ERROR;
547a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
548a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
5499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool HWComposer::hasDeviceComposition(int32_t displayId) const {
550ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
551ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        // Displays without a corresponding HWC display are never composed by
552ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        // the device
553ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        return false;
554ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    }
5559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
5569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("hasDeviceComposition: Invalid display %d", displayId);
557e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        return false;
5589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mDisplayData[displayId].hasDeviceComposition;
560e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian}
5615f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
5629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool HWComposer::hasClientComposition(int32_t displayId) const {
563ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
564ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        // Displays without a corresponding HWC display are always composed by
565ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        // the client
566ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza        return true;
567ec0f717dfd3821cbc648198c6d3b98fcc3b53369Dan Stoza    }
5689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
5699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("hasClientComposition: Invalid display %d", displayId);
57099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall        return true;
5719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mDisplayData[displayId].hasClientComposition;
5739c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian}
5749c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian
57511d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglardsp<Fence> HWComposer::getPresentFence(int32_t displayId) const {
5769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
57711d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard        ALOGE("getPresentFence failed for invalid display %d", displayId);
57813f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        return Fence::NO_FENCE;
579da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
58011d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard    return mDisplayData[displayId].lastPresentFence;
581da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
582da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
5839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozasp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId,
584d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas        HWC2::Layer* layer) const {
5859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
5869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getLayerReleaseFence: Invalid display");
5879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return Fence::NO_FENCE;
5889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto displayFences = mDisplayData[displayId].releaseFences;
5909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayFences.count(layer) == 0) {
5919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("getLayerReleaseFence: Release fence not found");
5929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return Fence::NO_FENCE;
5939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return displayFences[layer];
5959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
59680e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall
597a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglardstatus_t HWComposer::presentAndGetReleaseFences(int32_t displayId) {
5989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
599f435863467ab407f2a482604beed5fa6f0144c62Mathias Agopian
6009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
6019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
60258959343dbdb6157fa5f5463262d4842b8954353Mathias Agopian    }
603a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
6049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayData = mDisplayData[displayId];
6059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcDisplay = displayData.hwcDisplay;
606249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard
607249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard    if (displayData.validateWasSkipped) {
6080c6ce4608fc022608537162dd919e7f729b9cb77Chia-I Wu        hwcDisplay->discardCommands();
609249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        auto error = displayData.presentError;
610249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        if (error != HWC2::Error::None) {
611249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard            ALOGE("skipValidate: failed for display %d: %s (%d)",
612249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard                  displayId, to_string(error).c_str(), static_cast<int32_t>(error));
613249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard            return UNKNOWN_ERROR;
614249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        }
615249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard        return NO_ERROR;
616249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard    }
617249c0ae80a6e5690d091294c4447cb3facafbc37Fabien Sanglard
61811d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard    auto error = hwcDisplay->present(&displayData.lastPresentFence);
6199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
620a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglard        ALOGE("presentAndGetReleaseFences: failed for display %d: %s (%d)",
621a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglard              displayId, to_string(error).c_str(), static_cast<int32_t>(error));
6229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return UNKNOWN_ERROR;
62310fbdb6059755f009e02f0ccc2b9d289beb6b086Colin Cross    }
62410fbdb6059755f009e02f0ccc2b9d289beb6b086Colin Cross
625d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
6269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcDisplay->getReleaseFences(&releaseFences);
6279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
628a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglard        ALOGE("presentAndGetReleaseFences: Failed to get release fences "
629a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglard              "for display %d: %s (%d)",
6309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId, to_string(error).c_str(),
6319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                static_cast<int32_t>(error));
6329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return UNKNOWN_ERROR;
6336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    displayData.releaseFences = std::move(releaseFences);
63627ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden
6379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return NO_ERROR;
638b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden}
639b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
6409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::setPowerMode(int32_t displayId, int32_t intMode) {
6419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setPowerMode(%d, %d)", displayId, intMode);
6429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
6439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setPowerMode: Bad display");
6449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
6459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayId >= VIRTUAL_DISPLAY_ID_BASE) {
6479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setPowerMode: Virtual display %d passed in, returning",
6489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId);
6499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
6509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
651da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
6529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto mode = static_cast<HWC2::PowerMode>(intMode);
6539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mode == HWC2::PowerMode::Off) {
6549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setVsyncEnabled(displayId, HWC2::Vsync::Disable);
655cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    }
656cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
6579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
6589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    switch (mode) {
6599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::PowerMode::Off:
6609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::PowerMode::On:
6619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
6629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            {
6639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto error = hwcDisplay->setPowerMode(mode);
6649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (error != HWC2::Error::None) {
6659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    ALOGE("setPowerMode: Unable to set power mode %s for "
6669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            "display %d: %s (%d)", to_string(mode).c_str(),
6679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            displayId, to_string(error).c_str(),
6689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            static_cast<int32_t>(error));
6699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                }
6709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
6719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
6729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::PowerMode::Doze:
6739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::PowerMode::DozeSuspend:
6749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
6759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            {
6769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                bool supportsDoze = false;
6779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto error = hwcDisplay->supportsDoze(&supportsDoze);
6789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (error != HWC2::Error::None) {
6799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    ALOGE("setPowerMode: Unable to query doze support for "
6809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            "display %d: %s (%d)", displayId,
6819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            to_string(error).c_str(),
6829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            static_cast<int32_t>(error));
6839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                }
6849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (!supportsDoze) {
6859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mode = HWC2::PowerMode::On;
6869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                }
687da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
6889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                error = hwcDisplay->setPowerMode(mode);
6899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (error != HWC2::Error::None) {
6909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    ALOGE("setPowerMode: Unable to set power mode %s for "
6919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            "display %d: %s (%d)", to_string(mode).c_str(),
6929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            displayId, to_string(error).c_str(),
6939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            static_cast<int32_t>(error));
6949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                }
6959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
6969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
6979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        default:
6989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("setPowerMode: Not calling HWC");
6999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
700b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    }
7019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return NO_ERROR;
703b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden}
704b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
7059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::setActiveConfig(int32_t displayId, size_t configId) {
7069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
7079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setActiveConfig: Display %d is not valid", displayId);
7089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
709b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    }
710b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
7119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayData = mDisplayData[displayId];
7129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayData.configMap.count(configId) == 0) {
7139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setActiveConfig: Invalid config %zd", configId);
714851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        return BAD_INDEX;
7159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
7169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = displayData.hwcDisplay->setActiveConfig(
7189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayData.configMap[configId]);
7199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setActiveConfig: Failed to set config %zu on display %d: "
7219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                "%s (%d)", configId, displayId, to_string(error).c_str(),
7229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                static_cast<int32_t>(error));
7239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return UNKNOWN_ERROR;
7249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
725851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall
726851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall    return NO_ERROR;
727851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall}
728851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall
7299f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stozastatus_t HWComposer::setColorTransform(int32_t displayId,
7309f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        const mat4& transform) {
7319f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (!isValidDisplay(displayId)) {
7329f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        ALOGE("setColorTransform: Display %d is not valid", displayId);
7339f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        return BAD_INDEX;
7349f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
7359f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
7369f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    auto& displayData = mDisplayData[displayId];
7379f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    bool isIdentity = transform == mat4();
7389f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    auto error = displayData.hwcDisplay->setColorTransform(transform,
7399f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY :
7409f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX);
7419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (error != HWC2::Error::None) {
7429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        ALOGE("setColorTransform: Failed to set transform on display %d: "
7439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                "%s (%d)", displayId, to_string(error).c_str(),
7449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                static_cast<int32_t>(error));
7459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        return UNKNOWN_ERROR;
7469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
7479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
7489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    return NO_ERROR;
7499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza}
7509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
7519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::disconnectDisplay(int displayId) {
7529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    LOG_ALWAYS_FATAL_IF(displayId < 0);
7539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayData = mDisplayData[displayId];
754851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall
7559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto displayType = HWC2::DisplayType::Invalid;
7569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = displayData.hwcDisplay->getType(&displayType);
7579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("disconnectDisplay: Failed to determine type of display %d",
7599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId);
7609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
76103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
7629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // If this was a virtual display, add its slot back for reuse by future
7649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // virtual displays
7659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayType == HWC2::DisplayType::Virtual) {
7669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mFreeDisplaySlots.insert(displayId);
7679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ++mRemainingHwcVirtualDisplays;
76803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
7699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayData.hwcDisplay->getId();
7719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcDisplaySlots.erase(hwcId);
7729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    displayData.reset();
773d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas
774d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    mHwcDevice->destroyDisplay(hwcId);
77503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
77603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
7779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::setOutputBuffer(int32_t displayId,
7789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
7799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
7809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setOutputBuffer: Display %d is not valid", displayId);
7819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
7823e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    }
7833e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
7849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
7859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto displayType = HWC2::DisplayType::Invalid;
7869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcDisplay->getType(&displayType);
7879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setOutputBuffer: Failed to determine type of display %d",
7899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId);
7909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return NAME_NOT_FOUND;
791c39736088398a9b4367b30fc307ed7de96ac342eMathias Agopian    }
792d814cf2a3e3a2fdb73efa80539fe8af0a93da1dbPablo Ceballos
7939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayType != HWC2::DisplayType::Virtual) {
7949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setOutputBuffer: Display %d is not virtual", displayId);
7959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return INVALID_OPERATION;
796f435863467ab407f2a482604beed5fa6f0144c62Mathias Agopian    }
7979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcDisplay->setOutputBuffer(buffer, acquireFence);
7999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
8009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setOutputBuffer: Failed to set buffer on display %d: %s (%d)",
8019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId, to_string(error).c_str(),
8029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                static_cast<int32_t>(error));
8039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return UNKNOWN_ERROR;
804f435863467ab407f2a482604beed5fa6f0144c62Mathias Agopian    }
8053e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
8069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return NO_ERROR;
807a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
808a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
8099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::clearReleaseFences(int32_t displayId) {
8109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
8119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("clearReleaseFences: Display %d is not valid", displayId);
8129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
813da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
8149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mDisplayData[displayId].releaseFences.clear();
8153e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian}
8163e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
817c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastd::unique_ptr<HdrCapabilities> HWComposer::getHdrCapabilities(
818c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        int32_t displayId) {
819c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (!isValidDisplay(displayId)) {
820c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getHdrCapabilities: Display %d is not valid", displayId);
821c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return nullptr;
822c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
823c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
824c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
825c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    std::unique_ptr<HdrCapabilities> capabilities;
826c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    auto error = hwcDisplay->getHdrCapabilities(&capabilities);
827c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (error != HWC2::Error::None) {
828c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getOutputCapabilities: Failed to get capabilities on display %d:"
829c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza                " %s (%d)", displayId, to_string(error).c_str(),
830c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza                static_cast<int32_t>(error));
831c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return nullptr;
832c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
833c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
834c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    return capabilities;
835c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza}
836c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
8374df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden// Converts a PixelFormat to a human-readable string.  Max 11 chars.
8384df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden// (Could use a table of prefab String8 objects.)
8399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza/*
8404df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFaddenstatic String8 getFormatStr(PixelFormat format) {
8414df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    switch (format) {
8424df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    case PIXEL_FORMAT_RGBA_8888:    return String8("RGBA_8888");
8434df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    case PIXEL_FORMAT_RGBX_8888:    return String8("RGBx_8888");
8444df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    case PIXEL_FORMAT_RGB_888:      return String8("RGB_888");
8454df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    case PIXEL_FORMAT_RGB_565:      return String8("RGB_565");
8464df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    case PIXEL_FORMAT_BGRA_8888:    return String8("BGRA_8888");
847f0058ca0e592485ac9e5a4aedb0dd8fa187625efAndy McFadden    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
848f0058ca0e592485ac9e5a4aedb0dd8fa187625efAndy McFadden                                    return String8("ImplDef");
8494df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    default:
8504df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden        String8 result;
8514df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden        result.appendFormat("? %08x", format);
8524df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden        return result;
8534df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    }
8544df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden}
8559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza*/
8564df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden
85787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaarbool HWComposer::isUsingVrComposer() const {
85887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    return getComposer()->isUsingVrComposer();
85987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar}
86087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
86174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid HWComposer::dump(String8& result) const {
8629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // TODO: In order to provide a dump equivalent to HWC1, we need to shadow
8639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // all the state going into the layers. This is probably better done in
8649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Layer itself, but it's going to take a bit of work to get there.
8659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    result.append(mHwcDevice->dump().c_str());
8668372785879d329f592f6883620b5a32d80d74691Mathias Agopian}
8678372785879d329f592f6883620b5a32d80d74691Mathias Agopian
868a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian// ---------------------------------------------------------------------------
8692965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian
8709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWComposer::DisplayData::DisplayData()
8719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza  : hasClientComposition(false),
8729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    hasDeviceComposition(false),
873d7f49c5e93a554c2f0e85e279a765f92fb1e66f1Steven Thomas    hwcDisplay(nullptr),
87411d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard    lastPresentFence(Fence::NO_FENCE),
8759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    outbufHandle(nullptr),
8769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    outbufAcquireFence(Fence::NO_FENCE),
8779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    vsyncEnabled(HWC2::Vsync::Disable) {
8789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Created new DisplayData");
8792965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian}
8802965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian
8819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWComposer::DisplayData::~DisplayData() {
8822965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian}
8832965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian
8849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::DisplayData::reset() {
8859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("DisplayData reset");
8869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    *this = DisplayData();
887a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall}
888a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall
8892965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian// ---------------------------------------------------------------------------
890a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}; // namespace android
891