Home | History | Annotate | Download | only in hwc2
      1 /*
      2  * Copyright 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "EmuHWC2.h"
     18 //#define LOG_NDEBUG 0
     19 //#define LOG_NNDEBUG 0
     20 #undef LOG_TAG
     21 #define LOG_TAG "EmuHWC2"
     22 
     23 #include <errno.h>
     24 #include <log/log.h>
     25 #include <sync/sync.h>
     26 
     27 #include <EGL/egl.h>
     28 #include <EGL/eglext.h>
     29 
     30 #include "../egl/goldfish_sync.h"
     31 
     32 #include "ThreadInfo.h"
     33 
     34 #if defined(LOG_NNDEBUG) && LOG_NNDEBUG == 0
     35 #define ALOGVV ALOGV
     36 #else
     37 #define ALOGVV(...) ((void)0)
     38 #endif
     39 
     40 template <typename PFN, typename T>
     41 static hwc2_function_pointer_t asFP(T function)
     42 {
     43     static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
     44     return reinterpret_cast<hwc2_function_pointer_t>(function);
     45 }
     46 
     47 static HostConnection *sHostCon = nullptr;
     48 
     49 static HostConnection* createOrGetHostConnection() {
     50     if (!sHostCon) {
     51         sHostCon = HostConnection::createUnique();
     52     }
     53     return sHostCon;
     54 }
     55 
     56 #define DEFINE_AND_VALIDATE_HOST_CONNECTION \
     57     HostConnection *hostCon = createOrGetHostConnection(); \
     58     if (!hostCon) { \
     59         ALOGE("EmuHWC2: Failed to get host connection\n"); \
     60         return Error::NoResources; \
     61     } \
     62     ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \
     63     if (!rcEnc) { \
     64         ALOGE("EmuHWC2: Failed to get renderControl encoder context\n"); \
     65         return Error::NoResources; \
     66     }
     67 
     68 
     69 using namespace HWC2;
     70 
     71 namespace android {
     72 
     73 EmuHWC2::EmuHWC2()
     74   : mStateMutex()
     75 {
     76     common.tag = HARDWARE_DEVICE_TAG;
     77     common.version = HWC_DEVICE_API_VERSION_2_0;
     78     common.close = closeHook;
     79     getCapabilities = getCapabilitiesHook;
     80     getFunction = getFunctionHook;
     81     populateCapabilities();
     82 }
     83 
     84 void EmuHWC2::doGetCapabilities(uint32_t* outCount, int32_t* outCapabilities) {
     85     if (outCapabilities == nullptr) {
     86         *outCount = mCapabilities.size();
     87         return;
     88     }
     89 
     90     auto capabilityIter = mCapabilities.cbegin();
     91     for (size_t i = 0; i < *outCount; ++i) {
     92         if (capabilityIter == mCapabilities.cend()) {
     93             return;
     94         }
     95         outCapabilities[i] = static_cast<int32_t>(*capabilityIter);
     96         ++capabilityIter;
     97     }
     98 }
     99 
    100 hwc2_function_pointer_t EmuHWC2::doGetFunction(
    101         FunctionDescriptor descriptor) {
    102     switch(descriptor) {
    103         case FunctionDescriptor::CreateVirtualDisplay:
    104             return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
    105                     createVirtualDisplayHook);
    106         case FunctionDescriptor::DestroyVirtualDisplay:
    107             return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
    108                     destroyVirtualDisplayHook);
    109         case FunctionDescriptor::Dump:
    110             return asFP<HWC2_PFN_DUMP>(dumpHook);
    111         case FunctionDescriptor::GetMaxVirtualDisplayCount:
    112             return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
    113                     getMaxVirtualDisplayCountHook);
    114         case FunctionDescriptor::RegisterCallback:
    115             return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
    116 
    117             // Display functions
    118         case FunctionDescriptor::AcceptDisplayChanges:
    119             return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
    120                     displayHook<decltype(&Display::acceptChanges),
    121                     &Display::acceptChanges>);
    122         case FunctionDescriptor::CreateLayer:
    123             return asFP<HWC2_PFN_CREATE_LAYER>(
    124                     displayHook<decltype(&Display::createLayer),
    125                     &Display::createLayer, hwc2_layer_t*>);
    126         case FunctionDescriptor::DestroyLayer:
    127             return asFP<HWC2_PFN_DESTROY_LAYER>(
    128                     displayHook<decltype(&Display::destroyLayer),
    129                     &Display::destroyLayer, hwc2_layer_t>);
    130         case FunctionDescriptor::GetActiveConfig:
    131             return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(
    132                     displayHook<decltype(&Display::getActiveConfig),
    133                     &Display::getActiveConfig, hwc2_config_t*>);
    134         case FunctionDescriptor::GetChangedCompositionTypes:
    135             return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
    136                     displayHook<decltype(&Display::getChangedCompositionTypes),
    137                     &Display::getChangedCompositionTypes, uint32_t*,
    138                     hwc2_layer_t*, int32_t*>);
    139         case FunctionDescriptor::GetColorModes:
    140             return asFP<HWC2_PFN_GET_COLOR_MODES>(
    141                     displayHook<decltype(&Display::getColorModes),
    142                     &Display::getColorModes, uint32_t*, int32_t*>);
    143         case FunctionDescriptor::GetDisplayAttribute:
    144             return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
    145                     displayHook<decltype(&Display::getDisplayAttribute),
    146                     &Display::getDisplayAttribute, hwc2_config_t,
    147                     int32_t, int32_t*>);
    148         case FunctionDescriptor::GetDisplayConfigs:
    149             return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(
    150                     displayHook<decltype(&Display::getConfigs),
    151                     &Display::getConfigs, uint32_t*, hwc2_config_t*>);
    152         case FunctionDescriptor::GetDisplayName:
    153             return asFP<HWC2_PFN_GET_DISPLAY_NAME>(
    154                     displayHook<decltype(&Display::getName),
    155                     &Display::getName, uint32_t*, char*>);
    156         case FunctionDescriptor::GetDisplayRequests:
    157             return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(
    158                     displayHook<decltype(&Display::getRequests),
    159                     &Display::getRequests, int32_t*, uint32_t*, hwc2_layer_t*,
    160                     int32_t*>);
    161         case FunctionDescriptor::GetDisplayType:
    162             return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(
    163                     displayHook<decltype(&Display::getType),
    164                     &Display::getType, int32_t*>);
    165         case FunctionDescriptor::GetDozeSupport:
    166             return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(
    167                     displayHook<decltype(&Display::getDozeSupport),
    168                     &Display::getDozeSupport, int32_t*>);
    169         case FunctionDescriptor::GetHdrCapabilities:
    170             return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(
    171                     displayHook<decltype(&Display::getHdrCapabilities),
    172                     &Display::getHdrCapabilities, uint32_t*, int32_t*, float*,
    173                     float*, float*>);
    174         case FunctionDescriptor::GetReleaseFences:
    175             return asFP<HWC2_PFN_GET_RELEASE_FENCES>(
    176                     displayHook<decltype(&Display::getReleaseFences),
    177                     &Display::getReleaseFences, uint32_t*, hwc2_layer_t*,
    178                     int32_t*>);
    179         case FunctionDescriptor::PresentDisplay:
    180             return asFP<HWC2_PFN_PRESENT_DISPLAY>(
    181                     displayHook<decltype(&Display::present),
    182                     &Display::present, int32_t*>);
    183         case FunctionDescriptor::SetActiveConfig:
    184             return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(
    185                     displayHook<decltype(&Display::setActiveConfig),
    186                     &Display::setActiveConfig, hwc2_config_t>);
    187         case FunctionDescriptor::SetClientTarget:
    188             return asFP<HWC2_PFN_SET_CLIENT_TARGET>(
    189                     displayHook<decltype(&Display::setClientTarget),
    190                     &Display::setClientTarget, buffer_handle_t, int32_t,
    191                     int32_t, hwc_region_t>);
    192         case FunctionDescriptor::SetColorMode:
    193             return asFP<HWC2_PFN_SET_COLOR_MODE>(
    194                     displayHook<decltype(&Display::setColorMode),
    195                     &Display::setColorMode, int32_t>);
    196         case FunctionDescriptor::SetColorTransform:
    197             return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(
    198                     displayHook<decltype(&Display::setColorTransform),
    199                     &Display::setColorTransform, const float*, int32_t>);
    200         case FunctionDescriptor::SetOutputBuffer:
    201             return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
    202                     displayHook<decltype(&Display::setOutputBuffer),
    203                     &Display::setOutputBuffer, buffer_handle_t, int32_t>);
    204         case FunctionDescriptor::SetPowerMode:
    205             return asFP<HWC2_PFN_SET_POWER_MODE>(
    206                     displayHook<decltype(&Display::setPowerMode),
    207                     &Display::setPowerMode, int32_t>);
    208         case FunctionDescriptor::SetVsyncEnabled:
    209             return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(
    210                     displayHook<decltype(&Display::setVsyncEnabled),
    211                     &Display::setVsyncEnabled, int32_t>);
    212         case FunctionDescriptor::ValidateDisplay:
    213             return asFP<HWC2_PFN_VALIDATE_DISPLAY>(
    214                     displayHook<decltype(&Display::validate),
    215                     &Display::validate, uint32_t*, uint32_t*>);
    216         case FunctionDescriptor::GetClientTargetSupport:
    217             return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
    218                     displayHook<decltype(&Display::getClientTargetSupport),
    219                     &Display::getClientTargetSupport, uint32_t, uint32_t,
    220                                                       int32_t, int32_t>);
    221         // Layer functions
    222         case FunctionDescriptor::SetCursorPosition:
    223             return asFP<HWC2_PFN_SET_CURSOR_POSITION>(
    224                     layerHook<decltype(&Layer::setCursorPosition),
    225                     &Layer::setCursorPosition, int32_t, int32_t>);
    226         case FunctionDescriptor::SetLayerBuffer:
    227             return asFP<HWC2_PFN_SET_LAYER_BUFFER>(
    228                     layerHook<decltype(&Layer::setBuffer), &Layer::setBuffer,
    229                     buffer_handle_t, int32_t>);
    230         case FunctionDescriptor::SetLayerSurfaceDamage:
    231             return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
    232                     layerHook<decltype(&Layer::setSurfaceDamage),
    233                     &Layer::setSurfaceDamage, hwc_region_t>);
    234 
    235         // Layer state functions
    236         case FunctionDescriptor::SetLayerBlendMode:
    237             return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(
    238                     layerHook<decltype(&Layer::setBlendMode),
    239                     &Layer::setBlendMode, int32_t>);
    240         case FunctionDescriptor::SetLayerColor:
    241             return asFP<HWC2_PFN_SET_LAYER_COLOR>(
    242                     layerHook<decltype(&Layer::setColor), &Layer::setColor,
    243                     hwc_color_t>);
    244         case FunctionDescriptor::SetLayerCompositionType:
    245             return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
    246                     layerHook<decltype(&Layer::setCompositionType),
    247                     &Layer::setCompositionType, int32_t>);
    248         case FunctionDescriptor::SetLayerDataspace:
    249             return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(
    250                     layerHook<decltype(&Layer::setDataspace),
    251                     &Layer::setDataspace, int32_t>);
    252         case FunctionDescriptor::SetLayerDisplayFrame:
    253             return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
    254                     layerHook<decltype(&Layer::setDisplayFrame),
    255                     &Layer::setDisplayFrame, hwc_rect_t>);
    256         case FunctionDescriptor::SetLayerPlaneAlpha:
    257             return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
    258                     layerHook<decltype(&Layer::setPlaneAlpha),
    259                     &Layer::setPlaneAlpha, float>);
    260         case FunctionDescriptor::SetLayerSidebandStream:
    261             return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
    262                     layerHook<decltype(&Layer::setSidebandStream),
    263                     &Layer::setSidebandStream, const native_handle_t*>);
    264         case FunctionDescriptor::SetLayerSourceCrop:
    265             return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
    266                     layerHook<decltype(&Layer::setSourceCrop),
    267                     &Layer::setSourceCrop, hwc_frect_t>);
    268         case FunctionDescriptor::SetLayerTransform:
    269             return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(
    270                     layerHook<decltype(&Layer::setTransform),
    271                     &Layer::setTransform, int32_t>);
    272         case FunctionDescriptor::SetLayerVisibleRegion:
    273             return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
    274                     layerHook<decltype(&Layer::setVisibleRegion),
    275                     &Layer::setVisibleRegion, hwc_region_t>);
    276         case FunctionDescriptor::SetLayerZOrder:
    277             return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(
    278                     displayHook<decltype(&Display::updateLayerZ),
    279                     &Display::updateLayerZ, hwc2_layer_t, uint32_t>);
    280 
    281         default:
    282             ALOGE("doGetFunction: Unknown function descriptor: %d (%s)",
    283                     static_cast<int32_t>(descriptor),
    284                     to_string(descriptor).c_str());
    285             return nullptr;
    286     }
    287 }
    288 
    289 
    290 // Device functions
    291 
    292 Error EmuHWC2::createVirtualDisplay(uint32_t /*width*/, uint32_t /*height*/,
    293         int32_t* /*format*/, hwc2_display_t* /*outDisplay*/) {
    294     ALOGVV("%s", __FUNCTION__);
    295     //TODO: VirtualDisplay support
    296     return Error::None;
    297 }
    298 
    299 Error EmuHWC2::destroyVirtualDisplay(hwc2_display_t /*displayId*/) {
    300     ALOGVV("%s", __FUNCTION__);
    301     //TODO: VirtualDisplay support
    302     return Error::None;
    303 }
    304 
    305 void EmuHWC2::dump(uint32_t* /*outSize*/, char* /*outBuffer*/) {
    306     ALOGVV("%s", __FUNCTION__);
    307     //TODO:
    308     return;
    309 }
    310 
    311 uint32_t EmuHWC2::getMaxVirtualDisplayCount() {
    312     ALOGVV("%s", __FUNCTION__);
    313     //TODO: VirtualDisplay support
    314     return 0;
    315 }
    316 
    317 static bool isValid(Callback descriptor) {
    318     switch (descriptor) {
    319         case Callback::Hotplug: // Fall-through
    320         case Callback::Refresh: // Fall-through
    321         case Callback::Vsync: return true;
    322         default: return false;
    323     }
    324 }
    325 
    326 Error EmuHWC2::registerCallback(Callback descriptor,
    327         hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
    328     ALOGVV("%s", __FUNCTION__);
    329     if (!isValid(descriptor)) {
    330         ALOGE("registerCallback: Unkown function descriptor: %d",
    331                 static_cast<int32_t>(descriptor));
    332         return Error::BadParameter;
    333     }
    334     ALOGV("registerCallback(%s, %p, %p)", to_string(descriptor).c_str(),
    335             callbackData, pointer);
    336 
    337     std::unique_lock<std::mutex> lock(mStateMutex);
    338 
    339     if (pointer != nullptr) {
    340         mCallbacks[descriptor] = {callbackData, pointer};
    341     }
    342     else {
    343         ALOGV("unregisterCallback(%s)", to_string(descriptor).c_str());
    344         mCallbacks.erase(descriptor);
    345         return Error::None;
    346     }
    347 
    348     // Callback without the state lock held
    349     if (descriptor == Callback::Hotplug) {
    350         lock.unlock();
    351         auto hotplug = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
    352         hotplug(callbackData, 0, static_cast<int32_t>(Connection::Connected));
    353     }
    354 
    355     return Error::None;
    356 }
    357 
    358 //Gralloc Functions
    359 EmuHWC2::GrallocModule::GrallocModule() {
    360     int ret;
    361 
    362     ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mHw);
    363     assert(ret == 0 && "Gralloc moudle not found");
    364     mGralloc = reinterpret_cast<const gralloc_module_t*>(mHw);
    365 
    366     ret = framebuffer_open(mHw, &mFbDev);
    367     assert(ret == 0 && "Fail to open FrameBuffer device");
    368 }
    369 
    370 EmuHWC2::GrallocModule::~GrallocModule() {
    371     if (mHandle != nullptr) {
    372         mGralloc->unregisterBuffer(mGralloc, mHandle);
    373         mAllocDev->free(mAllocDev, mHandle);
    374         ALOGI("free targetCb %d", ((cb_handle_t*)(mHandle))->hostHandle);
    375     }
    376 }
    377 
    378 uint32_t EmuHWC2::GrallocModule::getTargetCb() {
    379     if (mHandle == nullptr) {
    380         int ret, stride;
    381         ret = gralloc_open(mHw, &mAllocDev);
    382         assert(ret == 0 && "Fail to open GPU device");
    383         ret = mAllocDev->alloc(mAllocDev,
    384                                mFbDev->width, mFbDev->height, mFbDev->format,
    385                                GRALLOC_USAGE_HW_COMPOSER|GRALLOC_USAGE_HW_RENDER,
    386                                &mHandle, &stride);
    387         assert(ret == 0 && "Fail to allocate target ColorBuffer");
    388         mGralloc->registerBuffer(mGralloc, mHandle);
    389         ALOGI("targetCb %d", reinterpret_cast<const cb_handle_t*>(mHandle)
    390               ->hostHandle);
    391     }
    392     return reinterpret_cast<const cb_handle_t*>(mHandle)->hostHandle;
    393 }
    394 
    395 // Display functions
    396 
    397 std::atomic<hwc2_display_t> EmuHWC2::Display::sNextId(0);
    398 
    399 EmuHWC2::Display::Display(EmuHWC2& device, DisplayType type)
    400   : mDevice(device),
    401     mId(sNextId++),
    402     mName(),
    403     mType(type),
    404     mPowerMode(PowerMode::Off),
    405     mVsyncEnabled(Vsync::Invalid),
    406     mVsyncPeriod(1000*1000*1000/60), // vsync is 60 hz
    407     mVsyncThread(*this),
    408     mClientTarget(),
    409     mChanges(),
    410     mLayers(),
    411     mReleaseLayerIds(),
    412     mReleaseFences(),
    413     mConfigs(),
    414     mActiveConfig(nullptr),
    415     mColorModes(),
    416     mSetColorTransform(false),
    417     mStateMutex()
    418     {
    419         mVsyncThread.run("", HAL_PRIORITY_URGENT_DISPLAY);
    420     }
    421 
    422 Error EmuHWC2::Display::acceptChanges() {
    423     ALOGVV("%s: displayId %u", __FUNCTION__, (uint32_t)mId);
    424     std::unique_lock<std::mutex> lock(mStateMutex);
    425 
    426     if (!mChanges) {
    427         ALOGW("%s: displayId %u acceptChanges failed, not validated",
    428               __FUNCTION__, (uint32_t)mId);
    429         return Error::NotValidated;
    430     }
    431 
    432 
    433     for (auto& change : mChanges->getTypeChanges()) {
    434         auto layerId = change.first;
    435         auto type = change.second;
    436         if (mDevice.mLayers.count(layerId) == 0) {
    437             // This should never happen but somehow does.
    438             ALOGW("Cannot accept change for unknown layer %u",
    439                   (uint32_t)layerId);
    440             continue;
    441         }
    442         auto layer = mDevice.mLayers[layerId];
    443         layer->setCompositionType((int32_t)type);
    444     }
    445 
    446     mChanges->clearTypeChanges();
    447     return Error::None;
    448 }
    449 
    450 Error EmuHWC2::Display::createLayer(hwc2_layer_t* outLayerId) {
    451     ALOGVV("%s", __FUNCTION__);
    452     std::unique_lock<std::mutex> lock(mStateMutex);
    453 
    454     auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
    455     mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
    456     *outLayerId = layer->getId();
    457     ALOGV("%s: Display %u created layer %u", __FUNCTION__, (uint32_t)mId,
    458          (uint32_t)(*outLayerId));
    459     return Error::None;
    460 }
    461 
    462 Error EmuHWC2::Display::destroyLayer(hwc2_layer_t layerId) {
    463     ALOGVV("%s", __FUNCTION__);
    464     std::unique_lock<std::mutex> lock(mStateMutex);
    465 
    466     const auto mapLayer = mDevice.mLayers.find(layerId);
    467     if (mapLayer == mDevice.mLayers.end()) {
    468         ALOGW("%s failed: no such layer, displayId %u layerId %u",
    469              __FUNCTION__, (uint32_t)mId, (uint32_t)layerId);
    470         return Error::BadLayer;
    471     }
    472     const auto layer = mapLayer->second;
    473     mDevice.mLayers.erase(mapLayer);
    474     const auto zRange = mLayers.equal_range(layer);
    475     for (auto current = zRange.first; current != zRange.second; ++current) {
    476         if (**current == *layer) {
    477             current = mLayers.erase(current);
    478             break;
    479         }
    480     }
    481     ALOGV("%s: displayId %d layerId %d", __FUNCTION__, (uint32_t)mId,
    482          (uint32_t)layerId);
    483     return Error::None;
    484 }
    485 
    486 Error EmuHWC2::Display::getActiveConfig(hwc2_config_t* outConfig) {
    487     ALOGVV("%s", __FUNCTION__);
    488     std::unique_lock<std::mutex> lock(mStateMutex);
    489 
    490     if (!mActiveConfig) {
    491         ALOGW("%s: displayId %d %s", __FUNCTION__, (uint32_t)mId,
    492                 to_string(Error::BadConfig).c_str());
    493         return Error::BadConfig;
    494     }
    495     auto configId = mActiveConfig->getId();
    496     ALOGV("%s: displayId %d configId %d", __FUNCTION__,
    497           (uint32_t)mId, (uint32_t)configId);
    498     *outConfig = configId;
    499     return Error::None;
    500 }
    501 
    502 Error EmuHWC2::Display::getDisplayAttribute(hwc2_config_t configId,
    503         int32_t attribute, int32_t* outValue) {
    504     ALOGVV("%s", __FUNCTION__);
    505     std::unique_lock<std::mutex> lock(mStateMutex);
    506 
    507     if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
    508         ALOGW("%s: bad config (%u %u)", __FUNCTION__, (uint32_t)mId, configId);
    509         return Error::BadConfig;
    510     }
    511     *outValue = mConfigs[configId]->getAttribute((Attribute)attribute);
    512     ALOGV("%s: (%d %d) %s --> %d", __FUNCTION__,
    513           (uint32_t)mId, (uint32_t)configId,
    514           to_string((Attribute)attribute).c_str(), *outValue);
    515     return Error::None;
    516 }
    517 
    518 Error EmuHWC2::Display::getChangedCompositionTypes(
    519         uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes) {
    520     ALOGVV("%s", __FUNCTION__);
    521     std::unique_lock<std::mutex> lock(mStateMutex);
    522 
    523     if (!mChanges) {
    524         ALOGW("display %u getChangedCompositionTypes failed: not validated",
    525                 (uint32_t)mId);
    526         return Error::NotValidated;
    527     }
    528 
    529     if ((outLayers == nullptr) || (outTypes == nullptr)) {
    530         *outNumElements = mChanges->getTypeChanges().size();
    531         return Error::None;
    532     }
    533 
    534     uint32_t numWritten = 0;
    535     for (const auto& element : mChanges->getTypeChanges()) {
    536         if (numWritten == *outNumElements) {
    537             break;
    538         }
    539         auto layerId = element.first;
    540         auto intType = static_cast<int32_t>(element.second);
    541         ALOGV("%s: Adding layer %u %s", __FUNCTION__, (uint32_t)layerId,
    542                 to_string(element.second).c_str());
    543         outLayers[numWritten] = layerId;
    544         outTypes[numWritten] = intType;
    545         ++numWritten;
    546     }
    547     *outNumElements = numWritten;
    548     return Error::None;
    549 }
    550 
    551 Error EmuHWC2::Display::getColorModes(uint32_t* outNumModes,
    552         int32_t* outModes) {
    553     ALOGVV("%s", __FUNCTION__);
    554     std::unique_lock<std::mutex> lock(mStateMutex);
    555 
    556     if (!outModes) {
    557         *outNumModes = mColorModes.size();
    558         return Error::None;
    559     }
    560 
    561     // we only support HAL_COLOR_MODE_NATIVE so far
    562     uint32_t numModes = std::min(*outNumModes,
    563             static_cast<uint32_t>(mColorModes.size()));
    564     std::copy_n(mColorModes.cbegin(), numModes, outModes);
    565     *outNumModes = numModes;
    566     return Error::None;
    567 }
    568 
    569 Error EmuHWC2::Display::getConfigs(uint32_t* outNumConfigs,
    570         hwc2_config_t* outConfigs) {
    571     ALOGVV("%s", __FUNCTION__);
    572     std::unique_lock<std::mutex> lock(mStateMutex);
    573 
    574     if (!outConfigs) {
    575         *outNumConfigs = mConfigs.size();
    576         return Error::None;
    577     }
    578     uint32_t numWritten = 0;
    579     for (const auto config : mConfigs) {
    580         if (numWritten == *outNumConfigs) {
    581             break;
    582         }
    583         outConfigs[numWritten] = config->getId();
    584         ++numWritten;
    585     }
    586     *outNumConfigs = numWritten;
    587     return Error::None;
    588 }
    589 
    590 Error EmuHWC2::Display::getDozeSupport(int32_t* outSupport) {
    591     ALOGVV("%s", __FUNCTION__);
    592     // We don't support so far
    593     *outSupport = 0;
    594     return Error::None;
    595 }
    596 
    597 Error EmuHWC2::Display::getHdrCapabilities(uint32_t* outNumTypes,
    598         int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
    599         float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
    600     ALOGVV("%s", __FUNCTION__);
    601     // We don't support so far
    602     *outNumTypes = 0;
    603     return Error::None;
    604 }
    605 
    606 Error EmuHWC2::Display::getName(uint32_t* outSize, char* outName) {
    607     ALOGVV("%s", __FUNCTION__);
    608     std::unique_lock<std::mutex> lock(mStateMutex);
    609 
    610     if (!outName) {
    611         *outSize = mName.size();
    612         return Error::None;
    613     }
    614     auto numCopied = mName.copy(outName, *outSize);
    615     *outSize = numCopied;
    616     return Error::None;
    617 }
    618 
    619 Error EmuHWC2::Display::getReleaseFences(uint32_t* outNumElements,
    620         hwc2_layer_t* outLayers, int32_t* outFences) {
    621     ALOGVV("%s", __FUNCTION__);
    622 
    623     *outNumElements = mReleaseLayerIds.size();
    624 
    625     ALOGVV("%s. Got %u elements", __FUNCTION__, *outNumElements);
    626 
    627     if (*outNumElements && outLayers) {
    628         ALOGVV("%s. export release layers", __FUNCTION__);
    629         memcpy(outLayers, mReleaseLayerIds.data(),
    630                sizeof(hwc2_layer_t) * (*outNumElements));
    631     }
    632 
    633     if (*outNumElements && outFences) {
    634         ALOGVV("%s. export release fences", __FUNCTION__);
    635         memcpy(outFences, mReleaseFences.data(),
    636                sizeof(int32_t) * (*outNumElements));
    637     }
    638 
    639     return Error::None;
    640 }
    641 
    642 Error EmuHWC2::Display::getRequests(int32_t* outDisplayRequests,
    643         uint32_t* outNumElements, hwc2_layer_t* outLayers,
    644         int32_t* outLayerRequests) {
    645     ALOGVV("%s", __FUNCTION__);
    646     std::unique_lock<std::mutex> lock(mStateMutex);
    647 
    648     if (!mChanges) {
    649         return Error::NotValidated;
    650     }
    651 
    652     if (outLayers == nullptr || outLayerRequests == nullptr) {
    653         *outNumElements = mChanges->getNumLayerRequests();
    654         return Error::None;
    655     }
    656 
    657     //TODO
    658     // Display requests (HWC2::DisplayRequest) are not supported so far:
    659     *outDisplayRequests = 0;
    660 
    661     uint32_t numWritten = 0;
    662     for (const auto& request : mChanges->getLayerRequests()) {
    663         if (numWritten == *outNumElements) {
    664             break;
    665         }
    666         outLayers[numWritten] = request.first;
    667         outLayerRequests[numWritten] = static_cast<int32_t>(request.second);
    668         ++numWritten;
    669     }
    670 
    671     return Error::None;
    672 }
    673 
    674 Error EmuHWC2::Display::getType(int32_t* outType) {
    675     ALOGVV("%s", __FUNCTION__);
    676     std::unique_lock<std::mutex> lock(mStateMutex);
    677 
    678     *outType = (int32_t)mType;
    679     return Error::None;
    680 }
    681 
    682 Error EmuHWC2::Display::present(int32_t* outRetireFence) {
    683     ALOGVV("%s", __FUNCTION__);
    684 
    685     *outRetireFence = -1;
    686 
    687     std::unique_lock<std::mutex> lock(mStateMutex);
    688 
    689     if (!mChanges || (mChanges->getNumTypes() > 0)) {
    690         ALOGE("%s display(%u) set failed: not validated", __FUNCTION__,
    691               (uint32_t)mId);
    692         return Error::NotValidated;
    693     }
    694     mChanges.reset();
    695 
    696     DEFINE_AND_VALIDATE_HOST_CONNECTION
    697     hostCon->lock();
    698     bool hostCompositionV1 = rcEnc->hasHostCompositionV1();
    699     hostCon->unlock();
    700 
    701     if (hostCompositionV1) {
    702         uint32_t numLayer = 0;
    703         for (auto layer: mLayers) {
    704             if (layer->getCompositionType() == Composition::Device ||
    705                 layer->getCompositionType() == Composition::SolidColor) {
    706                 numLayer++;
    707             }
    708         }
    709 
    710         ALOGVV("present %d layers total %u layers",
    711               numLayer, (uint32_t)mLayers.size());
    712 
    713         mReleaseLayerIds.clear();
    714         mReleaseFences.clear();
    715 
    716         if (numLayer == 0) {
    717             ALOGVV("No layers, exit");
    718             mGralloc->getFb()->post(mGralloc->getFb(), mClientTarget.getBuffer());
    719             *outRetireFence = mClientTarget.getFence();
    720             return Error::None;
    721         }
    722 
    723         if (mComposeMsg == nullptr || mComposeMsg->getLayerCnt() < numLayer) {
    724             mComposeMsg.reset(new ComposeMsg(numLayer));
    725         }
    726 
    727         // Handle the composition
    728         ComposeDevice* p = mComposeMsg->get();
    729         ComposeLayer* l = p->layer;
    730 
    731         for (auto layer: mLayers) {
    732             if (layer->getCompositionType() != Composition::Device &&
    733                 layer->getCompositionType() != Composition::SolidColor) {
    734                 ALOGE("%s: Unsupported composition types %d layer %u",
    735                       __FUNCTION__, layer->getCompositionType(),
    736                       (uint32_t)layer->getId());
    737                 continue;
    738             }
    739             // send layer composition command to host
    740             if (layer->getCompositionType() == Composition::Device) {
    741                 int fence = layer->getLayerBuffer().getFence();
    742                 mReleaseLayerIds.push_back(layer->getId());
    743                 if (fence != -1) {
    744                     int err = sync_wait(fence, 3000);
    745                     if (err < 0 && errno == ETIME) {
    746                         ALOGE("%s waited on fence %d for 3000 ms",
    747                             __FUNCTION__, fence);
    748                     }
    749                     close(fence);
    750                 }
    751                 else {
    752                     ALOGV("%s: acquire fence not set for layer %u",
    753                           __FUNCTION__, (uint32_t)layer->getId());
    754                 }
    755                 cb_handle_t *cb =
    756                     (cb_handle_t *)layer->getLayerBuffer().getBuffer();
    757                 if (cb != nullptr) {
    758                     l->cbHandle = cb->hostHandle;
    759                 }
    760                 else {
    761                     ALOGE("%s null buffer for layer %d", __FUNCTION__,
    762                           (uint32_t)layer->getId());
    763                 }
    764             }
    765             else {
    766                 // solidcolor has no buffer
    767                 l->cbHandle = 0;
    768             }
    769             l->composeMode = (hwc2_composition_t)layer->getCompositionType();
    770             l->displayFrame = layer->getDisplayFrame();
    771             l->crop = layer->getSourceCrop();
    772             l->blendMode = layer->getBlendMode();
    773             l->alpha = layer->getPlaneAlpha();
    774             l->color = layer->getColor();
    775             l->transform = layer->getTransform();
    776             ALOGV("   cb %d blendmode %d alpha %f %d %d %d %d z %d"
    777                   " composeMode %d, transform %d",
    778                   l->cbHandle, l->blendMode, l->alpha,
    779                   l->displayFrame.left, l->displayFrame.top,
    780                   l->displayFrame.right, l->displayFrame.bottom,
    781                   layer->getZ(), l->composeMode, l->transform);
    782             l++;
    783         }
    784         p->version = 1;
    785         p->targetHandle = mGralloc->getTargetCb();
    786         p->numLayers = numLayer;
    787 
    788         hostCon->lock();
    789         rcEnc->rcCompose(rcEnc,
    790                          sizeof(ComposeDevice) + numLayer * sizeof(ComposeLayer),
    791                          (void *)p);
    792         hostCon->unlock();
    793 
    794         // Send a retire fence and use it as the release fence for all layers,
    795         // since media expects it
    796         EGLint attribs[] = { EGL_SYNC_NATIVE_FENCE_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID };
    797 
    798         uint64_t sync_handle, thread_handle;
    799         int retire_fd;
    800 
    801         hostCon->lock();
    802         rcEnc->rcCreateSyncKHR(rcEnc, EGL_SYNC_NATIVE_FENCE_ANDROID,
    803                 attribs, 2 * sizeof(EGLint), true /* destroy when signaled */,
    804                 &sync_handle, &thread_handle);
    805         hostCon->unlock();
    806 
    807         goldfish_sync_queue_work(mSyncDeviceFd,
    808                 sync_handle, thread_handle, &retire_fd);
    809 
    810         for (size_t i = 0; i < mReleaseLayerIds.size(); ++i) {
    811             mReleaseFences.push_back(dup(retire_fd));
    812         }
    813 
    814         *outRetireFence = dup(retire_fd);
    815         close(retire_fd);
    816         hostCon->lock();
    817         rcEnc->rcDestroySyncKHR(rcEnc, sync_handle);
    818         hostCon->unlock();
    819     } else {
    820         // we set all layers Composition::Client, so do nothing.
    821         mGralloc->getFb()->post(mGralloc->getFb(), mClientTarget.getBuffer());
    822         *outRetireFence = mClientTarget.getFence();
    823         ALOGV("%s fallback to post, returns outRetireFence %d",
    824               __FUNCTION__, *outRetireFence);
    825     }
    826 
    827     return Error::None;
    828 }
    829 
    830 Error EmuHWC2::Display::setActiveConfig(hwc2_config_t configId) {
    831     ALOGVV("%s %u", __FUNCTION__, (uint32_t)configId);
    832     std::unique_lock<std::mutex> lock(mStateMutex);
    833 
    834     if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
    835         ALOGW("%s: bad config (%u %u)", __FUNCTION__, (uint32_t)mId,
    836               (uint32_t)configId);
    837         return Error::BadConfig;
    838     }
    839     auto config = mConfigs[configId];
    840     if (config == mActiveConfig) {
    841         return Error::None;
    842     }
    843 
    844     mActiveConfig = config;
    845     return Error::None;
    846 }
    847 
    848 Error EmuHWC2::Display::setClientTarget(buffer_handle_t target,
    849         int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/) {
    850     ALOGVV("%s", __FUNCTION__);
    851 
    852     cb_handle_t *cb =
    853             (cb_handle_t *)target;
    854     ALOGV("%s: display(%u) buffer handle %p cb %d, acquireFence %d", __FUNCTION__,
    855           (uint32_t)mId, target, cb->hostHandle, acquireFence);
    856     std::unique_lock<std::mutex> lock(mStateMutex);
    857     mClientTarget.setBuffer(target);
    858     mClientTarget.setFence(acquireFence);
    859     return Error::None;
    860 }
    861 
    862 Error EmuHWC2::Display::setColorMode(int32_t intMode) {
    863     ALOGVV("%s %d", __FUNCTION__, intMode);
    864     std::unique_lock<std::mutex> lock(mStateMutex);
    865 
    866     auto mode = static_cast<android_color_mode_t>(intMode);
    867     ALOGV("%s: (display %u mode %d)", __FUNCTION__, (uint32_t)mId, intMode);
    868     if (mode == mActiveColorMode) {
    869         return Error::None;
    870     }
    871     if (mColorModes.count(mode) == 0) {
    872         ALOGE("%s: display %d Mode %d not found in mColorModes",
    873              __FUNCTION__, (uint32_t)mId, intMode);
    874         return Error::Unsupported;
    875     }
    876     mActiveColorMode = mode;
    877     return Error::None;
    878 }
    879 
    880 Error EmuHWC2::Display::setColorTransform(const float* /*matrix*/,
    881                                           int32_t hint) {
    882     ALOGVV("%s hint %d", __FUNCTION__, hint);
    883     std::unique_lock<std::mutex> lock(mStateMutex);
    884     //we force client composition if this is set
    885     if (hint == 0 ) {
    886         mSetColorTransform = false;
    887     }
    888     else {
    889         mSetColorTransform = true;
    890     }
    891     return Error::None;
    892 }
    893 
    894 Error EmuHWC2::Display::setOutputBuffer(buffer_handle_t /*buffer*/,
    895         int32_t /*releaseFence*/) {
    896     ALOGVV("%s", __FUNCTION__);
    897     //TODO: for virtual display
    898     return Error::None;
    899 }
    900 
    901 static bool isValid(PowerMode mode) {
    902     switch (mode) {
    903         case PowerMode::Off: // Fall-through
    904         case PowerMode::DozeSuspend: // Fall-through
    905         case PowerMode::Doze: // Fall-through
    906         case PowerMode::On: return true;
    907         default: return false;
    908     }
    909 }
    910 
    911 Error EmuHWC2::Display::setPowerMode(int32_t intMode) {
    912     ALOGVV("%s", __FUNCTION__);
    913     // Emulator always set screen ON
    914     PowerMode mode = static_cast<PowerMode>(intMode);
    915     if (!isValid(mode)) {
    916         return Error::BadParameter;
    917     }
    918     if (mode == mPowerMode) {
    919         return Error::None;
    920     }
    921     std::unique_lock<std::mutex> lock(mStateMutex);
    922 
    923     ALOGV("%s: (display %u mode %s)", __FUNCTION__,
    924           (uint32_t)mId, to_string(mode).c_str());
    925     mPowerMode = mode;
    926     return Error::None;
    927 }
    928 
    929 static bool isValid(Vsync enable) {
    930     switch (enable) {
    931         case Vsync::Enable: // Fall-through
    932         case Vsync::Disable: return true;
    933         case Vsync::Invalid: return false;
    934     }
    935 }
    936 
    937 Error EmuHWC2::Display::setVsyncEnabled(int32_t intEnable) {
    938     ALOGVV("%s %d", __FUNCTION__, intEnable);
    939     Vsync enable = static_cast<Vsync>(intEnable);
    940     if (!isValid(enable)) {
    941         return Error::BadParameter;
    942     }
    943     if (enable == mVsyncEnabled) {
    944         return Error::None;
    945     }
    946 
    947     std::unique_lock<std::mutex> lock(mStateMutex);
    948 
    949     mVsyncEnabled = enable;
    950     return Error::None;
    951 }
    952 
    953 Error EmuHWC2::Display::validate(uint32_t* outNumTypes,
    954         uint32_t* outNumRequests) {
    955     ALOGVV("%s", __FUNCTION__);
    956     std::unique_lock<std::mutex> lock(mStateMutex);
    957 
    958     if (!mChanges) {
    959         mChanges.reset(new Changes);
    960         DEFINE_AND_VALIDATE_HOST_CONNECTION
    961         hostCon->lock();
    962         bool hostCompositionV1 = rcEnc->hasHostCompositionV1();
    963         hostCon->unlock();
    964 
    965         if (hostCompositionV1) {
    966             // Support Device and SolidColor, otherwise, fallback all layers
    967             // to Client
    968             bool fallBack = false;
    969             for (auto& layer : mLayers) {
    970                 if (layer->getCompositionType() == Composition::Invalid) {
    971                     // Log error for unused layers, layer leak?
    972                     ALOGE("%s layer %u CompositionType(%d) not set",
    973                           __FUNCTION__, (uint32_t)layer->getId(),
    974                           layer->getCompositionType());
    975                     continue;
    976                 }
    977                 if (layer->getCompositionType() == Composition::Client ||
    978                     layer->getCompositionType() == Composition::Cursor ||
    979                     layer->getCompositionType() == Composition::Sideband) {
    980                     ALOGW("%s: layer %u CompositionType %d, fallback", __FUNCTION__,
    981                          (uint32_t)layer->getId(), layer->getCompositionType());
    982                     fallBack = true;
    983                     break;
    984                 }
    985             }
    986             if (mSetColorTransform) {
    987                 fallBack = true;
    988             }
    989             if (fallBack) {
    990                 for (auto& layer : mLayers) {
    991                     if (layer->getCompositionType() == Composition::Invalid) {
    992                         continue;
    993                     }
    994                     if (layer->getCompositionType() != Composition::Client) {
    995                         mChanges->addTypeChange(layer->getId(),
    996                                                 Composition::Client);
    997                     }
    998                 }
    999             }
   1000        }
   1001        else {
   1002             for (auto& layer : mLayers) {
   1003                 if (layer->getCompositionType() != Composition::Client) {
   1004                     mChanges->addTypeChange(layer->getId(),
   1005                                             Composition::Client);
   1006                 }
   1007             }
   1008         }
   1009     }
   1010     else {
   1011         ALOGE("Validate was called more than once!");
   1012     }
   1013 
   1014     *outNumTypes = mChanges->getNumTypes();
   1015     *outNumRequests = mChanges->getNumLayerRequests();
   1016     ALOGV("%s: displayId %u types %u, requests %u", __FUNCTION__,
   1017           (uint32_t)mId, *outNumTypes, *outNumRequests);
   1018     return *outNumTypes > 0 ? Error::HasChanges : Error::None;
   1019 }
   1020 
   1021 Error EmuHWC2::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z) {
   1022     ALOGVV("%s", __FUNCTION__);
   1023     std::unique_lock<std::mutex> lock(mStateMutex);
   1024 
   1025     const auto mapLayer = mDevice.mLayers.find(layerId);
   1026     if (mapLayer == mDevice.mLayers.end()) {
   1027         ALOGE("%s failed to find layer %u", __FUNCTION__, (uint32_t)mId);
   1028         return Error::BadLayer;
   1029     }
   1030 
   1031     const auto layer = mapLayer->second;
   1032     const auto zRange = mLayers.equal_range(layer);
   1033     bool layerOnDisplay = false;
   1034     for (auto current = zRange.first; current != zRange.second; ++current) {
   1035         if (**current == *layer) {
   1036             if ((*current)->getZ() == z) {
   1037                 // Don't change anything if the Z hasn't changed
   1038                 return Error::None;
   1039             }
   1040             current = mLayers.erase(current);
   1041             layerOnDisplay = true;
   1042             break;
   1043         }
   1044     }
   1045 
   1046     if (!layerOnDisplay) {
   1047         ALOGE("%s failed to find layer %u on display", __FUNCTION__,
   1048               (uint32_t)mId);
   1049         return Error::BadLayer;
   1050     }
   1051 
   1052     layer->setZ(z);
   1053     mLayers.emplace(std::move(layer));
   1054     return Error::None;
   1055 }
   1056 
   1057 Error EmuHWC2::Display::getClientTargetSupport(uint32_t width, uint32_t height,
   1058                                       int32_t format, int32_t dataspace){
   1059     ALOGVV("%s", __FUNCTION__);
   1060     std::unique_lock<std::mutex> lock(mStateMutex);
   1061 
   1062     if (mActiveConfig == nullptr) {
   1063         return Error::Unsupported;
   1064     }
   1065 
   1066     if (width == (uint32_t)mActiveConfig->getAttribute(Attribute::Width) &&
   1067         height == (uint32_t)mActiveConfig->getAttribute(Attribute::Height) &&
   1068         format == HAL_PIXEL_FORMAT_RGBA_8888 &&
   1069         dataspace == HAL_DATASPACE_UNKNOWN) {
   1070         return Error::None;
   1071     }
   1072 
   1073     return Error::None;
   1074 }
   1075 
   1076 
   1077 int EmuHWC2::Display::populatePrimaryConfigs() {
   1078     ALOGVV("%s DisplayId %u", __FUNCTION__, (uint32_t)mId);
   1079     std::unique_lock<std::mutex> lock(mStateMutex);
   1080 
   1081     mGralloc.reset(new GrallocModule());
   1082     auto newConfig = std::make_shared<Config>(*this);
   1083     // vsync is 60 hz;
   1084     newConfig->setAttribute(Attribute::VsyncPeriod, mVsyncPeriod);
   1085     newConfig->setAttribute(Attribute::Width, mGralloc->getFb()->width);
   1086     newConfig->setAttribute(Attribute::Height, mGralloc->getFb()->height);
   1087     newConfig->setAttribute(Attribute::DpiX, mGralloc->getFb()->xdpi*1000);
   1088     newConfig->setAttribute(Attribute::DpiY, mGralloc->getFb()->ydpi*1000);
   1089 
   1090     newConfig->setId(static_cast<hwc2_config_t>(mConfigs.size()));
   1091     ALOGV("Found new config %d: %s", (uint32_t)newConfig->getId(),
   1092             newConfig->toString().c_str());
   1093     mConfigs.emplace_back(std::move(newConfig));
   1094 
   1095     // Only have single config so far, it is activeConfig
   1096     mActiveConfig = mConfigs[0];
   1097     mActiveColorMode = HAL_COLOR_MODE_NATIVE;
   1098     mColorModes.emplace((android_color_mode_t)HAL_COLOR_MODE_NATIVE);
   1099 
   1100     mSyncDeviceFd = goldfish_sync_open();
   1101 
   1102     return 0;
   1103 }
   1104 
   1105 
   1106 // Config functions
   1107 
   1108 void EmuHWC2::Display::Config::setAttribute(Attribute attribute,
   1109        int32_t value) {
   1110     mAttributes[attribute] = value;
   1111 }
   1112 
   1113 int32_t EmuHWC2::Display::Config::getAttribute(Attribute attribute) const {
   1114     if (mAttributes.count(attribute) == 0) {
   1115         return -1;
   1116     }
   1117     return mAttributes.at(attribute);
   1118 }
   1119 
   1120 std::string EmuHWC2::Display::Config::toString() const {
   1121     std::string output;
   1122 
   1123     const size_t BUFFER_SIZE = 100;
   1124     char buffer[BUFFER_SIZE] = {};
   1125     auto writtenBytes = snprintf(buffer, BUFFER_SIZE,
   1126             "%u x %u", mAttributes.at(HWC2::Attribute::Width),
   1127             mAttributes.at(HWC2::Attribute::Height));
   1128     output.append(buffer, writtenBytes);
   1129 
   1130     if (mAttributes.count(HWC2::Attribute::VsyncPeriod) != 0) {
   1131         std::memset(buffer, 0, BUFFER_SIZE);
   1132         writtenBytes = snprintf(buffer, BUFFER_SIZE, " @ %.1f Hz",
   1133                 1e9 / mAttributes.at(HWC2::Attribute::VsyncPeriod));
   1134         output.append(buffer, writtenBytes);
   1135     }
   1136 
   1137     if (mAttributes.count(HWC2::Attribute::DpiX) != 0 &&
   1138             mAttributes.at(HWC2::Attribute::DpiX) != -1) {
   1139         std::memset(buffer, 0, BUFFER_SIZE);
   1140         writtenBytes = snprintf(buffer, BUFFER_SIZE,
   1141                 ", DPI: %.1f x %.1f",
   1142                 mAttributes.at(HWC2::Attribute::DpiX) / 1000.0f,
   1143                 mAttributes.at(HWC2::Attribute::DpiY) / 1000.0f);
   1144         output.append(buffer, writtenBytes);
   1145     }
   1146 
   1147     return output;
   1148 }
   1149 
   1150 
   1151 // VsyncThread function
   1152 bool EmuHWC2::Display::VsyncThread::threadLoop() {
   1153     struct timespec rt;
   1154     if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
   1155         ALOGE("%s: error in vsync thread clock_gettime: %s",
   1156               __FUNCTION__, strerror(errno));
   1157         return true;
   1158     }
   1159     const int logInterval = 60;
   1160     int64_t lastLogged = rt.tv_sec;
   1161     int sent = 0;
   1162     int lastSent = 0;
   1163     bool vsyncEnabled = false;
   1164     struct timespec wait_time;
   1165     wait_time.tv_sec = 0;
   1166     wait_time.tv_nsec = mDisplay.mVsyncPeriod;
   1167 
   1168     while (true) {
   1169         int err = nanosleep(&wait_time, NULL);
   1170         if (err == -1) {
   1171             if (errno == EINTR) {
   1172                 break;
   1173             }
   1174             ALOGE("%s: error in vsync thread: %s", __FUNCTION__, strerror(errno));
   1175         }
   1176 
   1177         std::unique_lock<std::mutex> lock(mDisplay.mStateMutex);
   1178         vsyncEnabled = (mDisplay.mVsyncEnabled == Vsync::Enable);
   1179         lock.unlock();
   1180 
   1181         if (!vsyncEnabled) {
   1182             continue;
   1183         }
   1184 
   1185         if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
   1186             ALOGE("%s: error in vsync thread clock_gettime: %s",
   1187                  __FUNCTION__, strerror(errno));
   1188         }
   1189 
   1190         int64_t timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
   1191 
   1192         lock.lock();
   1193         const auto& callbackInfo = mDisplay.mDevice.mCallbacks[Callback::Vsync];
   1194         auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
   1195         lock.unlock();
   1196 
   1197         if (vsync) {
   1198             vsync(callbackInfo.data, mDisplay.mId, timestamp);
   1199         }
   1200 
   1201         if (rt.tv_sec - lastLogged >= logInterval) {
   1202             ALOGVV("sent %d syncs in %ds", sent - lastSent, rt.tv_sec - lastLogged);
   1203             lastLogged = rt.tv_sec;
   1204             lastSent = sent;
   1205         }
   1206         ++sent;
   1207     }
   1208     return false;
   1209 }
   1210 
   1211 
   1212 // Layer functions
   1213 bool EmuHWC2::SortLayersByZ::operator()(const std::shared_ptr<Layer>& lhs,
   1214         const std::shared_ptr<Layer>& rhs) const {
   1215     return lhs->getZ() < rhs->getZ();
   1216 }
   1217 
   1218 std::atomic<hwc2_layer_t> EmuHWC2::Layer::sNextId(1);
   1219 
   1220 EmuHWC2::Layer::Layer(Display& display)
   1221   : mId(sNextId++),
   1222     mDisplay(display),
   1223     mBuffer(),
   1224     mSurfaceDamage(),
   1225     mBlendMode(BlendMode::None),
   1226     mColor({0, 0, 0, 0}),
   1227     mCompositionType(Composition::Invalid),
   1228     mDisplayFrame({0, 0, -1, -1}),
   1229     mPlaneAlpha(0.0f),
   1230     mSidebandStream(nullptr),
   1231     mSourceCrop({0.0f, 0.0f, -1.0f, -1.0f}),
   1232     mTransform(Transform::None),
   1233     mVisibleRegion(),
   1234     mZ(0)
   1235     {}
   1236 
   1237 Error EmuHWC2::Layer::setBuffer(buffer_handle_t buffer,
   1238         int32_t acquireFence) {
   1239     ALOGVV("%s: Setting acquireFence %d for layer %u", __FUNCTION__,
   1240           acquireFence, (uint32_t)mId);
   1241     mBuffer.setBuffer(buffer);
   1242     mBuffer.setFence(acquireFence);
   1243     return Error::None;
   1244 }
   1245 
   1246 Error EmuHWC2::Layer::setCursorPosition(int32_t /*x*/,
   1247                                         int32_t /*y*/) {
   1248     ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
   1249     if (mCompositionType != Composition::Cursor) {
   1250         ALOGE("%s: CompositionType not Cursor type", __FUNCTION__);
   1251         return Error::BadLayer;
   1252     }
   1253    //TODO
   1254     return Error::None;
   1255 }
   1256 
   1257 Error EmuHWC2::Layer::setSurfaceDamage(hwc_region_t /*damage*/) {
   1258     // Emulator redraw whole layer per frame, so ignore this.
   1259     ALOGVV("%s", __FUNCTION__);
   1260     return Error::None;
   1261 }
   1262 
   1263 // Layer state functions
   1264 
   1265 Error EmuHWC2::Layer::setBlendMode(int32_t mode) {
   1266     ALOGVV("%s %d for layer %u", __FUNCTION__, mode, (uint32_t)mId);
   1267     mBlendMode = static_cast<BlendMode>(mode);
   1268     return Error::None;
   1269 }
   1270 
   1271 Error EmuHWC2::Layer::setColor(hwc_color_t color) {
   1272     ALOGVV("%s layer %u %d", __FUNCTION__, (uint32_t)mId, color);
   1273     mColor = color;
   1274     return Error::None;
   1275 }
   1276 
   1277 Error EmuHWC2::Layer::setCompositionType(int32_t type) {
   1278     ALOGVV("%s layer %u %u", __FUNCTION__, (uint32_t)mId, type);
   1279     mCompositionType = static_cast<Composition>(type);
   1280     return Error::None;
   1281 }
   1282 
   1283 Error EmuHWC2::Layer::setDataspace(int32_t) {
   1284     ALOGVV("%s", __FUNCTION__);
   1285     return Error::None;
   1286 }
   1287 
   1288 Error EmuHWC2::Layer::setDisplayFrame(hwc_rect_t frame) {
   1289     ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
   1290     mDisplayFrame = frame;
   1291     return Error::None;
   1292 }
   1293 
   1294 Error EmuHWC2::Layer::setPlaneAlpha(float alpha) {
   1295     ALOGVV("%s layer %u %f", __FUNCTION__, (uint32_t)mId, alpha);
   1296     mPlaneAlpha = alpha;
   1297     return Error::None;
   1298 }
   1299 
   1300 Error EmuHWC2::Layer::setSidebandStream(const native_handle_t* stream) {
   1301     ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
   1302     mSidebandStream = stream;
   1303     return Error::None;
   1304 }
   1305 
   1306 Error EmuHWC2::Layer::setSourceCrop(hwc_frect_t crop) {
   1307     ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
   1308     mSourceCrop = crop;
   1309     return Error::None;
   1310 }
   1311 
   1312 Error EmuHWC2::Layer::setTransform(int32_t transform) {
   1313     ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
   1314     mTransform = static_cast<Transform>(transform);
   1315     return Error::None;
   1316 }
   1317 
   1318 static bool compareRects(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
   1319     return rect1.left == rect2.left &&
   1320             rect1.right == rect2.right &&
   1321             rect1.top == rect2.top &&
   1322             rect1.bottom == rect2.bottom;
   1323 }
   1324 
   1325 Error EmuHWC2::Layer::setVisibleRegion(hwc_region_t visible) {
   1326     ALOGVV("%s", __FUNCTION__);
   1327     if ((getNumVisibleRegions() != visible.numRects) ||
   1328         !std::equal(mVisibleRegion.begin(), mVisibleRegion.end(), visible.rects,
   1329                     compareRects)) {
   1330         mVisibleRegion.resize(visible.numRects);
   1331         std::copy_n(visible.rects, visible.numRects, mVisibleRegion.begin());
   1332     }
   1333     return Error::None;
   1334 }
   1335 
   1336 Error EmuHWC2::Layer::setZ(uint32_t z) {
   1337     ALOGVV("%s layer %u %d", __FUNCTION__, (uint32_t)mId, z);
   1338     mZ = z;
   1339     return Error::None;
   1340 }
   1341 
   1342 // Adaptor Helpers
   1343 
   1344 void EmuHWC2::populateCapabilities() {
   1345     //TODO: add Capabilities
   1346     // support virtualDisplay
   1347     // support sideBandStream
   1348     // support backGroundColor
   1349     // we should not set this for HWC2, TODO: remove
   1350     // mCapabilities.insert(Capability::PresentFenceIsNotReliable);
   1351 }
   1352 
   1353 int EmuHWC2::populatePrimary() {
   1354     int ret = 0;
   1355     auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
   1356     ret = display->populatePrimaryConfigs();
   1357     if (ret != 0) {
   1358         return ret;
   1359     }
   1360     mDisplays.emplace(display->getId(), std::move(display));
   1361     return ret;
   1362 }
   1363 
   1364 EmuHWC2::Display* EmuHWC2::getDisplay(hwc2_display_t id) {
   1365     auto display = mDisplays.find(id);
   1366     if (display == mDisplays.end()) {
   1367         return nullptr;
   1368     }
   1369     return display->second.get();
   1370 }
   1371 
   1372 std::tuple<EmuHWC2::Layer*, Error> EmuHWC2::getLayer(
   1373         hwc2_display_t displayId, hwc2_layer_t layerId) {
   1374     auto display = getDisplay(displayId);
   1375     if (!display) {
   1376         ALOGE("%s: Fail to find display %d", __FUNCTION__, (uint32_t)displayId);
   1377         return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay);
   1378     }
   1379 
   1380     auto layerEntry = mLayers.find(layerId);
   1381     if (layerEntry == mLayers.end()) {
   1382         ALOGE("%s: Fail to find layer %d", __FUNCTION__, (uint32_t)layerId);
   1383         return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
   1384     }
   1385 
   1386     auto layer = layerEntry->second;
   1387     if (layer->getDisplay().getId() != displayId) {
   1388         ALOGE("%s: layer %d not belongs to display %d", __FUNCTION__,
   1389               (uint32_t)layerId, (uint32_t)displayId);
   1390         return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
   1391     }
   1392     return std::make_tuple(layer.get(), Error::None);
   1393 }
   1394 
   1395 static int hwc2DevOpen(const struct hw_module_t *module, const char *name,
   1396         struct hw_device_t **dev) {
   1397     ALOGVV("%s ", __FUNCTION__);
   1398     if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
   1399         ALOGE("Invalid module name- %s", name);
   1400         return -EINVAL;
   1401     }
   1402 
   1403     EmuHWC2* ctx = new EmuHWC2();
   1404     if (!ctx) {
   1405         ALOGE("Failed to allocate EmuHWC2");
   1406         return -ENOMEM;
   1407     }
   1408     int ret = ctx->populatePrimary();
   1409     if (ret != 0) {
   1410         ALOGE("Failed to populate primary display");
   1411         return ret;
   1412     }
   1413 
   1414     ctx->common.module = const_cast<hw_module_t *>(module);
   1415     *dev = &ctx->common;
   1416     return 0;
   1417 }
   1418 }
   1419 
   1420 static struct hw_module_methods_t hwc2_module_methods = {
   1421     .open = android::hwc2DevOpen
   1422 };
   1423 
   1424 hw_module_t HAL_MODULE_INFO_SYM = {
   1425     .tag = HARDWARE_MODULE_TAG,
   1426     .version_major = 2,
   1427     .version_minor = 0,
   1428     .id = HWC_HARDWARE_MODULE_ID,
   1429     .name = "goldfish HWC2 module",
   1430     .author = "The Android Open Source Project",
   1431     .methods = &hwc2_module_methods,
   1432     .dso = NULL,
   1433     .reserved = {0},
   1434 };
   1435