📄 pg_graphics.cpp
字号:
return PG_STATUS_ERROR;
}
}
return PG_STATUS_SUCCESS;
}
/**
* PGGraphicsDeleteAllPalettes - release the surface memory
*
* @return PG_STATUS
*/
PG_STATUS PGGraphicsDeleteAllPalettes()
{
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];
/* call create palette with the entries we give here */
if (CurPal->DFBPal->Release(CurPal->DFBPal) != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsDeleteAllPalettes(): Failed to release DFB Palette\n"));
return PG_STATUS_ERROR;
}
CurPal->DFBPal = NULL;
}
return (PG_STATUS_SUCCESS);
}
/**
* PGGraphicsFreeSurface - release the surface memory
*
* @param IDirectFBSurface *Surface - The DFB Surface to release
*
* @return PG_STATUS
*/
PG_STATUS PGGraphicsFreeSurface(IDirectFBSurface *Surface)
{
if (Surface != NULL)
{
Surface->Release(Surface);
}
return (PG_STATUS_SUCCESS);
}
/**
* PGGraphicsCreateLUT8Surface - create a directfb surface for the LUT8 member of an ODS
*
* @param DFBSurfaceDescription *desc = Description pointer describing the new surface
* @param OBJECT_DEFINITION_SEGMENT *Obj = The object that contains the LUT8 DFB Surface to create
*
* @return PG_STATUS
*/
PG_STATUS PGGraphicsCreateLUT8Surface(DFBSurfaceDescription *desc, OBJECT_DEFINITION_SEGMENT *Obj)
{
#ifdef ALLOW_PG_PROFILING
ULONG TickStart = 0;
#endif
/* create the palettized surface of the object passed in */
#ifdef ALLOW_PG_PROFILING
if (1 == PGStats.Profiling)
{
TickStart = OS_GetTicks();
}
#endif
if (DFB_OK != PGInfo.DFBInfo.SurfaceManager->CreateSurface(PGInfo.DFBInfo.SurfaceManager, desc, &Obj->SurfaceLUT8))
{
return PG_STATUS_ERROR;
}
#ifdef ALLOW_PG_PROFILING
if (1 == PGStats.Profiling)
{
PGStats.PGTotalCreateSurfaceTicks += OS_GetTicks() - TickStart;
}
#endif
return PG_STATUS_SUCCESS;
}
/**
* PGGraphicsFlip - present the backbuffer on screen
*
* @param void
*
* @return PG_STATUS
*/
PG_STATUS PGGraphicsFlip()
{
OS_SemTake(PGInfo.BlitLock, OS_WAIT_FOREVER);
#ifdef ALLOW_PG_PROFILING
ULONG TickStart = 0;
#endif
if ((gPGFlipRegion.x2 > gPGFlipRegion.x1) && (gPGFlipRegion.y2 > gPGFlipRegion.y1))
{
#ifdef ALLOW_PG_PROFILING
if (1 == PGStats.Profiling)
{
TickStart = OS_GetTicks();
}
#endif
/* adjust flipping region to account for rectangle vs region size, one pixel in all directions */
gPGFlipRegion.x1 = ((gPGFlipRegion.x1-1) < 0) ? 0 : gPGFlipRegion.x1-1;
gPGFlipRegion.y1 = ((gPGFlipRegion.y1-1) < 0) ? 0 : gPGFlipRegion.y1-1;
if (PGInfo.CoordsHalfWidth == 1)
{
gPGFlipRegion.x2 = ((gPGFlipRegion.x2+1) > (PGInfo.DFBInfo.ScreenWidth/2)) ? gPGFlipRegion.x2+1 : (PGInfo.DFBInfo.ScreenWidth/2);
gPGFlipRegion.y2 = ((gPGFlipRegion.y2+1) > PGInfo.DFBInfo.ScreenHeight) ? gPGFlipRegion.y2+1 : PGInfo.DFBInfo.ScreenHeight;
}
else
{
gPGFlipRegion.x2 = ((gPGFlipRegion.x2+1) > PGInfo.DFBInfo.ScreenWidth) ? gPGFlipRegion.x2+1 : PGInfo.DFBInfo.ScreenWidth;
gPGFlipRegion.y2 = ((gPGFlipRegion.y2+1) > PGInfo.DFBInfo.ScreenHeight) ? gPGFlipRegion.y2+1 : PGInfo.DFBInfo.ScreenHeight;
}
if (PGInfo.DFBInfo.PrimarySurface->Flip(PGInfo.DFBInfo.PrimarySurface, &gPGFlipRegion, DSFLIP_NONE) != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("Failed to flip surface\n"));
}
#ifdef ALLOW_PG_PROFILING
if (1 == PGStats.Profiling)
{
PGStats.PGTotalFlipTicks += OS_GetTicks() - TickStart;
}
#endif
}
else
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PG Not Flipping (%d %d) w=%d h=%d\n", gPGFlipRegion.x1, gPGFlipRegion.y1,
gPGFlipRegion.x2-gPGFlipRegion.x1, gPGFlipRegion.y2-gPGFlipRegion.y1));
}
/* after a flip clear the region */
if (PGInfo.CoordsHalfWidth == 0)
{
gPGFlipRegion.x1 = PGInfo.DFBInfo.ScreenWidth;
gPGFlipRegion.x2 = 0;
gPGFlipRegion.y1 = PGInfo.DFBInfo.ScreenHeight;
gPGFlipRegion.y2 = 0;
}
else
{
gPGFlipRegion.x1 = PGInfo.DFBInfo.ScreenWidth/2;
gPGFlipRegion.x2 = 0;
gPGFlipRegion.y1 = PGInfo.DFBInfo.ScreenHeight;
gPGFlipRegion.y2 = 0;
}
OS_SemGive(PGInfo.BlitLock);
return PG_STATUS_SUCCESS;
}
/**
* PGGraphicsClearBuffer - present the backbuffer on screen
*
* @param void
*
* @return PG_STATUS
*/
PG_STATUS PGGraphicsClearBuffer(BYTE *fUpdateScreen, OS_SEM_ID Sem)
{
if (Sem == 0)
{
OS_SemTake(PGInfo.BlitLock, OS_WAIT_FOREVER);
}
if (0 == gPGImageIndex)
{
if (fUpdateScreen)
{
*fUpdateScreen = 0;
}
if (Sem == 0)
{
OS_SemGive(PGInfo.BlitLock);
}
return PG_STATUS_SUCCESS;
}
/* use color 255 to clear the screen, this is the clear color */
PGInfo.DFBInfo.PrimarySurface->SetColorIndex(PGInfo.DFBInfo.PrimarySurface, 0xFF);
/* clean up all rectangles in the list with one call */
PGInfo.DFBInfo.PrimarySurface->FillRectangles(PGInfo.DFBInfo.PrimarySurface, PGCleanupList, gPGImageIndex);
if (PGInfo.CoordsHalfWidth == 0)
{
gPGFlipRegion.x1 = PGInfo.DFBInfo.ScreenWidth;
gPGFlipRegion.x2 = 0;
gPGFlipRegion.y1 = PGInfo.DFBInfo.ScreenHeight;
gPGFlipRegion.y2 = 0;
}
else
{
gPGFlipRegion.x1 = PGInfo.DFBInfo.ScreenWidth/2;
gPGFlipRegion.x2 = 0;
gPGFlipRegion.y1 = PGInfo.DFBInfo.ScreenHeight;
gPGFlipRegion.y2 = 0;
}
for (ULONG i=0; i<gPGImageIndex; i++)
{
if (PGCleanupList[i].x < gPGFlipRegion.x1)
{
gPGFlipRegion.x1 = PGCleanupList[i].x;
}
if (PGCleanupList[i].x + PGCleanupList[i].w > gPGFlipRegion.x2)
{
gPGFlipRegion.x2 = PGCleanupList[i].x + PGCleanupList[i].w;
}
if (PGCleanupList[i].y < gPGFlipRegion.y1)
{
gPGFlipRegion.y1 = PGCleanupList[i].y;
}
if (PGCleanupList[i].y + PGCleanupList[i].h > gPGFlipRegion.y2)
{
gPGFlipRegion.y2 = PGCleanupList[i].y + PGCleanupList[i].h;
}
memset(&PGCleanupList[i], 0, sizeof(DFBRectangle));
}
gPGImageIndex = 0;
if (fUpdateScreen)
{
*fUpdateScreen = 1;
}
if (Sem == 0)
{
OS_SemGive(PGInfo.BlitLock);
}
return PG_STATUS_SUCCESS;
}
/**
* PGGraphicsClearScreen - clear the buffer offscreen
*
* @param void
*
* @return PG_STATUS
*/
PG_STATUS PGGraphicsClearScreen()
{
IDirectFBSurface *ClearSurf = NULL;
IDirectFBPalette *ClearPal = NULL;
DFBColor ClearColor = {0,0,0,0};
OS_SemTake(PGInfo.BlitLock, OS_WAIT_FOREVER);
/* get the primary surface for this diplay layer */
if (PGInfo.DFBInfo.DispLayer->GetSurface(PGInfo.DFBInfo.DispLayer, &ClearSurf) != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to get surface\n"));
goto errout;
}
/* get the surfaces palette */
if (ClearSurf->GetPalette(ClearSurf, &ClearPal) != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to get palette!\n"));
goto errout;
}
/* set default transparent palette entry */
if (ClearPal->SetEntries(ClearPal, &ClearColor, 1, 0xff) != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to set transparent palette entry!\n"));
goto errout;
}
/* set surface color index to transparent */
if (ClearSurf->SetColorIndex(ClearSurf, 0xff) != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to set color index!\n"));
goto errout;
}
/* clear the surface */
if (PGInfo.CoordsHalfWidth == 1)
{
if (ClearSurf->FillRectangle(ClearSurf, 0, 0, PGInfo.DFBInfo.ScreenWidth/2, PGInfo.DFBInfo.ScreenHeight) != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to clear surface!\n"));
goto errout;
}
/* set to invalid region */
gPGFlipRegion.x1 = 0;
gPGFlipRegion.x2 = PGInfo.DFBInfo.ScreenWidth/2;
gPGFlipRegion.y1 = 0;
gPGFlipRegion.y2 = PGInfo.DFBInfo.ScreenHeight;
}
else
{
if (ClearSurf->FillRectangle(ClearSurf, 0, 0, PGInfo.DFBInfo.ScreenWidth, PGInfo.DFBInfo.ScreenHeight) != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to clear surface!\n"));
goto errout;
}
/* set to invalid region */
gPGFlipRegion.x1 = 0;
gPGFlipRegion.x2 = PGInfo.DFBInfo.ScreenWidth;
gPGFlipRegion.y1 = 0;
gPGFlipRegion.y2 = PGInfo.DFBInfo.ScreenHeight;
}
if (ClearPal)
{
ClearPal->Release(ClearPal);
}
if (ClearSurf)
{
ClearSurf->Release(ClearSurf);
}
OS_SemGive(PGInfo.BlitLock);
return PG_STATUS_SUCCESS;
errout:
if (ClearPal)
{
ClearPal->Release(ClearPal);
}
if (ClearSurf)
{
ClearSurf->Release(ClearSurf);
}
OS_SemGive(PGInfo.BlitLock);
return PG_STATUS_ERROR;
}
/**
* PGGraphicsBuildFlipRegion - build a flip region based on what images we have drawn
*
* @param void
*
* @return PG_STATUS
*/
void PGGraphicsBuildFlipRegion()
{
for (ULONG i=0; i<gPGImageIndex; i++)
{
if (PGCleanupList[i].x < gPGFlipRegion.x1)
{
gPGFlipRegion.x1 = PGCleanupList[i].x;
}
if (PGCleanupList[i].x + PGCleanupList[i].w > gPGFlipRegion.x2)
{
gPGFlipRegion.x2 = PGCleanupList[i].x + PGCleanupList[i].w;
}
if (PGCleanupList[i].y < gPGFlipRegion.y1)
{
gPGFlipRegion.y1 = PGCleanupList[i].y;
}
if (PGCleanupList[i].y + PGCleanupList[i].h > gPGFlipRegion.y2)
{
gPGFlipRegion.y2 = PGCleanupList[i].y + PGCleanupList[i].h;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -