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

📄 pg_graphics.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  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_graphics.cpp
 *
 * $Revision: 1.4 $ 
 *
 * PG graphics drawing routines
 *
 */

#include "pg_api.h"
#include "pg_defs.h"
#include "pg_util.h"
#include "pg_graphics.h"
#include "directfb.h"

#ifdef DMALLOC
#include "dmalloc.h"
#endif

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

DFBRegion gPGFlipRegion;
DFBRectangle PGCleanupList[PG_MAX_ODS];  /* our list of objects to clean on screen */
ULONG gPGImageIndex = 0;

/* externs */
extern PALETTE PGPalettes[PG_MAX_PALETTES];
extern OBJECT_DEFINITION_SEGMENT PGObjList[PG_MAX_ODS];
extern PGINFO PGInfo;
extern PGSTATS PGStats;

/* local prototypes */
void PGAddToCleanupList(int X, int Y, int Width, int Height);

/**
 * PGGraphicsSetPalette - update the palette for the currently displayed surface
 *
 * @param PALETTE *Pal - The palette to set on DirectFB
 *
 * @return PG_STATUS
 */
PG_STATUS PGGraphicsSetPalette(PALETTE *Pal)
{
    if (NULL == Pal)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PG: Invalid palette\n"));
        return PG_STATUS_ERROR;
    }

    if (NULL == Pal->DFBPal)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PG: Invalid DFB palette\n"));
        return PG_STATUS_ERROR;
    }

    /* set the palette for the primary surface */
    if (Pal->DFBPal->SetEntries(Pal->DFBPal, Pal->Colors, PG_MAX_PALETTE_COLORS, 0) != DFB_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsSetPalette(): Failed to set palette entries\n"));
        return PG_STATUS_ERROR;
    }

    /* set palette for primary surface */
    if (DFB_OK != PGInfo.DFBInfo.PrimarySurface->SetPalette(PGInfo.DFBInfo.PrimarySurface, Pal->DFBPal))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("Failed to set palette\n"));
        return PG_STATUS_ERROR;
    }

    return PG_STATUS_SUCCESS;
}

/**
 * PGGraphicsDrawCompObj - draw the given composition object on screen, cropped images also
 *
 * @param COMPOSITION_OBJECT *CompObj - The Composition object to draw
 * @param PALETTE *Pal - The palette used to convert RLE to ARGB
 *
 * @return PG_STATUS
 */
PG_STATUS PGGraphicsDrawCompObj(COMPOSITION_OBJECT *CompObj)
{
    OBJECT_DEFINITION_SEGMENT *Img=NULL;
    USHORT DrawX, DrawY, DrawW, DrawH;
    USHORT ScreenMaxX, ScreenMaxY;
    DFBResult Result;
    int imgsize;

#ifdef ALLOW_PG_PROFILING
    ULONG TickStart = 0;
#endif

    DBGPRINT(DBG_ON(DBG_TRACE), ("PGGraphicsDrawCompObj: Draw Object %d\n", CompObj->ObjectIDRef));

    /* grab the object from the list */
    Img = &PGObjList[CompObj->ObjectIDRef];
    if (0 == Img->InUse)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsDrawCompObj(): Could not render object it is not available in PGRender, id %d\n", CompObj->ObjectIDRef));
        return PG_STATUS_ERROR;
    }

    /* we need to create a new surface */
    imgsize = Img->ObjData.Width * Img->ObjData.Height;
    if ((0 == imgsize) || (imgsize > 1920 * 1080))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsDrawCompObj(): ERROR imgsize is zero or too large\n"));
        return PG_STATUS_ERROR;
    }

    /* make sure the image is at least 8 pixels wide (spec) */
    if ((Img->ObjData.Width < 8) || (Img->ObjData.Height < 8))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsDrawCompObj(): Do not draw image, too small w=%d h=%d\n", Img->ObjData.Width, Img->ObjData.Height));
        goto errout;
    }

    /* load drawing params, if we are drawing half width cut all x coords in half */
    if (PGInfo.CoordsHalfWidth == 0)
    {
        DrawX = CompObj->XPosition;
        DrawY = CompObj->YPosition;
        DrawW = Img->ObjData.Width;
        DrawH = Img->ObjData.Height;
        ScreenMaxX = MAX_GRFX_WIDTH;
        ScreenMaxY = MAX_GRFX_HEIGHT;
    }
    else
    {
        DrawX = CompObj->XPosition/2;
        DrawY = CompObj->YPosition;
        DrawW = (Img->ObjData.Width+1)/2;
        DrawH = Img->ObjData.Height;
        ScreenMaxX = MAX_GRFX_WIDTH/2;
        ScreenMaxY = MAX_GRFX_HEIGHT;
    }

    /* see if the image is cropped */
    if (!CompObj->CroppedFlag)
    {
        /* check that we do not go outside screen space */
        if ((DrawX <= ScreenMaxX) && (DrawY <= ScreenMaxY) &&
           ((DrawX + DrawW) <= ScreenMaxX) && ((DrawY + DrawH) <= ScreenMaxY))
        {
            /* image is not cropped */
#ifdef ALLOW_PG_PROFILING
            if (1 == PGStats.Profiling)
            {
                TickStart = OS_GetTicks();
            }
#endif

            Result = PGInfo.DFBInfo.PrimarySurface->Blit(PGInfo.DFBInfo.PrimarySurface, Img->SurfaceLUT8, NULL, DrawX, DrawY);

#ifdef ALLOW_PG_PROFILING
            if (1 == PGStats.Profiling)
            {
                PGStats.PGTotalBlitTicks += OS_GetTicks() - TickStart;
            }
#endif

            if (Result == DFB_OK)
            {
                PGAddToCleanupList(DrawX, DrawY, DrawW, DrawH);
            }
            else
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PG Blit Failed object %d\n", CompObj->ObjectIDRef));
            }
        }
    }
    else
    {
        /* img is cropped */
        DFBRectangle Rect;

        if (PGInfo.CoordsHalfWidth == 0)
        {
            Rect.x = CompObj->Rect.X;
            Rect.y = CompObj->Rect.Y;
            Rect.w = CompObj->Rect.Width;
            Rect.h = CompObj->Rect.Height;
        }
        else
        {
            Rect.x = CompObj->Rect.X/2;
            Rect.y = CompObj->Rect.Y;
            Rect.w = (CompObj->Rect.Width+1)/2;
            Rect.h = CompObj->Rect.Height;
        }

        if ((DrawX <= ScreenMaxX) && (DrawY <= ScreenMaxY) &&
           ((DrawX + Rect.w) <= ScreenMaxX) && ((DrawY + Rect.h) <= ScreenMaxY))
        {
            /* draw the image */
#ifdef ALLOW_PG_PROFILING
            if (1 == PGStats.Profiling)
            {
                TickStart = OS_GetTicks();
            }
#endif

            Result = PGInfo.DFBInfo.PrimarySurface->Blit(PGInfo.DFBInfo.PrimarySurface, Img->SurfaceLUT8, &Rect, DrawX, DrawY);

#ifdef ALLOW_PG_PROFILING
            if (1 == PGStats.Profiling)
            {
                PGStats.PGTotalBlitTicks += OS_GetTicks() - TickStart;
            }
#endif

            if (Result == DFB_OK)
            {
                PGAddToCleanupList(DrawX, DrawY, DrawW, DrawH);
            }
            else
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PG Blit Failed object %d\n", CompObj->ObjectIDRef));
            }
        }
        else
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsDrawCompObj(): image tried to draw out of bounds %d %d %d %d\n",
                DrawX, DrawY, DrawX + Rect.w, DrawY + Rect.h));
        }
    }

    return PG_STATUS_SUCCESS;

errout:

    return PG_STATUS_ERROR;
}

/**
 * PGAddToCleanupList - add an image to the cleanup list, this list will be cleared using the
 *                      clear color when it is time for a display blank
 *
 * @param int Height - height of the image
 * @param int Width - width of the image
 * @param int X - starting x coord
 * @param int Y - starting y coord
 *
 * @return PG_STATUS
 */
void PGAddToCleanupList(int X, int Y, int Width, int Height)
{
    /* loop looking for a match */
    for (ULONG i=0; i<gPGImageIndex; i++)
    {
        /* see if we match inputs */
        if ((PGCleanupList[i].h == Height) &&
            (PGCleanupList[i].w == Width)  &&
            (PGCleanupList[i].x == X)      &&
            (PGCleanupList[i].y == Y))
        {
            /* input matches one in the list, don't add */
            return;
        }
    }

    /* if we didn't find a match in the list, we got here, so add it */
    PGCleanupList[gPGImageIndex].h = Height;
    PGCleanupList[gPGImageIndex].w = Width;
    PGCleanupList[gPGImageIndex].x = X;
    PGCleanupList[gPGImageIndex].y = Y;

    /* stretch the flipping region to fit the new coords */
    if (X < gPGFlipRegion.x1)
    {
        gPGFlipRegion.x1 = X;
    }

    if (Y < gPGFlipRegion.y1)
    {
        gPGFlipRegion.y1 = Y;
    }

    if (X+Width > gPGFlipRegion.x2)
    {
        gPGFlipRegion.x2 = X+Width;
    }

    if (Y+Height > gPGFlipRegion.y2)
    {
        gPGFlipRegion.y2 = Y+Height;
    }

    gPGImageIndex++;
}

/**
 * PGGraphicsSetPaletteColors - update the palette for the currently displayed surface
 *
 * @param DFBPaletteDescription PalDesc - the description of the palette
 * @param PALETTE *Pal - The palette to set on DirectFB
 *
 * @return PG_STATUS
 */
PG_STATUS PGGraphicsSetPaletteColors(int PaletteNumber, BYTE *DataPtr, int NumEntries, BYTE fClearPalette, PG_COLOR_SPACE ColorSpace)
{
    BYTE PaletteEntryID;
    int i;
    PALETTE *CurPal = &PGPalettes[PaletteNumber];

    /* if we are not in EPOCH_NORMAL, fclearpalette will be 1, if normal we are just doing an update
       don't clear the palette */
    if (fClearPalette)
    {
        memset(CurPal->Colors, 0, sizeof(DFBColor) * PG_MAX_PALETTE_COLORS);
    }

    /* pal_ptr here points to the first byte which is palette_entry_id (we use it as the palette_color) */
    ULONG Color;
    BYTE *ClrBytes = (BYTE *)&Color;

    /* fill in the palette colors in the correct PaletteEntryID positions in the palette */
    for (i=0; i<NumEntries; i++)
    {
        PaletteEntryID = *DataPtr; /* this is the palette_entry_id */
        DataPtr++;

        if (ColorSpace == REC_709)
        {
            /* convert all colors to ARGB */
            Color = MakeARGBfromYCrCb709(*DataPtr++,  // y
                                         *DataPtr++,  //cr
                                         *DataPtr++,  //cb
                                         *DataPtr++); //t
        }
        else
        {
            /* convert all colors to ARGB */
            Color = MakeARGBfromYCrCb601(*DataPtr++,  // y
                                         *DataPtr++,  //cr
                                         *DataPtr++,  //cb
                                         *DataPtr++); //t
        }

        /* Pal*/
        CurPal->Colors[PaletteEntryID].a = ClrBytes[0];
        CurPal->Colors[PaletteEntryID].r = ClrBytes[1];
        CurPal->Colors[PaletteEntryID].g = ClrBytes[2];
        CurPal->Colors[PaletteEntryID].b = ClrBytes[3];
    }
    return PG_STATUS_SUCCESS;
}

/**
 * PGGraphicsCreateAllPalettes - create all the pg palettes
 *
 * @return PG_STATUS
 */
PG_STATUS PGGraphicsCreateAllPalettes()
{
    DFBPaletteDescription PalDesc;
    PALETTE *CurPal;

    /* loop and create all the dfb palettes but with clear as their colors */
    for (int i=0; i<PG_MAX_PALETTES; i++)
    {
        CurPal = &PGPalettes[i];
        for (int j=0; j<PG_MAX_PALETTE_COLORS; j++)
        {
            CurPal->Colors[j].a = 0;
            CurPal->Colors[j].r = 0;
            CurPal->Colors[j].g = 0;
            CurPal->Colors[j].b = 0;
        }

        /* setup the description */
        PalDesc.flags = (DFBPaletteDescriptionFlags) (DPDESC_SIZE | DPDESC_ENTRIES);
        PalDesc.size = PG_MAX_PALETTE_COLORS;
        PalDesc.entries = CurPal->Colors;

        /* call create palette with the entries we give here */
        if (PGInfo.DFBInfo.pDFBHandle->CreatePalette(PGInfo.DFBInfo.pDFBHandle, &PalDesc, &CurPal->DFBPal) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsCreateAllPalettes(): Failed to create DFB Palette\n"));

⌨️ 快捷键说明

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