9aa03de5创建于 2022年10月24日历史提交
/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <hdi_session.h>
#include <cerrno>
#include <mutex>
#include "display_common.h"
#include "display_device.h"
#include "display_layer.h"
#include "hdi_netlink_monitor.h"

namespace OHOS {
    namespace HDI {
        namespace DISPLAY {
            HdiSession &HdiSession::GetInstance()
            {
                static HdiSession instance;
                static std::once_flag once;
                std::call_once(once, [&]() { instance.Init(); });
                return instance;
            }

            void HdiSession::Init()
            {
                DISPLAY_DEBUGLOG();
                mHdiDevices = HdiDeviceInterface::DiscoveryDevice();
                DISPLAY_DEBUGLOG("devices size %{public}zd", mHdiDevices.size());
                mHdiDisplays.clear();
                for (auto device : mHdiDevices) {
                    auto displays = device->DiscoveryDisplay();
                    /* Register the connectors instead of display device.
                     * There are several connectors in one display device
                     * in rockchip platform.
                     */
                    for (auto display : displays) {
                        mHdiDisplays[display.first] = display.second;
                    }
                }
                mNetLinkMonitor = std::make_shared<HdiNetLinkMonitor>();
                mNetLinkMonitor->Init();
            }

            void HdiSession::HandleHotplug(bool plugIn)
            {
                for (auto device : mHdiDevices) {
                    for (auto displayMap : mHdiDisplays) {
                        auto display = displayMap.second;
                        auto isSuccess = device->HandleHotplug(display->GetId(), plugIn);
                        if (isSuccess == true) {
                            DoHotPlugCallback(display->GetId(), plugIn);
                        }
                    }
                }
            }

            int32_t HdiSession::RegHotPlugCallback(HotPlugCallback callback, void *data)
            {
                DISPLAY_CHK_RETURN((callback == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the callback is nullptr"));
                mHotPlugCallBacks.emplace(callback, data);
                for (auto displayMap : mHdiDisplays) {
                    auto display = displayMap.second;
                    if (display->IsConnected()) {
                        DoHotPlugCallback(display->GetId(), true);
                    }
                }
                return DISPLAY_SUCCESS;
            }

            void HdiSession::DoHotPlugCallback(uint32_t devId, bool connect)
            {
                DISPLAY_DEBUGLOG();
                for (const auto &callback : mHotPlugCallBacks) {
                    callback.first(devId, connect, callback.second);
                }
            }
        } // OHOS
    }     // HDI
} // DISPLAY

using namespace OHOS::HDI::DISPLAY;
static int32_t RegHotPlugCallback(HotPlugCallback callback, void *data)
{
    DISPLAY_DEBUGLOG();
    HdiSession::GetInstance().RegHotPlugCallback(callback, data);
    return DISPLAY_SUCCESS;
}

static int32_t GetDisplayCapability(uint32_t devId, DisplayCapability *info)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN(info == nullptr, DISPLAY_NULL_PTR, DISPLAY_LOGE("info is nullptr"));
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayCapability, info);
}

static int32_t GetDisplaySupportedModes(uint32_t devId, uint32_t *num, DisplayModeInfo *modes)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN(num == nullptr, DISPLAY_NULL_PTR, DISPLAY_LOGE("num is nullptr"));
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplaySupportedModes, num, modes);
}

static int32_t GetDisplayMode(uint32_t devId, uint32_t *mode)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((mode == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("mode is nullptr"));
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayMode, mode);
}

static int32_t SetDisplayMode(uint32_t devId, uint32_t mode)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayMode, mode);
}

static int32_t GetDisplayPowerStatus(uint32_t devId, DispPowerStatus *status)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((status == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("status is nullptr"));
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayPowerStatus, status);
}

static int32_t SetDisplayPowerStatus(uint32_t devId, DispPowerStatus status)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayPowerStatus, status);
}

static int32_t GetDisplayBacklight(uint32_t devId, uint32_t *value)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((value == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("value is nullptr"));
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayBacklight, value);
}

static int32_t SetDisplayBacklight(uint32_t devId, uint32_t value)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayBacklight, value);
}

static int32_t GetDisplayProperty(uint32_t devId, uint32_t id, uint64_t *value)
{
    DISPLAY_DEBUGLOG();
    (void)id;
    DISPLAY_CHK_RETURN((value == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("value is nullptr"));
    return DISPLAY_NOT_SUPPORT;
}

static int32_t SetDisplayProperty(uint32_t devId, uint32_t id, uint64_t value)
{
    DISPLAY_DEBUGLOG();
    (void)id;
    return DISPLAY_NOT_SUPPORT;
}

static int32_t PrepareDisplayLayers(uint32_t devId, bool *needFlushFb)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((needFlushFb == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("needFlushFb is nullptr"));
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::PrepareDisplayLayers, needFlushFb);
}

static int32_t GetDisplayCompChange(uint32_t devId, uint32_t *num, uint32_t *layers, int32_t *type)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("num is nullptr"));
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayCompChange, num, layers, type);
}

static int32_t SetDisplayClientCrop(uint32_t devId, IRect *rect)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
    return DISPLAY_NOT_SUPPORT;
}

static int32_t SetDisplayClientDestRect(uint32_t devId, IRect *rect)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
    return DISPLAY_NOT_SUPPORT;
}

static int32_t SetDisplayClientBuffer(uint32_t devId, const BufferHandle *buffer, int32_t fence)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayClientBuffer, buffer, fence);
}

static int32_t SetDisplayClientDamage(uint32_t devId, uint32_t num, IRect *rect)
{
    DISPLAY_DEBUGLOG();
    (void)num;
    DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
    return DISPLAY_NOT_SUPPORT;
}

static int32_t SetDisplayVsyncEnabled(uint32_t devId, bool enabled)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayVsyncEnabled, enabled);
}

static int32_t RegDisplayVBlankCallback(uint32_t devId, VBlankCallback callback, void *data)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::RegDisplayVBlankCallback, callback, data);
}

static int32_t GetDisplayReleaseFence(uint32_t devId, uint32_t *num, uint32_t *layers, int32_t *fences)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayReleaseFence, num, layers,
                                                         fences);
}

static int32_t Commit(uint32_t devId, int32_t *fence)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((fence == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("fence is nullptr"));
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::Commit, fence);
}

static int32_t CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t *format, uint32_t *devId)
{
    DISPLAY_DEBUGLOG();
    return DISPLAY_NOT_SUPPORT;
}
static int32_t DestroyVirtualDisplay(uint32_t devId)
{
    DISPLAY_DEBUGLOG();
    return DISPLAY_NOT_SUPPORT;
}
static int32_t SetVirtualDisplayBuffer(uint32_t devId, BufferHandle *buffer, int32_t releaseFence)
{
    DISPLAY_DEBUGLOG();
    return DISPLAY_NOT_SUPPORT;
}

// Layer function
static int32_t CreateLayer(uint32_t devId, const LayerInfo *layerInfo, uint32_t *layerId)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((layerId == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("layerId is nullptr"));
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::CreateLayer, layerInfo, layerId);
}

static int32_t CloseLayer(uint32_t devId, uint32_t layerId)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::CloseLayer, layerId);
}

static int32_t SetLayerSize(uint32_t devId, uint32_t layerId, IRect *rect)
{
    DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerSize, rect);
}

static int32_t SetLayerCrop(uint32_t devId, uint32_t layerId, IRect *rect)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
    return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerCrop, rect);
}

static int32_t SetLayerZorder(uint32_t devId, uint32_t layerId, uint32_t zorder)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetLayerZorder, layerId, zorder);
}

static int32_t SetLayerPreMulti(uint32_t devId, uint32_t layerId, bool preMul)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerPreMulti, preMul);
}

static int32_t SetLayerAlpha(uint32_t devId, uint32_t layerId, LayerAlpha *alpha)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((alpha == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("alpha is nullptr"));
    return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerAlpha, alpha);
}

static int32_t SetTransformMode(uint32_t devId, uint32_t layerId, TransformType type)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetTransformMode, type);
}

static int32_t SetLayerDirtyRegion(uint32_t devId, uint32_t layerId, IRect *region)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((region == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("region is nullptr"));
    return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerDirtyRegion, region);
}

static int32_t SetLayerVisibleRegion(uint32_t devId, uint32_t layerId, uint32_t num, IRect *rect)
{
    DISPLAY_DEBUGLOG();
    DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
    return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerVisibleRegion, num, rect);
}

static int32_t SetLayerBuffer(uint32_t devId, uint32_t layerId, const BufferHandle *buffer, int32_t fence)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerBuffer, buffer, fence);
}

static int32_t SetLayerCompositionType(uint32_t devId, uint32_t layerId, CompositionType type)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerCompositionType, type);
}

static int32_t SetLayerBlendType(uint32_t devId, uint32_t layerId, BlendType type)
{
    DISPLAY_DEBUGLOG();
    return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerBlendType, type);
}

extern "C" {
int32_t DeviceInitialize(DeviceFuncs **funcs)
{
    DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in funcs is null"));
    DeviceFuncs *dFuncs = (DeviceFuncs *)calloc(1, sizeof(DeviceFuncs));
    if (dFuncs == nullptr) {
        DISPLAY_LOGE("can not calloc");
        return DISPLAY_FAILURE;
    }

    dFuncs->RegHotPlugCallback = RegHotPlugCallback;
    dFuncs->GetDisplayCapability = GetDisplayCapability;
    dFuncs->GetDisplaySupportedModes = GetDisplaySupportedModes;
    dFuncs->GetDisplayMode = GetDisplayMode;
    dFuncs->SetDisplayMode = SetDisplayMode;
    dFuncs->GetDisplayPowerStatus = GetDisplayPowerStatus;
    dFuncs->SetDisplayPowerStatus = SetDisplayPowerStatus;
    dFuncs->PrepareDisplayLayers = PrepareDisplayLayers;
    dFuncs->GetDisplayBacklight = GetDisplayBacklight;
    dFuncs->SetDisplayBacklight = SetDisplayBacklight;
    dFuncs->GetDisplayProperty = GetDisplayProperty;
    dFuncs->GetDisplayCompChange = GetDisplayCompChange;
    dFuncs->SetDisplayClientCrop = SetDisplayClientCrop;
    dFuncs->SetDisplayClientDestRect = SetDisplayClientDestRect;
    dFuncs->SetDisplayClientBuffer = SetDisplayClientBuffer;
    dFuncs->SetDisplayClientDamage = SetDisplayClientDamage;
    dFuncs->SetDisplayVsyncEnabled = SetDisplayVsyncEnabled;
    dFuncs->RegDisplayVBlankCallback = RegDisplayVBlankCallback;
    dFuncs->GetDisplayReleaseFence = GetDisplayReleaseFence;
    dFuncs->CreateVirtualDisplay = CreateVirtualDisplay;
    dFuncs->DestroyVirtualDisplay = DestroyVirtualDisplay;
    dFuncs->SetVirtualDisplayBuffer = SetVirtualDisplayBuffer;
    dFuncs->SetDisplayProperty = SetDisplayProperty;
    dFuncs->Commit = Commit;
    *funcs = dFuncs;
    DISPLAY_DEBUGLOG("%{public}s: device initialize success", __func__);
    HdiSession::GetInstance();
    return DISPLAY_SUCCESS;
}

int32_t DeviceUninitialize(DeviceFuncs *funcs)
{
    DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in funcs is null"));
    free(funcs);
    return DISPLAY_SUCCESS;
}

int32_t LayerInitialize(LayerFuncs **funcs)
{
    DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the in funcs is nullptr"));
    LayerFuncs *lFuncs = (LayerFuncs *)calloc(1, sizeof(LayerFuncs));
    if (lFuncs == nullptr) {
        DISPLAY_LOGE("can not calloc errno: %{public}d", errno);
        return DISPLAY_FAILURE;
    }
    lFuncs->SetLayerAlpha = SetLayerAlpha;
    lFuncs->CreateLayer = CreateLayer;
    lFuncs->CloseLayer = CloseLayer;
    lFuncs->SetLayerSize = SetLayerSize;
    lFuncs->SetLayerCrop = SetLayerCrop;
    lFuncs->SetLayerZorder = SetLayerZorder;
    lFuncs->SetLayerPreMulti = SetLayerPreMulti;
    lFuncs->SetTransformMode = SetTransformMode;
    lFuncs->SetLayerDirtyRegion = SetLayerDirtyRegion;
    lFuncs->SetLayerVisibleRegion = SetLayerVisibleRegion;
    lFuncs->SetLayerBuffer = SetLayerBuffer;
    lFuncs->SetLayerCompositionType = SetLayerCompositionType;
    lFuncs->SetLayerBlendType = SetLayerBlendType;

    *funcs = lFuncs;
    DISPLAY_DEBUGLOG("%{public}s: layer initialize success", __func__);
    return DISPLAY_SUCCESS;
}

int32_t LayerUninitialize(LayerFuncs *funcs)
{
    DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the funcs is nullptr"));
    free(funcs);
    DISPLAY_DEBUGLOG("%{public}s: layer uninitialize success", __func__);
    return DISPLAY_SUCCESS;
}
}