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

📄 pg_render.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2005-2006 Videon Central, Inc.                            **
**  All rights reserved.                                                    **
**                                                                          **
**  The computer program contained herein contains proprietary information  **
**  which is the property of Videon Central, Inc.  The program may be used  **
**  and/or copied only with the written permission of Videon Central, Inc.  **
**  or in accordance with the terms and conditions stipulated in the        **
**  agreement/contract under which the programs have been supplied.         **
**                                                                          **
******************************************************************************
*****************************************************************************/
/**
 * @file pg_render.cpp
 *
 * $Revision: 1.3 $ 
 *
 * render functions for the PG module
 *
 */

#include "vcitypes.h"
#include "pg_defs.h"
#include "pg_parse.h"
#include "pg_util.h"
#include "pg_render.h"
#include "pg_graphics.h"

#define DEBUG_PG_RENDER DBG_ERROR
#define DBG_ON(x)       (DEBUG_PG_RENDER >= x)

/* local prototypes */
static PG_STATUS PGWaitForPTS(ULONG PTS);

/* extern'd */
extern int FrameTimes[16];
extern PALETTE PGPalettes[PG_MAX_PALETTES];
extern OBJECT_DEFINITION_SEGMENT PGObjList[PG_MAX_ODS];
extern PGINFO PGInfo;

/**
 * RenderPCS - draw the objects in a Presentation Composition Segment to our buffer
 *
 * @param PCS *RenderMe - The PCS object to render
 *
 * @return PG_STATUS
 */
PG_STATUS RenderPCS(PRESENTATION_COMPOSITION_SEGMENT *RenderMe)
{
    int i;
    BYTE fUpdateScreen;

    if (NULL == RenderMe)
    {
        DbgPrint(("RenderPCS - Got Null PCS\n"));
        return PG_STATUS_ERROR;
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("\nRendering PCS, CurPTS=0x%x\n", PGInfo.CurPTS));

    /* always release and copy the new pcs when we get a new one, we will always have an old one
     * this way after the first */
    if (PGInfo.RenderPCS != RenderMe)
    {
        if (PGInfo.RenderPCS)
        {
            /* free the composition objects and PCS memory */
            ReleasePCS(PGInfo.RenderPCS);
            PGInfo.RenderPCS = NULL;
        }

        /* now take the current one */
        PGInfo.RenderPCS = RenderMe;
    }

    /* get screen width and height */
    PGInfo.DFBInfo.ScreenWidth  = PGInfo.RenderPCS->VideoDesc.Width;
    PGInfo.DFBInfo.ScreenHeight = PGInfo.RenderPCS->VideoDesc.Height;

    /* grab the palette we want */
    PALETTE Pal = PGPalettes[PGInfo.RenderPCS->PaletteIDRef];

    /* if this is a palette only update, flip and leave */
    if (1 == PGInfo.RenderPCS->PaletteUpdateFlag)
    {
        if (PGGraphicsSetPalette(&Pal) != PG_STATUS_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("RenderPCS: failed to set palette\n"));

            /* set pcs to not active */
            PGInfo.RenderPCS->fPCSShowing = FALSE;
            return (PG_STATUS_ERROR);
        }

        /* on palette only updates we need to build a flipping
         * region since we don't have any new images to work with */
        PGGraphicsBuildFlipRegion();

        /* wait for the PTS given in the pes header */
        PGWaitForPTS(PGInfo.RenderPCS->PTSDisplayTime);

        return (PG_STATUS_SUCCESS);
    }

    /* set the size of the display layer */
    PGInfo.DFBInfo.ScreenWidth  = PGInfo.RenderPCS->VideoDesc.Width;
    PGInfo.DFBInfo.ScreenHeight = PGInfo.RenderPCS->VideoDesc.Height;

    /* clear buffer in prep for display update */
    PGGraphicsClearBuffer(&fUpdateScreen, PGInfo.BlitLock);

    /* check for number of compositions  */
    if (PGInfo.RenderPCS->NumCompositionObjects > 0)
    {
        /* set the pcs to active */
        PGInfo.RenderPCS->fPCSShowing = TRUE;

        /* check the PCS forced flag and showgraphics flag */
        if (PGInfo.RenderPCS->fPCSHasForced || (PG_SHOW_GRAPHICS == PGInfo.ShowGraphics))
        {
            /* walk the list of composition objects and look them up in the palette and draw one at a time */
            for (i=0; i<PGInfo.RenderPCS->NumCompositionObjects; i++)
            {
                if (PG_SHOW_GRAPHICS == PGInfo.ShowGraphics)
                {
                    PGGraphicsDrawCompObj(&PGInfo.RenderPCS->CompObjs[i]);
                    fUpdateScreen = 1;
                }
                else if (PG_HIDE_GRAPHICS == PGInfo.ShowGraphics)
                {
                    if (PGInfo.RenderPCS->CompObjs[i].ForcedOnFlag)
                    {
                        PGGraphicsDrawCompObj(&PGInfo.RenderPCS->CompObjs[i]);
                        fUpdateScreen = 1;
                    }
                }
            }
        }
    }
    else
    {
        /* set pcs to not fPCSShowing */
        PGInfo.RenderPCS->fPCSShowing = FALSE;
    }

    /* show the display update if we have dirtied the screen */
    if (fUpdateScreen == 1)
    {
        /* set the palette for the primary surface */
        if (PGGraphicsSetPalette(&Pal) != PG_STATUS_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("RenderPCS: failed to set palette\n"));

            /* set pcs to not active */
            PGInfo.RenderPCS->fPCSShowing = FALSE;
            return (PG_STATUS_ERROR);
        }

        /* wait for the PTS given in the pes header */
        PGWaitForPTS(PGInfo.RenderPCS->PTSDisplayTime);
    }

    return PG_STATUS_SUCCESS;
}


/**
 * ReleasePCS - release the given pcs
 *
 * @param PCS *pcs - The PCS object to release
 *
 * @return PG_STATUS
 */
PG_STATUS ReleasePCS(PRESENTATION_COMPOSITION_SEGMENT *pcs)
{
    if (pcs == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("ReleasePCS() -- null pointer!\n"));
        return (PG_STATUS_ERROR);
    }

    /* cleanup */
    if (pcs->CompObjs != NULL)
    {
        OS_MemFree(pcs->CompObjs);
        pcs->CompObjs = NULL;
    }

    OS_MemFree(pcs);

    return (PG_STATUS_SUCCESS);
}


/**
 * PGWaitForPTS - wait for a PTS to show up
 *
 * @return VOID
 */
PG_STATUS PGWaitForPTS(ULONG PTS)
{
    /* first check if the time has already passed that we want, if so just return */
    if (PGInfo.CurPTS < PTS)
    {
        /* setup the RenderWait IG_WAIT_TIME_SEM to block and wait for the PTS we want */
        PGInfo.RenderWait.WaitTime.WaitPTS = PTS;
        PGInfo.RenderWait.WaitTime.Enabled = 1;

        /* now block wait for the time to show, we awake via UpdateTimeStamp() semgive */
        OS_SemTake(PGInfo.RenderWait.WaitSem, OS_WAIT_FOREVER);

        PGInfo.RenderWait.WaitTime.WaitPTS = 0;
        PGInfo.RenderWait.WaitTime.Enabled = 0;
    }

    return PG_STATUS_SUCCESS;
}

⌨️ 快捷键说明

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