//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// Copyright (c) Samsung Electronics. Co. LTD. All rights reserved.

/*++

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:

    display_main.h

Abstract:

    This module present class definition of SMDKDisp, SMDKSurf, PACSurf
    SMDKDisp class is derived from DDGPE
    SMDKSurf class is derived from DDGPESurf
    PACSurf class is derived from GPESurf

Functions:


Notes:

--*/

#ifndef __DISPLAY_MAIN_H__
#define __DISPLAY_MAIN_H__

class SMDKSurf;

class FIMGSE2D;

#include "precomp.h"
//#include "priv_context.h"
//#include "fimgse2d.h"

class SMDKDisp : public DDGPE
{

protected:
    CRegistryEdit *m_ActiveReg;
    volatile DISPLAY_REG    *m_pDispConReg;    // Display Controller SFR
    volatile GPIO_REG       *m_pGPIOReg;        // GPIO SFR
#ifdef USE_DSI
    volatile MIPIDSI_REG    *m_pMIPIDSIReg;     // MIPI DSI Controller SFR
#else
    volatile SPI_REG        *m_pSPIReg;        // SPI Controller SFR
#endif

    volatile BSP_ARGS *m_pBspArg;   // Argument Area

    SMDKSurf     *m_pVisibleSurface;
#ifdef OVERLAY_USE_MEM2MEM
    SMDKSurf     *m_pOverlayDMAOutputBuf[OVERLAY_FB_NUM];
#else
    SMDKSurf     *m_pOverlayDMAOutputBuf1;
#endif
    GPEModeEx       m_ModeInfoEx;
    FIMG2D        *m_oG2D;

    G2D_ACCEL_CONTROL_ARGS m_G2DControlArgs;

    /// for Cache Region Clean
    DWORD       m_dwSourceSurfacePA;
    DWORD       m_dwPhyAddrOfSurface[2];  //< [0] is for Source, [1] is for Destination

    HANDLE      m_hVideoDrv;
    DWORD       m_dwPrimaryWinNum;
    DWORD       m_dwPrimaryWinMode;
    DWORD       m_dwDDOverlayWinNum;
    DWORD       m_dwDDOverlayWinMode;

    CRITICAL_SECTION    m_csDevice;                // Critical Section for Display Device Control (FIMD/POST)
    CRITICAL_SECTION    m_cs2D;                // Ciritcal Section for 2D

    DDGPESurf *SrcCloneSurf;
    DDGPESurf *DstCloneSurf;

private:

    DWORD       m_dwDeviceScreenWidth;        // LCD Pannel Horizontal Resolution (Pixel Count)
    DWORD       m_dwDeviceScreenHeight;        // LCD Pannel Vertical Resolution (Pixel Count)

    DWORD       m_VideoMemoryPhysicalBase;
    DWORD       m_VideoMemoryVirtualBase;
    DWORD       m_VideoMemorySize;
    SurfaceHeap *m_pVideoMemoryHeap;            // Video Memory Surface Heap
#ifdef USE_CMM_FOR_YUVSURFACE
    HANDLE m_hCmmFB;
#endif

    UCHAR       m_CursorBackingStore[64*64*4];
    UCHAR       m_CursorXorShape[64*64];
    UCHAR       m_CursorAndShape[64*64];
    BOOL        m_CursorDisabled;
    BOOL        m_CursorVisible;
    BOOL        m_CursorForcedOff;
    RECTL       m_CursorRect;
    POINTL      m_CursorSize;
    POINTL      m_CursorHotspot;

    VIDEO_POWER_STATE   m_VideoPowerState;

    DISP_VIDOUT_MODE    m_eOutputInterface;

    OverlayContext      m_OverlayCtxt;
#ifdef OVERLAY_USE_MEM2MEM
    HANDLE m_hPostReadyEvent;
    HANDLE m_hPostBusyEvent;
    HANDLE m_hPostTreadEnd;
    BOOL m_bPostThreadExit;
    HANDLE m_hPostIST;
    unsigned int m_uiCurPostFB;
#endif

    GPESurf     *m_pLastSrcSurfUsingHW;
    GPESurf     *m_pLastDstSurfUsingHW;
    GPESurf     *m_pLastPatSurfUsingHW;
    GPESurf     *m_pLastMskSurfUsingHW;
    DWORD       m_dwLastProcessType;

// For APM
#ifdef SUPPORT_APM_DISP
    void Disp_power_set_APM(CEDEVICE_POWER_STATE APM_POWER_STATUS);
    void Disp_power_init_APM();
    void Disp_power_deinit_APM();
#endif
#ifdef USE_CMM_FOR_YUVSURFACE
    BOOL SMDKDisp::AllocCmmMemory(unsigned int uiSize, DWORD Loc,
                                    unsigned int* puiPhy, unsigned int* puiVir);
    void SMDKDisp::ReleaseCmmMemory(PBYTE pbVir);
#endif

public:

    BOOL        m_InDDraw;
    ULONG_PTR   m_fpCurrentOverlay;
    ULONG_PTR   m_fpPreviousOverlay;

    SMDKDisp();

    virtual
    ~SMDKDisp();

    virtual
    int
    NumModes();

    virtual
    SCODE
    SetMode(
        int            modeId,
        HPALETTE    * palette
        );

    virtual
    int
    InDisplay(void);

    virtual
    int
    InVBlank();

    virtual
    SCODE
    SetPalette(
        const PALETTEENTRY *source,
        USHORT        firstEntry,
        USHORT        numEntries
        );

    virtual
    SCODE
    GetModeInfo(
        GPEMode * pMode,
        int       modeNo
        );

    virtual
    SCODE
    GetModeInfoEx(
        GPEModeEx *pModeEx,
        int       modeNo
        );

    virtual
    SCODE
    SetPointerShape(
        GPESurf * mask,
        GPESurf * colorSurface,
        int       xHot,
        int       yHot,
        int       cX,
        int       cY
        );

    virtual
    SCODE
    MovePointer(
        int xPosition,
        int yPosition
        );

    virtual
    void
    WaitForNotBusy();

    virtual
    int
    IsBusy();

    virtual
    void
    GetPhysicalVideoMemory(
        unsigned long * physicalMemoryBase,
        unsigned long * videoMemorySize
        );

    void
    GetVirtualVideoMemory(
        unsigned long * virtualMemoryBase,
        unsigned long * videoMemorySize
        );

    virtual
    SCODE
    Line(
        GPELineParms * lineParameters,
        EGPEPhase      phase
        );

    // blt.cpp
    virtual
    SCODE
        BltPrepare(
        GPEBltParms * blitParameters
        );

    virtual
    SCODE
        BltComplete(
        GPEBltParms * blitParameters
        );

    // For 2D Raster Graphic Acceleration
    void InitAcceleration(void);
    virtual SCODE NullBlt(GPEBltParms *pBltParms);
    BOOL CompromizeForPerformance(GPEBltParms *pBltParms);
    virtual SCODE AcceleratedBltSelect(GPEBltParms *pBltParms);
	virtual SCODE AcceleratedBlt(GPEBltParms *pBltParms);
    BOOL IsSurfLinear(GPEBltParms *pBltParms);
    BOOL CreateCloneSurf(void);
    BOOL ReleaseCloneSurf(void);
#if USE_SECEMUL_LIBRARY
    virtual SCODE SECEmulatedBltSelect2416(GPEBltParms *pBltParms);
    virtual SCODE SECEmulatedBltSelect1624(GPEBltParms *pBltParms);
    virtual SCODE SECEmulatedBltSelect16(GPEBltParms *pBltParms);
#endif
    virtual DWORD ValidatePAContinuityOfSurf(GPESurf *pTargetSurf, RECTL *pTargetRectl);
    virtual void FreePhysAddress(DWORD *m_pdwPhysAddress);
    virtual void ClipDestDrawRect(GPEBltParms *pBltParms);

    virtual
    ULONG
    DrvEscape(
        SURFOBJ * pso,
        ULONG     iEsc,
        ULONG     cjIn,
        void    * pvIn,
        ULONG     cjOut,
        void    * pvOut
        );

    int
    GetGameXInfo(
        ULONG   iEsc,
        ULONG   cjIn,
        void  * pvIn,
        ULONG   cjOut,
        void  * pvOut
        );

    int
    GetRawFrameBuffer(
        ULONG   iEsc,
        ULONG   cjIn,
        void  * pvIn,
        ULONG   cjOut,
        void  * pvOut
        );

    SCODE
    WrappedEmulatedLine(
        GPELineParms * lineParameters
        );

    void
    CursorOn();

    void
    CursorOff();

    // surf.cpp
    SCODE
    AllocSurface(
        GPESurf    ** ppSurf,
        int           width,
        int           height,
        EGPEFormat    format,
        int           surfaceFlags
        );

    SCODE
    AllocSurface(
        DDGPESurf         ** ppSurf,
        int                  width,
        int                  height,
        EGPEFormat           format,
        EDDGPEPixelFormat    pixelFormat,
        int                  surfaceFlags
        );

    SCODE
    AllocSurfaceVideo(
        DDGPESurf        ** ppSurf,
        int                width,
        int                height,
        int                stride,
        EGPEFormat           format,
        EDDGPEPixelFormat    pixelFormat
        );

    SCODE
    AllocSurfaceVideo(GPESurf **ppSurf,
                            int width,
                            int height,
                            EGPEFormat format);


    SCODE
    AllocSurfacePACS(
        GPESurf **ppSurf,
        int width,
        int height,
        EGPEFormat format,
        int stride = 0,
        EDDGPEPixelFormat pixelFormat = ddgpePixelFormat_UnknownFormat
        );


    virtual
    void
    SetVisibleSurface(
        GPESurf * pSurf,
        BOOL      bWaitForVBlank
        );

    int
    GetRotateModeFromReg();

    void
    SetRotateParams();

    long
    DynRotate(
        int angle
        );

    virtual
    SCODE DetectPixelFormat(
        DWORD                dwCaps,            // in: DDSCAPS_xxx flags
        DDPIXELFORMAT*        pDDPF,            // in: Explicit pixel format or current mode
        EGPEFormat*            pFormat,
        EDDGPEPixelFormat*    pPixelFormat
        );

    //---------------------------
    // Resource Alloc/Release Method
    //---------------------------
    BOOL AllocResource(void);
    void ReleaseResource(void);

    //------------------------
    // Power Management Handler
    //------------------------
    void SetDisplayPowerState(VIDEO_POWER_STATE PowerState);
    VIDEO_POWER_STATE GetDisplayPowerState(void);

    //----------------------------------------
    // H/W Device Control Wrapper Method
    //----------------------------------------

    // Frame Interrupt / Status
    BOOL WaitForVerticalBlank(VB_STATUS Status);
    DWORD GetScanLine(void);

    // Overlay Control
    BOOL OverlayAllocResource(BOOL bPostAttached);
    BOOL OverlayReleaseResource(BOOL bPostAttached);
    BOOL OverlayInitialize(SMDKSurf* pOverlaySurface, RECT *pSrc, RECT *pDest);
    void OverlaySetPosition(UINT32 uiOffsetX, UINT32 uiOffsetY);
    void OverlayEnable(void);
    void OverlayDisable(void);
    void OverlayBlendDisable(void);
    void OverlaySetColorKey(BOOL bSrcCKey, EDDGPEPixelFormat Format, DWORD ColorKey);
    void OverlaySetAlphaPlane(DWORD Alpha);
    void OverlaySetAlphaPixel(BOOL bSrcAlpha);
    void OverlaySetColorKeyWithAlpha(BOOL bSrcCKey, EDDGPEPixelFormat Format, DWORD ColorKey, DWORD Alpha);

    void InitalizeOverlayContext(void);
    SMDKSurf * GetCurrentOverlaySurf(void);
    SMDKSurf * GetPreviousOverlaySurf(void);

    //--------------------------------
    // H/W Device Control Method
    //--------------------------------

    // Initialize / Power Management
    BOOL DevInitialize(void);
    BOOL DevPowerOn(void);
    BOOL DevPowerOff(void);

    // Change Interface
    void DevOutputEnableRGBIF(void);
    void DevOutputDisableRGBIF(void);

    // Frame Interrupt / Status
    BOOL DevWaitForVerticalBlank(void);
    int DevGetVerticalStatus(void);
    DWORD DevGetScanLine(void);

    // Change Frame Buffer
    void DevSetVisibleSurface(SMDKSurf *pSurf, BOOL bWaitForVBlank);

    // Overlay Control
    void DevOverlayInitialize(void);
    void DevOverlaySetPosition(void);
    void DevOverlayEnable(void);
    void DevOverlayDisable(void);
    void DevOverlayBlendDisable(void);
    void DevOverlaySetColorKey(void);
    void DevOverlaySetAlpha(void);
    void DevOverlaySetColorKeyWithAlpha(void);
    void DevRecoverOverlay(void);
    void InitializeDisplayMode(void);
#ifdef OVERLAY_USE_MEM2MEM
    void Post_thread(void);
#endif

friend
    void
    buildDDHALInfo(
        LPDDHALINFO lpddhi,
        DWORD       modeidx
        );
};

class SMDKSurf : public DDGPESurf
{
private:
    SurfaceHeap*    m_pSurfHeap;

public:
    UINT32    m_uiOffsetCb;
    UINT32    m_uiOffsetCr;

#ifdef USE_CMM_FOR_YUVSURFACE
    HANDLE m_hCmmFB;

    SMDKSurf(int, int, DWORD, VOID*, int, EGPEFormat,
                EDDGPEPixelFormat pixelFormat, HANDLE hCmmFB);
#endif
    SMDKSurf(int, int, DWORD, VOID*, int, EGPEFormat,
                EDDGPEPixelFormat pixelFormat, SurfaceHeap*);

    virtual
    ~SMDKSurf();

    //VOID  WriteBack();
    //VOID  Discard();
};

class PACSurf : public DDGPESurf
{
public:
    // For allocation on System Memory
    PACSurf(
        int width,
        int height,
        EGPEFormat format,
        int stride = 0,
        EDDGPEPixelFormat pixelFormat = ddgpePixelFormat_UnknownFormat);

    // For allocation on Video Memory
    PACSurf(
        int         width,
        int         height,
        DWORD       dwOffset,
        void *      pBits,            // virtual address of allocated bits
        EGPEFormat  format,
        SurfaceHeap *pHeap
        );
    virtual ~PACSurf();

private:
    SurfaceHeap*    m_pSurfHeap;
    int             m_fPLAllocated;
public:
    ADDRESS         m_pPhysAddr;        // Physical address of memory (contiguous and 64KB-aligned)
    ADDRESS         m_pKernelVirtAddr;  // Virtual address of memory, before mapping to caller (m_pVirtAddr)
    HANDLE          m_hUserProcess;

};

#endif __DISPLAY_MAIN_H__
