Camx Jump table 浅析

前言

每次在追CSL这块代码的的时候找着找着就被一堆函数指针指来指去,就把我给指晕了。好好的一个函数名被改过来改过去的。然后后面就是跟着自己的感觉来追的。

于是决定好好的找下这个jumptable到底是怎么回事。下面的这些都是我又是正向反向各种推找理出来的。然后按照顺序整理了一下。

流程讲解

在camx中有个camxsettings.xml文件里面有着各种各样的配置,什么dump图,log开关这些property都写在里面的。其中有个属性是CSLMode就是会决定我们最后jumptable会用到哪个类型的。

路径:camx/src/settings/common/camxsettings.xml

<setting>
    <Name>CSL Mode</Name>
    <Help>Selects run-time CSL mode</Help>
    <VariableName>CSLMode</VariableName>
    <VariableType>CSLModeType</VariableType>
    <SetpropKey>vendor.debug.camera.CSLMode</SetpropKey>
    <DefaultValue>Hardware</DefaultValue>
    <Dynamic>FALSE</Dynamic>
</setting>

其中上面的这个属性会被解析保存到struct StaticSettings这个结构中,后面感兴趣的话可以分析一下。会把这个值存放到params这个参数中。provider起来的时候会调用HwEnvironment初始化的函数,这个CSLMode会被传入到CSLInitializ函数。

路径:camx/src/core/camxhwenvironment.cpp

 CamxResult HwEnvironment::Initialize()
 {
    const StaticSettings* pStaticSettings = pStaticSettingsManager->GetStaticSettings();
	params.mode = pStaticSettings->CSLMode; 
	result = CSLInitialize(&params);
 }

CSLInitialize这里要注意函数名一样的有两个地方,一个是带参数的一个是没有带参数的。带参数的是没有范围限制的,没有带参数的是CSLJumpTable的成员是有范围的我们这里调用的时候带参数的,后面会调用到没有参数的CSLInitialize。这里的几个函数都很重要。

1.创建CSLModeManager

2.获取到刚刚创建的Jumptable实例

3.调用对用创建的JumpTable实例的初始化方法

路径:camx/src/csl/camxcsl.cpp 

CamxResult CSLInitialize(
     CSLInitializeParams* pInitializeParams)
{
    g_pCSLModeManager = CAMX_NEW CSLModeManager(pInitializeParams);
    CSLJumpTable* pJumpTable = g_pCSLModeManager->GetJumpTable();
    return pJumpTable->CSLInitialize();
}
1.创建CSLModeManager 

创建对应的 CSLModeManager里面主要就是通过我们之前获取到的CSLMode的数值来创建对应的Jumptanble实例。这个case里面的条件的表示方法好像跟之前的不太一样。其实数值是一样的就是枚举换了一个名字而已,可以参考一下对应的代码。

路径:camx/src/csl/camxcsljumptable.cpp

 CSLModeManager::CSLModeManager(
     const CSLInitializeParams* pInitParams)
{
     m_emulatedSensorParams = pInitParams->emulatedSensorParams;
 
     switch (pInitParams->mode)
     {
         case CSLMode::CSLHwEnabled:
             m_pJumpTable            = GetCSLJumpTableHw();
             m_mode                  = static_cast<CSLMode>(pInitParams->mode);
             break;
         case CSLMode::CSLIFHEnabled:                                                                                                                               
             m_pJumpTable            = GetCSLJumpTableIFH();                                                                                                         
             m_mode                  = static_cast<CSLMode>(pInitParams->mode);                                                                                     
             break; 
	}
}

路径: camx/src/csl/camxcsl.h

typedef enum
{
    CSLHwEnabled,           ///< HW Enabled
    CSLIFHEnabled,          ///< IFH Enabled
    CSLPresilEnabled,       ///< Presil CSIM Enabled 
    CSLPresilRUMIEnabled,   ///< Presil RUMI Enabled
} CSLMode; 

路径: camx/src/settings/g_camxsettings.h

enum CSLModeType
{
    CSLModeHardware,                        ///< Hardware CSL implementation, using the standard CamX KMD and hardware
    CSLModeIFH,                             ///< Infinitely Fast Hardware CSL implementation, bypassing the KMD
    CSLModePresil,                          ///< Presil CSIM CSL Implementation
    CSLModePresilRUMI,                      ///< Presil RUMI CSL Implementation
};

这里就是根据对应的mode去获取到对应类型的jumptable实例 

路径:camx/src/csl/hw/camxcslhw.cpp

CSLJumpTable* GetCSLJumpTableHw()
{
    return &g_CSLjumpTableHW;
}

路径:camx/src/csl/ifh/camxcslifh.cpp 

CSLJumpTable* GetCSLJumpTableIFH(void)                                                                                            
{                                                                                                                                                                   
    return &g_CSLjumpTableIFH;                                                                                         
}

这个是JumpTable的结构体定义和Hareware这个类型的结构体变量的定义,如果是其他类型的JumpTable也是一样的。

可以看出来JumpTable中定义的成员都是函数指针,所以定义这个结构体成员是需要对里面的指针进行定义的。然后不同类型的JumpTable调用这些指针就可以调用的对应不同类型定制的函数中。

路径:camx/src/csl/camxcsljumptable.h

struct CSLJumpTable
{
    CamxResult (*CSLInitialize)(void);

    CamxResult (*CSLUninitialize)(void);

    CamxResult (*CSLOpen)(
        CSLHandle* phCSL);

    CamxResult (*CSLClose)(
        CSLHandle hCSL);

    CamxResult (*CSLAddReference)(
        CSLHandle hCSL);

    CamxResult (*CSLQueryCameraPlatform)(
        CSLCameraPlatform* pCameraPlatform);

    CamxResult (*CSLImageSensorProbe)(
        CSLMemHandle                hPacket,
        SIZE_T                      offset,
        CSLImageSensorProbeResult*  pProbeResult);

    CamxResult (*CSLSetDebugBuffer)(
        CSLHandle               hCSL,
        CSLDebugBufferType      type,
        CSLMemHandle            hBuffer,
        SIZE_T                  offset,
        SIZE_T                  length,
        CSLDebugBufferResult*   pDebugBufferResult);

    CamxResult (*CSLEnumerateDevices)(
        CSLDeviceDescriptor* pDeviceDescriptor);

    CamxResult (*CSLQueryDeviceCapabilities)(
        INT32   deviceIndex,
        VOID*   pDeviceData,
        SIZE_T  deviceDataSize);

    CamxResult (*CSLAcquireDevice)(
        CSLHandle           hCSL,
        CSLDeviceHandle*    phDevice,
        INT32               deviceIndex,
        CSLDeviceResource*  pDeviceResourceRequest,
        SIZE_T              numDeviceResources,
        CSLDeviceAttribute* pDeviceAttribute,
        SIZE_T              numDeviceAttributes,
        const CHAR*         pDeviceName);

    CamxResult (*CSLReleaseDevice)(
        CSLHandle       hCSL,
        CSLDeviceHandle hDevice);

    CamxResult (*CSLLink)(
        CSLHandle           hCSL,
        CSLDeviceHandle*    phDevices,
        UINT                handleCount,
        CSLLinkHandle*      phLink);

    CamxResult (*CSLUnlink)(
        CSLHandle          hCSL,
        CSLLinkHandle*     phLink);

    CamxResult (*CSLSyncLinks)(
        CSLHandle           hCSL,
        CSLLinkHandle*      phLink,
        UINT                handleCount,
        CSLLinkHandle       hMasterhLink,
        CSLSyncLinkMode     syncMode);

    CamxResult  (*CSLOpenRequest)(
        CSLHandle          hCSL,
        CSLLinkHandle      hLink,
        UINT64             requestId,
        BOOL               bubble,
        CSLSyncLinkMode    syncMode,
        UINT32             expectedExposureTimeInMs);

    CamxResult  (*CSLCancelRequest)(
        CSLHandle           hCSL,
        const CSLFlushInfo& pCSLFlushInfo);

    CamxResult (*CSLStreamOn)(
        CSLHandle hCSL,
        CSLLinkHandle* phLink,
        CSLDeviceHandle* phDevices);

    CamxResult (*CSLStreamOff)(
        CSLHandle hCSL,
        CSLLinkHandle* phLink,
        CSLDeviceHandle* phDevices,
        CSLDeactivateMode mode);

    CamxResult(*CSLSingleDeviceStreamOn)(
        CSLHandle           hCSL,
        INT32               deviceIndex,
        CSLDeviceHandle*    phDevice);

    CamxResult(*CSLSingleDeviceStreamOff)(
        CSLHandle           hCSL,
        INT32               deviceIndex,
        CSLDeviceHandle*    phDevice);

    CamxResult (*CSLSubmit)(
        CSLHandle           hCSL,
        CSLDeviceHandle     hDevice,
        CSLMemHandle        hPacket,
        SIZE_T              offset);

    CamxResult(*CSLFlushLock)(
        CSLHandle           hCSL,
        const CSLFlushInfo& rCSLFlushInfo);

    CamxResult(*CSLFlushUnlock)(
        CSLHandle           hCSL);

    CamxResult (*CSLRegisterMessageHandler)(
        CSLHandle           hCSL,
        CSLLinkHandle       hCSLLinkHandle,
        CSLMessageHandler   handler,
        VOID*               pUserData);

    CamxResult (*CSLRegisterSessionMessageHandler)(
        CSLHandle                  hCSL,
        CSLSessionMessageHandler   msgHandler,
        VOID*                      pUserData);

    CamxResult (*CSLAlloc)(
        const CHAR*     pStr,
        CSLBufferInfo*  pBufferInfo,
        SIZE_T          bufferSize,
        SIZE_T          alignment,
        UINT32          flags,
        const INT32*    pDeviceIndices,
        UINT            deviceCount);

    CamxResult (*CSLMapBuffer)(
        CSLBufferInfo*  pBufferInfo,
        INT             bufferFD,
        SIZE_T          offset,
        SIZE_T          bufferLength,
        UINT32          flags,
        const INT32*    pDeviceIndices,
        UINT            deviceCount);

    CamxResult (*CSLMapNativeBuffer)(
        CSLBufferInfo*          pBufferInfo,
        const CSLNativeHandle*  phNativeBuffer,
        SIZE_T                  offset,
        SIZE_T                  bufferLength,
        UINT32                  flags,
        const INT32*            pDeviceIndices,
        UINT                    deviceCount);

    CamxResult (*CSLGetBufferInfo)(
        CSLMemHandle    hBuffer,
        CSLBufferInfo*  pBufferInfo);

    CamxResult (*CSLBufferCacheOp)(
        CSLMemHandle    hBuffer,
        BOOL            invalidate,
        BOOL            clean);

    CamxResult (*CSLReleaseBuffer)(
        CSLMemHandle hBuffer);

    CamxResult (*CSLReleaseBufferForced)(
        CSLMemHandle hBuffer);

    CamxResult (*CSLCreatePrivateFence)(
        const CHAR* pName,
        CSLFence*   pFenceOut);

    CamxResult (*CSLCreateNativeFence)(
        CSLNativeFenceCreateDataPtr pCreateData,
        CSLFence*                   pFenceOut);

    CamxResult (*CSLMergeFences)(
        CSLFence*   phFences,
        SIZE_T      fenceCount,
        CSLFence*   pFenceOut);

    CamxResult (*CSLGetFenceAttrib)(
        CSLFence    hFence,
        UINT32      attrib,
        VOID*       pAttribVal,
        UINT32      valSize);

    CamxResult (*CSLFenceWait)(
        CSLFence    hFence,
        UINT64      timeout);

    CamxResult (*CSLFenceWaitMultiple)(
        CSLFence*   phFences,
        BOOL*       pFenceSignaled,
        SIZE_T      fenceCount,
        UINT64      timeout);

    CamxResult (*CSLFenceAsyncWait)(
        CSLFence        hFence,
        CSLFenceHandler handler,
        VOID*           pUserData);

    CamxResult (*CSLFenceAsyncCancel)(
        CSLFence        hFence,
        CSLFenceHandler handler,
        VOID*           pUserData);

    CamxResult (*CSLFenceSignal)(
        CSLFence        hFence,
        CSLFenceResult  status);

    CamxResult (*CSLReleaseFence)(
        CSLFence hFence);

    CamxResult(*CSLAcquireHardware)(
        CSLHandle           hCSL,
        CSLDeviceHandle     hDevice,
        CSLDeviceResource*  pDeviceResourceRequest,
        UINT32              version);

    CamxResult(*CSLReleaseHardware)(
        CSLHandle       hCSL,
        CSLDeviceHandle hDevice);

    CamxResult (*CSLDumpRequest) (
        CSLHandle              hCSL,
        CSLDumpRequestInfo*    pDumpRequestInfo,
        SIZE_T*                pFilledLength);
};

这是Hareware的Mode对应的Jumptable,可以类比看出这个结构体变量中成员是跟上面一一对应的。所以说我们调用上面的那些函数指针的时候要确定我们的CSLMode,这样就可以快速找到我们用的是哪个类型的JumpTable了。

路径:camx/src/csl/hw/camxcslhw.cpp 

CSLJumpTable g_CSLjumpTableHW =
{
    CSLInitializeHW,
    CSLUninitializeHW,
    CSLOpenHW,
    CSLCloseHW,
    CSLAddReferenceHW,
    CSLQueryCameraPlatformHW,
    CSLImageSensorProbeHW,
    CSLSetDebugBufferHW,
    CSLEnumerateDevicesHW,
    CSLQueryDeviceCapabilitiesHW,
    CSLAcquireDeviceHW,
    CSLReleaseDeviceHW,
    CSLLinkHW,
    CSLUnlinkHW,
    CSLSyncLinksHW,
    CSLOpenRequestHW,
    CSLCancelRequestHW,
    CSLStreamOnHW,
    CSLStreamOffHW,
    CSLSingleDeviceStreamOnHW,
    CSLSingleDeviceStreamOffHW,
    CSLSubmitHW,
    CSLFlushLockHW,
    CSLFlushUnlockHW,
    CSLRegisterMessageHandlerHW,
    CSLRegisterSessionMessageHandlerHW,
    CSLAllocHW,
    CSLMapBufferHW,
    CSLMapNativeBufferHW,
    CSLGetBufferInfoHW,
    CSLBufferCacheOpHW,
    CSLReleaseBufferHW,
    CSLReleaseBufferForcedHW,
    CSLCreatePrivateFenceHW,
    CSLCreateNativeFenceHW,
    CSLMergeFencesHW,
    CSLGetFenceAttribHW,
    CSLFenceWaitHW,
    CSLFenceWaitMultipleHW,
    CSLFenceAsyncWaitHW,
    CSLFenceAsyncCancelHW,
    CSLFenceSignalHW,
    CSLReleaseFenceHW,
    CSLAcquireHardwareHW,
    CSLReleaseHardwareHW,
    CSLDumpRequestHW
};

 2.获取创建类型的Jumptable实例

这里要跟之前获取各个类型的jumptable区分。上面各个类型的时已经定义好的变量,这里是获取上面的jumpdable的一个保存,并且是CSLModeManager的一个成员变量。 

路径:camx/src/csl/camxcsljumptable.h

inline CSLJumpTable* GetJumpTable() const
{
    return m_pJumpTable;
}
3.调用JumpTable实例的初始化方法 

因为我们这个平台的CSLMode是Hardware所以我这里只举例了Hw相关的,看着这个初始化主要就是获取KMD的device还有SyncManager是跟request同步相关的,这个还是挺重要的后面研究一下展开说说。

路径:camx/src/csl/hw/camxcslhw.cpp

CamxResult CSLInitializeHW()
{
    CSLHwEnumerateAndAddCSLHwDevice(CSLInternalHwVideodevice, CAM_VNODE_DEVICE_TYPE);
    CSLHwEnumerateAndAddCSLHwDevice(CSLInternalHwVideoSubdevice, CAM_CPAS_DEVICE_TYPE);
    g_CSLHwInstance.pSyncFW = CamX::SyncManager::GetInstance();
    g_CSLHwInstance.pSyncFW->Initialize(syncDeviceName);
    CSLHwInstanceSetState(CSLHwValidState);
}

 这是我整理画出来的简单的函数流程图,感觉看起来还是比较清晰的,比那种只上代码的感觉要舒服很多,然后可以简单推断出对应的代码结构和函数调用结构这些。如果还有类图做搭配的话应该会更加清晰一些。等后面有时间在补充一下。看不清楚的可以放大看下。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值