⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddipu_sdc_overlay.cpp

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
//  Copyright (C) 2004-2005, MOTOROLA, INC. All Rights Reserved
//  THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
//  BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
//  MOTOROLA, INC.
//------------------------------------------------------------------------------
//
//  Copyright (C) 2005-2007, Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//
//  File:  ddipu_sdc_overlay.cpp
//
//  Implementation of Overlay-related functions for DDIPU_SDC class, the
//  DirectDraw display driver.
//
//-----------------------------------------------------------------------------
#include "precomp.h"

//-----------------------------------------------------------------------------
// External Functions


//-----------------------------------------------------------------------------
// External Variables


//-----------------------------------------------------------------------------
// Defines

#define LOCK_PP()      EnterCriticalSection(&m_csPPLock)
#define UNLOCK_PP()    LeaveCriticalSection(&m_csPPLock)

#if defined(PLAT_WPC) || defined(PLAT_SMARTPHONE)

#define IsOverlayMirrorUpDown(pd) (pd->dwFlags & DDOVER_MIRRORUPDOWN)

#else // PLAT_WPC || PLAT_SMARTPHONE

#define IsOverlayMirrorUpDown(pd) ((pd->dwFlags & DDOVER_DDFX) && (pd->overlayFX.dwDDFX & DDOVERFX_MIRRORUPDOWN))

#endif

#define DDOVER_KEY \
    (DDOVER_KEYSRC | \
     DDOVER_KEYSRCOVERRIDE |\
     DDOVER_KEYDEST | \
     DDOVER_KEYDESTOVERRIDE)

#define DUMP_OVERLAY_OP()     {\
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->nBufPhysicalAddr 0x%08x\r\n"), m_pOverlaySurfaceOp->nBufPhysicalAddr));                                    \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->Width            %d\r\n"), m_pOverlaySurfaceOp->Width));                                                \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->Height           %d\r\n"), m_pOverlaySurfaceOp->Height));                                                \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->WidthHw          %d\r\n"), m_pOverlaySurfaceOp->WidthHw));                                                \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->HeightHw         %d\r\n"), m_pOverlaySurfaceOp->HeightHw));                                                \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->LineStride       %d\r\n"), m_pOverlaySurfaceOp->LineStride));                                            \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->XOffset          %d\r\n"), m_pOverlaySurfaceOp->XOffset));                                                \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->YOffset          %d\r\n"), m_pOverlaySurfaceOp->YOffset));                                                \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->Transparency     %d\r\n"), m_pOverlaySurfaceOp->Transparency));                                            \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->isUpsideDown     %s\r\n"), m_pOverlaySurfaceOp->isUpsideDown ? L"TRUE" : L"FALSE"));                    \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->ColorKeyMask     0x%08x\r\n"), m_pOverlaySurfaceOp->ColorKeyMask));                                        \
}


//-----------------------------------------------------------------------------
// Types


//-----------------------------------------------------------------------------
// Global Variables


//-----------------------------------------------------------------------------
// Local Variables


//-----------------------------------------------------------------------------
// Local Functions

BOOL IsOverlaySurfEqual(pOverlaySurf_t pSurf1, pOverlaySurf_t pSurf2);

//------------------------------------------------------------------------------
//
// Function: UpdateOverlay
//
// This function repositions or modifies the visual
// attributes of an overlay surface.
//
// Parameters:
//      pd
//          [in, out] Pointer to a DDHAL_UPDATEOVERLAYDATA structure that
//          contains the information required to update the overlay surface.
//
// Returns:
//      Returns one of the following values:
//       DDHAL_DRIVER_HANDLED
//       DDHAL_DRIVER_NOTHANDLED
//
//------------------------------------------------------------------------------
DWORD DDIPU_SDC::UpdateOverlay(LPDDHAL_UPDATEOVERLAYDATA pd)
{
    /*
    typedef struct _DDHAL_UPDATEOVERLAYDATA
    {
        LPDDRAWI_DIRECTDRAW_GBL     lpDD;           // driver struct
        LPDDRAWI_DDRAWSURFACE_LCL   lpDDDestSurface;// dest surface
        RECTL                       rDest;          // dest rect
        LPDDRAWI_DDRAWSURFACE_LCL   lpDDSrcSurface; // src surface
        RECTL                       rSrc;           // src rect
        DWORD                       dwFlags;        // flags
        DDOVERLAYFX                 overlayFX;      // overlay FX
        HRESULT                     ddRVal;         // return value
        LPDDHALSURFCB_UPDATEOVERLAY UpdateOverlay;  // PRIVATE: ptr to callback
    } DDHAL_UPDATEOVERLAYDATA;
    */
    overlaySurf_t overlaySurfInfo;

    DDGPESurf* pSrcSurf = DDGPESurf::GetDDGPESurf(pd->lpDDSrcSurface);

    if (pd->dwFlags & DDOVER_HIDE)
    {
        DEBUGMSG(GPE_ZONE_HW, (TEXT("DDIPU_SDC::OVERLAY HIDE REQUEST\r\n")));
        if (pSrcSurf == m_pVisibleOverlay)
        {
            // If it was running, stop the post-processor
            if (((m_iRotate != 0) || (pSrcSurf->PixelFormat() == ddgpePixelFormat_UYVY422) || (pSrcSurf->PixelFormat() == ddgpePixelFormat_YV12))
                    && (m_PPConfiguration == PPConfiguration_Overlay))
            {
                // Do not stop PP until...
                // 1) There are no messages in the PP operation queue
                // 2) The PP Overlay thread is done working on the last operation

                while(WaitForSingleObject(m_hReadPPOverlayQueue, 0) == WAIT_OBJECT_0)
                {
                    // Sleep for a while since there are still operations in the queue
                    Sleep(10);
                }

                // If we are here, there are no operations left in the queue.
                // Now, wait here if the PP is processing last operation.
                EnterCriticalSection(&m_csOverlayShutdown);

                LOCK_PP();
                // In case we are in TV mode, let TV update thread know
                // to restart PP
                m_PPConfiguration = PPConfiguration_None;
                PPStop(m_hPP);
                UNLOCK_PP();

                LeaveCriticalSection(&m_csOverlayShutdown);

            }

            // hide the overlay
            //WaitForVSync();
            DisableOverlay();
            // reset visible overlay
            m_pVisibleOverlay = NULL;
            DEBUGMSG(GPE_ZONE_HW, (TEXT("DDIPU_SDC::OVERLAY HIDE!\r\n")));
        }
        else
        {
            // the overlay is not currently visible
            // nothing we need to do here
        }

        pd->ddRVal = DD_OK;
        return DDHAL_DRIVER_HANDLED;
    }

    DDGPESurf* pDstSurf = DDGPESurf::GetDDGPESurf(pd->lpDDDestSurface);

    if (pSrcSurf != m_pVisibleOverlay)
    {
        if (pd->dwFlags & DDOVER_SHOW)
        {
            DEBUGMSG(GPE_ZONE_HW, (TEXT("DDIPU_SDC::OVERLAY SHOW REQUEST\r\n")));
            if (m_pVisibleOverlay != NULL)
            {
                // some other overlay is already visible
                DEBUGMSG(GPE_ZONE_ERROR,
                          (TEXT("Error: Other overlay already visible!\r\n")));
                pd->ddRVal = DDERR_OUTOFCAPS;
                return DDHAL_DRIVER_HANDLED;
            }
            else
            {
                // we are going to make the overlay visible
                // so mark it as such:
                m_pVisibleOverlay = pSrcSurf;
                DEBUGMSG(GPE_ZONE_HW, (TEXT("DDIPU_SDC::OVERLAY SHOW\r\n")));
            }
        }
        else // DDOVER_SHOW not requested
        {
            // the overlay isn't visible, and we haven't been
            // asked to make it visible, so nothing we need to do
            pd->ddRVal = DD_OK;
            return DDHAL_DRIVER_HANDLED;
        }
    }

    overlaySurfInfo.Width   = (UINT16)(pd->rDest.right - pd->rDest.left);
    overlaySurfInfo.Height  = (UINT16)(pd->rDest.bottom - pd->rDest.top);

    switch(m_iRotate)
    {
        case DMDO_0:
        case DMDO_180:
            overlaySurfInfo.WidthHw = overlaySurfInfo.Width;
            overlaySurfInfo.HeightHw = overlaySurfInfo.Height;
            break;

        case DMDO_90:
        case DMDO_270:
            // Rotation currently not supported...we need post-processing
            // support to perform rotation
//            DEBUGMSG(GPE_ZONE_ERROR,
//                (TEXT("Error: Rotation unsupported...aborting\r\n")));
//            pd->ddRVal = DDERR_UNSUPPORTED;
//            return DDHAL_DRIVER_HANDLED;
            overlaySurfInfo.WidthHw = overlaySurfInfo.Height;
            overlaySurfInfo.HeightHw = overlaySurfInfo.Width;
            break;
    }

    overlaySurfInfo.SrcRect.left = pd->rSrc.left;
    overlaySurfInfo.SrcRect.top = pd->rSrc.top;
    overlaySurfInfo.SrcRect.right = pd->rSrc.right;
    overlaySurfInfo.SrcRect.bottom = pd->rSrc.bottom;

    // Parameter validity check
    if((pd->rDest.right  > m_pMode->width)  ||
        (pd->rDest.bottom > m_pMode->height) ||
        (overlaySurfInfo.WidthHw < DISP_MIN_WIDTH) ||
        (m_iRotate && ((overlaySurfInfo.WidthHw & 0x7) || (overlaySurfInfo.HeightHw & 0x7))))
    {
        DEBUGMSG(GPE_ZONE_ERROR, (TEXT("%s: wrong parameters!\r\n"), __WFUNCTION__));
        DUMP_OVERLAY_OP();

        // We are aborting, so set the overlay to NULL
        m_pVisibleOverlay = NULL;

        pd->ddRVal = DDERR_INVALIDPARAMS;
        return DDHAL_DRIVER_HANDLED;
    }

    overlaySurfInfo.Bpp = m_pMode->Bpp;

    overlaySurfInfo.LineStride = overlaySurfInfo.WidthHw * m_pMode->Bpp / 8;

    SetupOverlayPosition(&overlaySurfInfo, pd->rDest.left, pd->rDest.top);

    // In TV mode, screen should remain unrotated.
    if (m_bTVModeActive)
    {
        overlaySurfInfo.XOffset = (UINT16)pd->rDest.left;
        overlaySurfInfo.YOffset = (UINT16)pd->rDest.top;
    }

    overlaySurfInfo.nBufPhysicalAddr = m_nLAWPhysical + pSrcSurf->OffsetInVideoMemory();

    // Setup if overlay is flipped as upside-down
    if(IsOverlayMirrorUpDown(pd))
    {
        DEBUGMSG(GPE_ZONE_HW, (TEXT("DDIPU_SDC UpdateOverlay: upside-down overlay is requested!\r\n")));
        overlaySurfInfo.isUpsideDown = TRUE;
    }
    else
    {
        overlaySurfInfo.isUpsideDown = FALSE;
    }

    // Setup color key.
    // IPU only supports one color key value and does not
    // support a range.  So, we take the low value
    // from the color key mask to use as the color key.

    // Initialize color key mask to 0xFFFFFFFF.  If no color keying
    // is specified, this 0xFFFFFFFF will indicate no color key.
    overlaySurfInfo.ColorKeyMask = 0xFFFFFFFF;

    // Default Graphics Window as Foreground.
    // GW should only be Background in case of Destination Color Keying.
    overlaySurfInfo.ColorKeyPlane = DisplayPlane_1;


    if(pd->dwFlags & DDOVER_KEYSRC)
    {
        overlaySurfInfo.ColorKeyMask = pd->lpDDDestSurface->ddckCKSrcOverlay.dwColorSpaceLowValue;
        overlaySurfInfo.ColorKeyPlane = DisplayPlane_1;
    }
    else if(pd->dwFlags & DDOVER_KEYSRCOVERRIDE)
    {
        overlaySurfInfo.ColorKeyMask = pd->overlayFX.dckSrcColorkey.dwColorSpaceLowValue;
        overlaySurfInfo.ColorKeyPlane = DisplayPlane_1;
    }

    if(pd->dwFlags & DDOVER_KEYDEST)
    {
        overlaySurfInfo.ColorKeyMask = pd->lpDDDestSurface->ddckCKDestOverlay.dwColorSpaceLowValue;
        overlaySurfInfo.ColorKeyPlane = DisplayPlane_0;

    }
    else if(pd->dwFlags & DDOVER_KEYDESTOVERRIDE)
    {
        overlaySurfInfo.ColorKeyMask = pd->overlayFX.dckDestColorkey.dwColorSpaceLowValue;
        overlaySurfInfo.ColorKeyPlane = DisplayPlane_0;

        // TODO: This is a hack required because of incompatibilities between DDraw
        // and rotation.  The wrong color key is provided in rotation mode if
        // this is not included.  For Windows Media Player, this should always
        // be the color key: 0x841
        if (m_iRotate)
        {
            //DEBUGMSG(1, (TEXT("DDIPU_SDC UpdateOverlay: Color Key hack - set to 0x841 for CE player overlay.\r\n")));
            overlaySurfInfo.ColorKeyMask = 0x841;
        }
    }

    // TODO: setup alpha blending
    overlaySurfInfo.Transparency = 0;

    // If overlay surface data has not changed, skip
    // step to set up overlay and return.
    if (!IsOverlaySurfEqual(m_pOverlaySurfaceOp, &overlaySurfInfo))
    {
        overlaySurfInfo.isOverlayWindowRunning = m_pOverlaySurfaceOp->isOverlayWindowRunning;
        memcpy(m_pOverlaySurfaceOp, &overlaySurfInfo, sizeof(overlaySurf_t));

        // Update the graphic window of the IPU display
        pd->ddRVal = EnableOverlay(pSrcSurf);
    }
    else
    {
        pd->ddRVal = DD_OK;
    }

    return DDHAL_DRIVER_HANDLED;
}


//------------------------------------------------------------------------------
//
// Function: SetOverlayPosition
//
// This callback function changes the display coordinates of
// an overlay surface.
//
// Parameters:
//      pd
//          [in, out] Pointer to a DDHAL_SETOVERLAYPOSITIONDATA structure
//          that contains the information required to change the display
//          coordinates of an overlay surface.
//
// Returns:
//      Returns one of the following values:
//       DDHAL_DRIVER_HANDLED
//       DDHAL_DRIVER_NOTHANDLED
//
//------------------------------------------------------------------------------
DWORD DDIPU_SDC::SetOverlayPosition(LPDDHAL_SETOVERLAYPOSITIONDATA pd)
{
    /*
    typedef struct _DDHAL_SETOVERLAYPOSITIONDATA
    {
        LPDDRAWI_DIRECTDRAW_GBL     lpDD;           // driver struct
        LPDDRAWI_DDRAWSURFACE_LCL   lpDDSrcSurface; // src surface
        LPDDRAWI_DDRAWSURFACE_LCL   lpDDDestSurface;// dest surface
        LONG                        lXPos;          // x position
        LONG                        lYPos;          // y position
        HRESULT                     ddRVal;         // return value
        LPDDHALSURFCB_SETOVERLAYPOSITION SetOverlayPosition;
                                                    // PRIVATE: ptr to callback
    } DDHAL_SETOVERLAYPOSITIONDATA;
    */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -