HWComposer.cpp revision 9f26a9c8be6f00f55cbc30b93adf4895c6a093aa
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
46a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include <cutils/log.h>
47e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian#include <cutils/properties.h>
48a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
49a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "HWComposer.h"
509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#include "HWC2On1Adapter.h"
519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza#include "HWC2.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
629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWComposer::HWComposer(const sp<SurfaceFlinger>& flinger)
63c7d14e247117392fbd44aa454622778a25c076aeMathias Agopian    : mFlinger(flinger),
649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mAdapter(),
659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mHwcDevice(),
669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mDisplayData(2),
679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mFreeDisplaySlots(),
689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mHwcDisplaySlots(),
699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mCBContext(),
709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mEventHandler(nullptr),
719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mVSyncCounts(),
729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza      mRemainingHwcVirtualDisplays(0)
73a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
74bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian    for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {
75bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian        mLastHwVSync[i] = 0;
76bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian        mVSyncCounts[i] = 0;
77bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian    }
78bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian
79b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    loadHwcModule();
809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
81bbd164a3c790a0649dffd2f015e6f47692c72e1cJesse Hall
829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWComposer::~HWComposer() {}
83b685c542836b93c99cd85053e07696406ea37adbJesse Hall
849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::setEventHandler(EventHandler* handler)
859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza{
869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (handler == nullptr) {
879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setEventHandler: Rejected attempt to clear handler");
889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
893a77871383bc1a03cc866686d81628493d14de7cMathias Agopian    }
903a77871383bc1a03cc866686d81628493d14de7cMathias Agopian
919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    bool wasNull = (mEventHandler == nullptr);
929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mEventHandler = handler;
93888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian
949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (wasNull) {
959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto hotplugHook = std::bind(&HWComposer::hotplug, this,
969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                std::placeholders::_1, std::placeholders::_2);
979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mHwcDevice->registerHotplugCallback(hotplugHook);
989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto invalidateHook = std::bind(&HWComposer::invalidate, this,
999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                std::placeholders::_1);
1009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mHwcDevice->registerRefreshCallback(invalidateHook);
1019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto vsyncHook = std::bind(&HWComposer::vsync, this,
1029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                std::placeholders::_1, std::placeholders::_2);
1039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mHwcDevice->registerVsyncCallback(vsyncHook);
104a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
105a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
106a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
107b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden// Load and prepare the hardware composer module.  Sets mHwc.
108b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFaddenvoid HWComposer::loadHwcModule()
109b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden{
1109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("loadHwcModule");
1119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
112b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    hw_module_t const* module;
113b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
114b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
1159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("%s module not found, aborting", HWC_HARDWARE_MODULE_ID);
1169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        abort();
117b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    }
118b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
119355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza    hw_device_t* device = nullptr;
120355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza    int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
121355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza    if (error != 0) {
122355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza        ALOGE("Failed to open HWC device (%s), aborting", strerror(-error));
123355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza        abort();
124355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza    }
125355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza
126355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza    uint32_t majorVersion = (device->version >> 24) & 0xF;
127355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza    if (majorVersion == 2) {
128355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza        mHwcDevice = std::make_unique<HWC2::Device>(
129355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza                reinterpret_cast<hwc2_device_t*>(device));
1309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
131355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza        mAdapter = std::make_unique<HWC2On1Adapter>(
132355f60461b1ec4f0035fcb5e73d36e662352cd18Dan Stoza                reinterpret_cast<hwc_composer_device_1_t*>(device));
1339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        uint8_t minorVersion = mAdapter->getHwc1MinorVersion();
1349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (minorVersion < 1) {
1359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("Cannot adapt to HWC version %d.%d",
1369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    static_cast<int32_t>((minorVersion >> 8) & 0xF),
1379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    static_cast<int32_t>(minorVersion & 0xF));
1389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            abort();
1399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
1409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mHwcDevice = std::make_unique<HWC2::Device>(
1419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                static_cast<hwc2_device_t*>(mAdapter.get()));
1429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mRemainingHwcVirtualDisplays = mHwcDevice->getMaxVirtualDisplayCount();
1459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
1469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stozabool HWComposer::hasCapability(HWC2::Capability capability) const
1489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza{
1499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    return mHwcDevice->getCapabilities().count(capability) > 0;
1509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza}
1519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
1529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool HWComposer::isValidDisplay(int32_t displayId) const {
1539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return static_cast<size_t>(displayId) < mDisplayData.size() &&
1549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mDisplayData[displayId].hwcDisplay;
1559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
1569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::validateChange(HWC2::Composition from, HWC2::Composition to) {
1589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    bool valid = true;
1599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    switch (from) {
1609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::Composition::Client:
1619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            valid = false;
1629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
1639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::Composition::Device:
1649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::Composition::SolidColor:
1659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            valid = (to == HWC2::Composition::Client);
1669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
1679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::Composition::Cursor:
1689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::Composition::Sideband:
1699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            valid = (to == HWC2::Composition::Client ||
1709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to == HWC2::Composition::Device);
1719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
1729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        default:
1739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
1749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!valid) {
1779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Invalid layer type change: %s --> %s", to_string(from).c_str(),
1789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(to).c_str());
1799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
1819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::hotplug(const std::shared_ptr<HWC2::Display>& display,
1839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        HWC2::Connection connected) {
1849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("hotplug: %" PRIu64 ", %s", display->getId(),
1859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            to_string(connected).c_str());
1869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    int32_t disp = 0;
1879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!mDisplayData[0].hwcDisplay) {
1889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(connected != HWC2::Connection::Connected, "Assumed primary"
1899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " display would be connected");
1909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mDisplayData[0].hwcDisplay = display;
1919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mHwcDisplaySlots[display->getId()] = 0;
1929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        disp = DisplayDevice::DISPLAY_PRIMARY;
1939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
1949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Disconnect is handled through HWComposer::disconnectDisplay via
1959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // SurfaceFlinger's onHotplugReceived callback handling
1969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (connected == HWC2::Connection::Connected) {
1979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mDisplayData[1].hwcDisplay = display;
1989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwcDisplaySlots[display->getId()] = 1;
1999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
2009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        disp = DisplayDevice::DISPLAY_EXTERNAL;
201b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    }
2029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mEventHandler->onHotplugReceived(disp,
2039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            connected == HWC2::Connection::Connected);
2041bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall}
2051bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall
2069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::invalidate(const std::shared_ptr<HWC2::Display>& /*display*/) {
207e2c2f9213f936f98db604dc9c126ff22f725a824Mathias Agopian    mFlinger->repaintEverything();
208c7d14e247117392fbd44aa454622778a25c076aeMathias Agopian}
209c7d14e247117392fbd44aa454622778a25c076aeMathias Agopian
2109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::vsync(const std::shared_ptr<HWC2::Display>& display,
2119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        int64_t timestamp) {
2129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto displayType = HWC2::DisplayType::Invalid;
2139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = display->getType(&displayType);
2149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
2159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("vsync: Failed to determine type of display %" PRIu64,
2169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                display->getId());
2179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
218bef42c50ebda2d63400f92611e1dd857c03bb38cMathias Agopian    }
219d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
2209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayType == HWC2::DisplayType::Virtual) {
2219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Virtual display %" PRIu64 " passed to vsync callback",
2229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                display->getId());
2231bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall        return;
2241bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall    }
2251bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall
2269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mHwcDisplaySlots.count(display->getId()) == 0) {
2279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback",
2289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                display->getId());
2299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
2301bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall    }
2311bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall
2329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    int32_t disp = mHwcDisplaySlots[display->getId()];
2339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    {
2349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock _l(mLock);
2351604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
2369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // There have been reports of HWCs that signal several vsync events
2379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // with the same timestamp when turning the display off and on. This
2389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // is a bug in the HWC implementation, but filter the extra events
2399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // out here so they don't cause havoc downstream.
2409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (timestamp == mLastHwVSync[disp]) {
2419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
2429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    timestamp);
2439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            return;
2441bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall        }
2457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
2469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mLastHwVSync[disp] = timestamp;
2471bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall    }
2481bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall
2499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    char tag[16];
2509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
2519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
2529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mEventHandler->onVSyncReceived(disp, timestamp);
2541bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall}
2551bd20e0f9ecd27cc5ad2bdf08b01837ecc10c357Jesse Hall
2569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
2575cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza        android_pixel_format_t* format, int32_t *outId) {
2589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mRemainingHwcVirtualDisplays == 0) {
2599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("allocateVirtualDisplay: No remaining virtual displays");
2609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return NO_MEMORY;
2611c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall    }
2621c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall
2639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    std::shared_ptr<HWC2::Display> display;
2645cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza    auto error = mHwcDevice->createVirtualDisplay(width, height, format,
2655cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza            &display);
2669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
2679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("allocateVirtualDisplay: Failed to create HWC virtual display");
2689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return NO_MEMORY;
2699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
2709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    size_t displaySlot = 0;
2729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!mFreeDisplaySlots.empty()) {
2739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        displaySlot = *mFreeDisplaySlots.begin();
2749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mFreeDisplaySlots.erase(displaySlot);
2759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else if (mDisplayData.size() < INT32_MAX) {
2769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Don't bother allocating a slot larger than we can return
2779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        displaySlot = mDisplayData.size();
2789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mDisplayData.resize(displaySlot + 1);
2799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
2809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("allocateVirtualDisplay: Unable to allocate a display slot");
281e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        return NO_MEMORY;
282e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian    }
2839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mDisplayData[displaySlot].hwcDisplay = display;
2859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    --mRemainingHwcVirtualDisplays;
2879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    *outId = static_cast<int32_t>(displaySlot);
2889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return NO_ERROR;
290e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian}
291e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian
2929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastd::shared_ptr<HWC2::Layer> HWComposer::createLayer(int32_t displayId) {
2939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
2949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Failed to create layer on invalid display %d", displayId);
2959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
296e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian    }
2979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto display = mDisplayData[displayId].hwcDisplay;
2989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    std::shared_ptr<HWC2::Layer> layer;
2999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = display->createLayer(&layer);
3009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
3019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Failed to create layer on display %d: %s (%d)", displayId,
3029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
3039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
304e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian    }
3059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return layer;
306e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian}
307e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian
3089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozansecs_t HWComposer::getRefreshTimestamp(int32_t disp) const {
309d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // this returns the last refresh timestamp.
310d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // if the last one is not available, we estimate it based on
311d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // the refresh period and whatever closest timestamp we have.
312d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    Mutex::Autolock _l(mLock);
313d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    nsecs_t now = systemTime(CLOCK_MONOTONIC);
3149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto vsyncPeriod = getActiveConfig(disp)->getVsyncPeriod();
3159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return now - ((now - mLastHwVSync[disp]) % vsyncPeriod);
3162ec3e0748bff8d75baade2ddda9fbfa21a3b7d3fJamie Gennis}
3172ec3e0748bff8d75baade2ddda9fbfa21a3b7d3fJamie Gennis
3189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool HWComposer::isConnected(int32_t disp) const {
3199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(disp)) {
3209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("isConnected: Attempted to access invalid display %d", disp);
3219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return false;
32219e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall    }
3239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mDisplayData[disp].hwcDisplay->isConnected();
3243eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian}
3253eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian
3269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastd::vector<std::shared_ptr<const HWC2::Display::Config>>
3279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        HWComposer::getConfigs(int32_t displayId) const {
3289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
3299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getConfigs: Attempted to access invalid display %d", displayId);
3309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return {};
3319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
3329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayData = mDisplayData[displayId];
3339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto configs = mDisplayData[displayId].hwcDisplay->getConfigs();
3349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayData.configMap.empty()) {
3359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (size_t i = 0; i < configs.size(); ++i) {
3369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayData.configMap[i] = configs[i];
3379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
3389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
3399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return configs;
3407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
3417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
3429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastd::shared_ptr<const HWC2::Display::Config>
3439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        HWComposer::getActiveConfig(int32_t displayId) const {
3449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
3459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getActiveConfigs: Attempted to access invalid display %d",
3469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId);
3479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
3489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
3499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    std::shared_ptr<const HWC2::Display::Config> config;
3509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = mDisplayData[displayId].hwcDisplay->getActiveConfig(&config);
3519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error == HWC2::Error::BadConfig) {
3529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("getActiveConfig: No config active, returning null");
3539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
3549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else if (error != HWC2::Error::None) {
3559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getActiveConfig failed for display %d: %s (%d)", displayId,
3569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
3579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
3589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else if (!config) {
3599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getActiveConfig returned an unknown config for display %d",
3609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId);
3619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return nullptr;
3629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
3637f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
3649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return config;
365f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian}
366f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian
367fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchterstd::vector<int32_t> HWComposer::getColorModes(int32_t displayId) const {
368fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    std::vector<int32_t> modes;
369fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter
370fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    if (!isValidDisplay(displayId)) {
371fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter        ALOGE("getColorModes: Attempted to access invalid display %d",
372fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter                displayId);
373fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter        return modes;
374fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    }
375fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    const std::shared_ptr<HWC2::Display>& hwcDisplay =
376fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter            mDisplayData[displayId].hwcDisplay;
377fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter
378fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    auto error = hwcDisplay->getColorModes(&modes);
379fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    if (error != HWC2::Error::None) {
380fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter        ALOGE("getColorModes failed for display %d: %s (%d)", displayId,
381fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter                to_string(error).c_str(), static_cast<int32_t>(error));
382fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter        return std::vector<int32_t>();
383fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    }
384fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter
385fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter    return modes;
386fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter}
387fad9d8cd070e94749d8eb5be8f92011c9567a44cCourtney Goeltzenleuchter
3889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::setVsyncEnabled(int32_t disp, HWC2::Vsync enabled) {
3899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (disp < 0 || disp >= HWC_DISPLAY_VIRTUAL) {
3909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGD("setVsyncEnabled: Ignoring for virtual display %d", disp);
391620685c2e684082c82657732d1e35cefd0c79006Andy McFadden        return;
392620685c2e684082c82657732d1e35cefd0c79006Andy McFadden    }
3939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
3949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(disp)) {
3959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setVsyncEnabled: Attempted to access invalid display %d", disp);
39681cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian        return;
39781cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian    }
3983a77871383bc1a03cc866686d81628493d14de7cMathias Agopian
3999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // NOTE: we use our own internal lock here because we have to call
4009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // into the HWC with the lock held, and we want to make sure
4019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // that even if HWC blocks (which it shouldn't), it won't
4029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // affect other threads.
4039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mVsyncLock);
4049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayData = mDisplayData[disp];
4059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (enabled != displayData.vsyncEnabled) {
4069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ATRACE_CALL();
4079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
4089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (error == HWC2::Error::None) {
4099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayData.vsyncEnabled = enabled;
4109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            char tag[16];
4129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", disp);
4139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ATRACE_INT(tag, enabled == HWC2::Vsync::Enable ? 1 : 0);
4149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        } else {
4159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("setVsyncEnabled: Failed to set vsync to %s on %d/%" PRIu64
4169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    ": %s (%d)", to_string(enabled).c_str(), disp,
4179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mDisplayData[disp].hwcDisplay->getId(),
4189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(error).c_str(), static_cast<int32_t>(error));
4199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
4203a77871383bc1a03cc866686d81628493d14de7cMathias Agopian    }
42131d2843b45ebdb69ec3355111b7567363fd2a6b7Mathias Agopian}
42231d2843b45ebdb69ec3355111b7567363fd2a6b7Mathias Agopian
4239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::setClientTarget(int32_t displayId,
4249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
4259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        android_dataspace_t dataspace) {
4269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
4271e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian        return BAD_INDEX;
428e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian    }
4291e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian
4309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setClientTarget for display %d", displayId);
4319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
4329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    buffer_handle_t handle = nullptr;
4339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if ((target != nullptr) && target->getNativeBuffer()) {
4349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        handle = target->getNativeBuffer()->handle;
435a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
4369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcDisplay->setClientTarget(handle, acquireFence, dataspace);
4379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
4389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("Failed to set client target for display %d: %s (%d)", displayId,
4399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
4409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_VALUE;
4419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
4429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
443a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    return NO_ERROR;
444a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
445a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
4469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::prepare(DisplayDevice& displayDevice) {
4479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
4489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mDisplayLock);
4509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto displayId = displayDevice.getHwcDisplayId();
4519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
452da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        return BAD_INDEX;
453da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
4549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayData = mDisplayData[displayId];
4569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcDisplay = displayData.hwcDisplay;
4579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!hwcDisplay->isConnected()) {
458da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        return NO_ERROR;
459da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
460da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
4619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    uint32_t numTypes = 0;
4629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    uint32_t numRequests = 0;
4639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcDisplay->validate(&numTypes, &numRequests);
4649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None && error != HWC2::Error::HasChanges) {
4659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("prepare: validate failed for display %d: %s (%d)", displayId,
4669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
4679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
468da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
469da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
4709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    std::unordered_map<std::shared_ptr<HWC2::Layer>, HWC2::Composition>
4719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        changedTypes;
4729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    changedTypes.reserve(numTypes);
4739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
4749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
4759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("prepare: getChangedCompositionTypes failed on display %d: "
4769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                "%s (%d)", displayId, to_string(error).c_str(),
4779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                static_cast<int32_t>(error));
4789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
4799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
480da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
4819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0);
4839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    std::unordered_map<std::shared_ptr<HWC2::Layer>, HWC2::LayerRequest>
4849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        layerRequests;
4859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    layerRequests.reserve(numRequests);
4869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcDisplay->getRequests(&displayData.displayRequests,
4879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            &layerRequests);
4889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
4899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("prepare: getRequests failed on display %d: %s (%d)", displayId,
4909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
4919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
492f435863467ab407f2a482604beed5fa6f0144c62Mathias Agopian    }
493db27621e22559a1b16414f890677ef04242fbc3bJesse Hall
4949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    displayData.hasClientComposition = false;
4959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    displayData.hasDeviceComposition = false;
4969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : displayDevice.getVisibleLayersSortedByZ()) {
4979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto hwcLayer = layer->getHwcLayer(displayId);
4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (changedTypes.count(hwcLayer) != 0) {
5009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // We pass false so we only update our state and don't call back
5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // into the HWC device
5029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            validateChange(layer->getCompositionType(displayId),
5039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    changedTypes[hwcLayer]);
5049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setCompositionType(displayId, changedTypes[hwcLayer], false);
5059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
5069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        switch (layer->getCompositionType(displayId)) {
5089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            case HWC2::Composition::Client:
5099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayData.hasClientComposition = true;
5109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                break;
5119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            case HWC2::Composition::Device:
5129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            case HWC2::Composition::SolidColor:
5139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            case HWC2::Composition::Cursor:
5149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            case HWC2::Composition::Sideband:
5159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayData.hasDeviceComposition = true;
5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                break;
5179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            default:
5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                break;
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
5209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (layerRequests.count(hwcLayer) != 0 &&
5229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                layerRequests[hwcLayer] ==
5239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        HWC2::LayerRequest::ClearClientTarget) {
5249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setClearClientTarget(displayId, true);
5259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        } else {
5269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layerRequests.count(hwcLayer) != 0) {
5279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGE("prepare: Unknown layer request: %s",
5289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        to_string(layerRequests[hwcLayer]).c_str());
5299c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian            }
5309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setClearClientTarget(displayId, false);
5319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        }
5329c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    }
5339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcDisplay->acceptChanges();
5359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
5369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("prepare: acceptChanges failed: %s", to_string(error).c_str());
5379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
5389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return NO_ERROR;
541a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
542a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
5439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool HWComposer::hasDeviceComposition(int32_t displayId) const {
5449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
5459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("hasDeviceComposition: Invalid display %d", displayId);
546e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        return false;
5479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mDisplayData[displayId].hasDeviceComposition;
549e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian}
5505f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
5519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool HWComposer::hasClientComposition(int32_t displayId) const {
5529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
5539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("hasClientComposition: Invalid display %d", displayId);
55499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall        return true;
5559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mDisplayData[displayId].hasClientComposition;
5579c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian}
5589c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian
5599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozasp<Fence> HWComposer::getRetireFence(int32_t displayId) const {
5609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
5619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getRetireFence failed for invalid display %d", displayId);
56213f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        return Fence::NO_FENCE;
563da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
5649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return mDisplayData[displayId].lastRetireFence;
565da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
566da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
5679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozasp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId,
5689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const std::shared_ptr<HWC2::Layer>& layer) const {
5699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
5709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("getLayerReleaseFence: Invalid display");
5719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return Fence::NO_FENCE;
5729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto displayFences = mDisplayData[displayId].releaseFences;
5749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayFences.count(layer) == 0) {
5759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("getLayerReleaseFence: Release fence not found");
5769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return Fence::NO_FENCE;
5779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
5789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return displayFences[layer];
5799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza}
58080e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall
5819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::commit(int32_t displayId) {
5829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
583f435863467ab407f2a482604beed5fa6f0144c62Mathias Agopian
5849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
5859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
58658959343dbdb6157fa5f5463262d4842b8954353Mathias Agopian    }
587a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
5889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayData = mDisplayData[displayId];
5899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcDisplay = displayData.hwcDisplay;
5909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcDisplay->present(&displayData.lastRetireFence);
5919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
5929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("commit: present failed for display %d: %s (%d)", displayId,
5939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                to_string(error).c_str(), static_cast<int32_t>(error));
5949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return UNKNOWN_ERROR;
59510fbdb6059755f009e02f0ccc2b9d289beb6b086Colin Cross    }
59610fbdb6059755f009e02f0ccc2b9d289beb6b086Colin Cross
5979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    std::unordered_map<std::shared_ptr<HWC2::Layer>, sp<Fence>> releaseFences;
5989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcDisplay->getReleaseFences(&releaseFences);
5999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
6009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("commit: Failed to get release fences for display %d: %s (%d)",
6019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId, to_string(error).c_str(),
6029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                static_cast<int32_t>(error));
6039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return UNKNOWN_ERROR;
6046c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6056c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    displayData.releaseFences = std::move(releaseFences);
60727ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden
6089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return NO_ERROR;
609b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden}
610b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
6119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::setPowerMode(int32_t displayId, int32_t intMode) {
6129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setPowerMode(%d, %d)", displayId, intMode);
6139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
6149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setPowerMode: Bad display");
6159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
6169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayId >= VIRTUAL_DISPLAY_ID_BASE) {
6189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setPowerMode: Virtual display %d passed in, returning",
6199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId);
6209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
6219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
622da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
6239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto mode = static_cast<HWC2::PowerMode>(intMode);
6249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (mode == HWC2::PowerMode::Off) {
6259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        setVsyncEnabled(displayId, HWC2::Vsync::Disable);
626cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    }
627cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
6289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
6299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    switch (mode) {
6309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::PowerMode::Off:
6319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::PowerMode::On:
6329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
6339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            {
6349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto error = hwcDisplay->setPowerMode(mode);
6359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (error != HWC2::Error::None) {
6369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    ALOGE("setPowerMode: Unable to set power mode %s for "
6379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            "display %d: %s (%d)", to_string(mode).c_str(),
6389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            displayId, to_string(error).c_str(),
6399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            static_cast<int32_t>(error));
6409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                }
6419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
6429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
6439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::PowerMode::Doze:
6449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        case HWC2::PowerMode::DozeSuspend:
6459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
6469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            {
6479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                bool supportsDoze = false;
6489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto error = hwcDisplay->supportsDoze(&supportsDoze);
6499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (error != HWC2::Error::None) {
6509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    ALOGE("setPowerMode: Unable to query doze support for "
6519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            "display %d: %s (%d)", displayId,
6529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            to_string(error).c_str(),
6539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            static_cast<int32_t>(error));
6549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                }
6559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (!supportsDoze) {
6569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mode = HWC2::PowerMode::On;
6579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                }
658da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
6599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                error = hwcDisplay->setPowerMode(mode);
6609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (error != HWC2::Error::None) {
6619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    ALOGE("setPowerMode: Unable to set power mode %s for "
6629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            "display %d: %s (%d)", to_string(mode).c_str(),
6639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            displayId, to_string(error).c_str(),
6649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            static_cast<int32_t>(error));
6659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                }
6669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            }
6679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
6689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        default:
6699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("setPowerMode: Not calling HWC");
6709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            break;
671b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    }
6729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return NO_ERROR;
674b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden}
675b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
6769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::setActiveConfig(int32_t displayId, size_t configId) {
6779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
6789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setActiveConfig: Display %d is not valid", displayId);
6799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
680b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    }
681b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
6829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayData = mDisplayData[displayId];
6839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayData.configMap.count(configId) == 0) {
6849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setActiveConfig: Invalid config %zd", configId);
685851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        return BAD_INDEX;
6869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
6879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
6889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = displayData.hwcDisplay->setActiveConfig(
6899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayData.configMap[configId]);
6909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
6919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setActiveConfig: Failed to set config %zu on display %d: "
6929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                "%s (%d)", configId, displayId, to_string(error).c_str(),
6939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                static_cast<int32_t>(error));
6949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return UNKNOWN_ERROR;
6959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
696851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall
697851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall    return NO_ERROR;
698851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall}
699851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall
7009f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stozastatus_t HWComposer::setColorTransform(int32_t displayId,
7019f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        const mat4& transform) {
7029f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (!isValidDisplay(displayId)) {
7039f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        ALOGE("setColorTransform: Display %d is not valid", displayId);
7049f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        return BAD_INDEX;
7059f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
7069f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
7079f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    auto& displayData = mDisplayData[displayId];
7089f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    bool isIdentity = transform == mat4();
7099f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    auto error = displayData.hwcDisplay->setColorTransform(transform,
7109f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY :
7119f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX);
7129f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (error != HWC2::Error::None) {
7139f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        ALOGE("setColorTransform: Failed to set transform on display %d: "
7149f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                "%s (%d)", displayId, to_string(error).c_str(),
7159f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                static_cast<int32_t>(error));
7169f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        return UNKNOWN_ERROR;
7179f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
7189f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
7199f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    return NO_ERROR;
7209f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza}
7219f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
7229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::disconnectDisplay(int displayId) {
7239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    LOG_ALWAYS_FATAL_IF(displayId < 0);
7249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& displayData = mDisplayData[displayId];
725851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall
7269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto displayType = HWC2::DisplayType::Invalid;
7279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = displayData.hwcDisplay->getType(&displayType);
7289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("disconnectDisplay: Failed to determine type of display %d",
7309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId);
7319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
73203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
7339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // If this was a virtual display, add its slot back for reuse by future
7359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // virtual displays
7369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayType == HWC2::DisplayType::Virtual) {
7379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mFreeDisplaySlots.insert(displayId);
7389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ++mRemainingHwcVirtualDisplays;
73903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
7409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto hwcId = displayData.hwcDisplay->getId();
7429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwcDisplaySlots.erase(hwcId);
7439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    displayData.reset();
74403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
74503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
7469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozastatus_t HWComposer::setOutputBuffer(int32_t displayId,
7479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
7489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
7499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setOutputBuffer: Display %d is not valid", displayId);
7509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return BAD_INDEX;
7513e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    }
7523e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
7539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
7549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto displayType = HWC2::DisplayType::Invalid;
7559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    auto error = hwcDisplay->getType(&displayType);
7569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setOutputBuffer: Failed to determine type of display %d",
7589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId);
7599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return NAME_NOT_FOUND;
760c39736088398a9b4367b30fc307ed7de96ac342eMathias Agopian    }
761d814cf2a3e3a2fdb73efa80539fe8af0a93da1dbPablo Ceballos
7629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (displayType != HWC2::DisplayType::Virtual) {
7639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setOutputBuffer: Display %d is not virtual", displayId);
7649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return INVALID_OPERATION;
765f435863467ab407f2a482604beed5fa6f0144c62Mathias Agopian    }
7669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
7679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    error = hwcDisplay->setOutputBuffer(buffer, acquireFence);
7689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (error != HWC2::Error::None) {
7699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("setOutputBuffer: Failed to set buffer on display %d: %s (%d)",
7709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                displayId, to_string(error).c_str(),
7719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                static_cast<int32_t>(error));
7729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return UNKNOWN_ERROR;
773f435863467ab407f2a482604beed5fa6f0144c62Mathias Agopian    }
7743e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
7759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return NO_ERROR;
776a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
777a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
7789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::clearReleaseFences(int32_t displayId) {
7799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (!isValidDisplay(displayId)) {
7809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE("clearReleaseFences: Display %d is not valid", displayId);
7819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        return;
782da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
7839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mDisplayData[displayId].releaseFences.clear();
7843e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian}
7853e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
786c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastd::unique_ptr<HdrCapabilities> HWComposer::getHdrCapabilities(
787c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        int32_t displayId) {
788c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (!isValidDisplay(displayId)) {
789c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getHdrCapabilities: Display %d is not valid", displayId);
790c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return nullptr;
791c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
792c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
793c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
794c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    std::unique_ptr<HdrCapabilities> capabilities;
795c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    auto error = hwcDisplay->getHdrCapabilities(&capabilities);
796c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (error != HWC2::Error::None) {
797c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getOutputCapabilities: Failed to get capabilities on display %d:"
798c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza                " %s (%d)", displayId, to_string(error).c_str(),
799c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza                static_cast<int32_t>(error));
800c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return nullptr;
801c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
802c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
803c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    return capabilities;
804c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza}
805c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
8064df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden// Converts a PixelFormat to a human-readable string.  Max 11 chars.
8074df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden// (Could use a table of prefab String8 objects.)
8089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza/*
8094df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFaddenstatic String8 getFormatStr(PixelFormat format) {
8104df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    switch (format) {
8114df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    case PIXEL_FORMAT_RGBA_8888:    return String8("RGBA_8888");
8124df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    case PIXEL_FORMAT_RGBX_8888:    return String8("RGBx_8888");
8134df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    case PIXEL_FORMAT_RGB_888:      return String8("RGB_888");
8144df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    case PIXEL_FORMAT_RGB_565:      return String8("RGB_565");
8154df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    case PIXEL_FORMAT_BGRA_8888:    return String8("BGRA_8888");
816f0058ca0e592485ac9e5a4aedb0dd8fa187625efAndy McFadden    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
817f0058ca0e592485ac9e5a4aedb0dd8fa187625efAndy McFadden                                    return String8("ImplDef");
8184df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    default:
8194df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden        String8 result;
8204df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden        result.appendFormat("? %08x", format);
8214df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden        return result;
8224df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden    }
8234df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden}
8249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza*/
8254df87bd1f6f68126e5e9081fc1365ae500e375dbAndy McFadden
82674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid HWComposer::dump(String8& result) const {
8279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // TODO: In order to provide a dump equivalent to HWC1, we need to shadow
8289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // all the state going into the layers. This is probably better done in
8299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Layer itself, but it's going to take a bit of work to get there.
8309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    result.append(mHwcDevice->dump().c_str());
8318372785879d329f592f6883620b5a32d80d74691Mathias Agopian}
8328372785879d329f592f6883620b5a32d80d74691Mathias Agopian
833a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian// ---------------------------------------------------------------------------
8342965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian
8359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWComposer::DisplayData::DisplayData()
8369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza  : hasClientComposition(false),
8379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    hasDeviceComposition(false),
8389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    hwcDisplay(),
8399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    lastRetireFence(Fence::NO_FENCE),
8409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    outbufHandle(nullptr),
8419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    outbufAcquireFence(Fence::NO_FENCE),
8429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    vsyncEnabled(HWC2::Vsync::Disable) {
8439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Created new DisplayData");
8442965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian}
8452965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian
8469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan StozaHWComposer::DisplayData::~DisplayData() {
8472965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian}
8482965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian
8499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid HWComposer::DisplayData::reset() {
8509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("DisplayData reset");
8519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    *this = DisplayData();
852a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall}
853a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall
8542965b26022f95051f65b09d7eac47cbe923855c9Mathias Agopian// ---------------------------------------------------------------------------
855a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}; // namespace android
856