mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2025-03-13 22:23:04 +00:00
minimizing disables the rendering back-end except for videos/screenshots
when minimized, we call the rest of the logic all the same (including the VM calls) only 1 screenshot command can be issued per frame (i.e. only first one is kept)
This commit is contained in:
parent
95e7407688
commit
515ca0883e
6 changed files with 107 additions and 17 deletions
|
@ -394,16 +394,10 @@ static void SCR_PerformanceCounters()
|
|||
void SCR_UpdateScreen()
|
||||
{
|
||||
static int recursive = 0;
|
||||
static int lastRenderTime = 0;
|
||||
|
||||
if ( !scr_initialized )
|
||||
return;
|
||||
|
||||
#ifndef DEDICATED
|
||||
if ( !CL_VideoRecording() && Sys_IsMinimized() && Sys_Milliseconds() - lastRenderTime < 1000 )
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
||||
// there are several cases where this IS called twice in one frame
|
||||
// easiest example is: conn to a server, kill the server
|
||||
if ( ++recursive > 2 ) {
|
||||
|
@ -417,22 +411,22 @@ void SCR_UpdateScreen()
|
|||
// function (or any function for that matter) is not always reached.
|
||||
recursive = 1;
|
||||
|
||||
const qbool drawFrame = CL_VideoRecording() || !Sys_IsMinimized();
|
||||
SCR_DrawScreenField( STEREO_CENTER );
|
||||
|
||||
if ( com_speeds->integer ) {
|
||||
re.EndFrame( pcFE, pc2D, pc3D );
|
||||
re.EndFrame( pcFE, pc2D, pc3D, drawFrame );
|
||||
time_frontend = pcFE[RF_MSEC];
|
||||
time_backend = pc3D[RB_MSEC];
|
||||
} else if ( Cvar_VariableIntegerValue("r_speeds") ) {
|
||||
// counters are actually the previous frame's, because EndFrame will clear them
|
||||
// and we need to submit the calls to show them before that
|
||||
SCR_PerformanceCounters();
|
||||
re.EndFrame( pcFE, pc2D, pc3D );
|
||||
re.EndFrame( pcFE, pc2D, pc3D, drawFrame );
|
||||
} else {
|
||||
re.EndFrame( NULL, NULL, NULL );
|
||||
re.EndFrame( NULL, NULL, NULL, drawFrame );
|
||||
}
|
||||
|
||||
recursive = 0;
|
||||
lastRenderTime = Sys_Milliseconds();
|
||||
}
|
||||
|
||||
|
|
|
@ -1147,3 +1147,64 @@ void RB_ExecuteRenderCommands( const void *data )
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void* RB_FindRenderCommand( renderCommand_t type )
|
||||
{
|
||||
renderCommandList_t* cmdList = &backEndData->commands;
|
||||
void* data = cmdList->cmds;
|
||||
void* end = cmdList->cmds + cmdList->used;
|
||||
|
||||
while ( 1 ) {
|
||||
data = PADP(data, sizeof(void *));
|
||||
|
||||
if( *(int *)data == type )
|
||||
return data;
|
||||
|
||||
if ( data >= end )
|
||||
return NULL;
|
||||
|
||||
switch ( *(const int *)data ) {
|
||||
case RC_SET_COLOR:
|
||||
data = (char*)data + sizeof(setColorCommand_t);
|
||||
break;
|
||||
case RC_STRETCH_PIC:
|
||||
data = (char*)data + sizeof(stretchPicCommand_t);
|
||||
break;
|
||||
case RC_TRIANGLE:
|
||||
data = (char*)data + sizeof(triangleCommand_t);
|
||||
break;
|
||||
case RC_DRAW_SURFS:
|
||||
data = (char*)data + sizeof(drawSurfsCommand_t);
|
||||
break;
|
||||
case RC_BEGIN_FRAME:
|
||||
data = (char*)data + sizeof(beginFrameCommand_t);
|
||||
break;
|
||||
case RC_SWAP_BUFFERS:
|
||||
data = (char*)data + sizeof(swapBuffersCommand_t);
|
||||
break;
|
||||
case RC_SCREENSHOT:
|
||||
data = (char*)data + sizeof(screenshotCommand_t);
|
||||
break;
|
||||
case RC_VIDEOFRAME:
|
||||
data = (char*)data + sizeof(videoFrameCommand_t);
|
||||
break;
|
||||
|
||||
case RC_END_OF_LIST:
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RB_RemoveRenderCommand( void* cmd, int cmdSize )
|
||||
{
|
||||
renderCommandList_t* cmdList = &backEndData->commands;
|
||||
const int endOffset = ((char*)cmd + cmdSize) - (char*)cmdList->cmds;
|
||||
const int endBytes = cmdList->used - endOffset;
|
||||
assert( cmd >= cmdList->cmds && ((char*)cmd + cmdSize) <= ((char*)cmdList->cmds + cmdList->used) );
|
||||
|
||||
memmove( cmd, (char*)cmd + cmdSize, endBytes );
|
||||
cmdList->used -= cmdSize;
|
||||
}
|
||||
|
|
|
@ -242,12 +242,39 @@ void RE_BeginFrame( stereoFrame_t stereoFrame )
|
|||
}
|
||||
|
||||
|
||||
void RE_EndFrame( int* pcFE, int* pc2D, int* pc3D )
|
||||
void RE_EndFrame( int* pcFE, int* pc2D, int* pc3D, qbool render )
|
||||
{
|
||||
if (!tr.registered)
|
||||
return;
|
||||
|
||||
R_CMD( swapBuffersCommand_t, RC_SWAP_BUFFERS );
|
||||
qbool delayScreenshot = qfalse;
|
||||
if ( !render && r_delayedScreenshotPending )
|
||||
render = qtrue;
|
||||
|
||||
if ( !render ) {
|
||||
screenshotCommand_t* ssCmd = (screenshotCommand_t*)RB_FindRenderCommand( RC_SCREENSHOT );
|
||||
|
||||
if ( ssCmd )
|
||||
render = qtrue;
|
||||
|
||||
if ( ssCmd && !ssCmd->delayed ) {
|
||||
// save and remove the command so we can push it back after the frame's done
|
||||
r_delayedScreenshot = *ssCmd;
|
||||
r_delayedScreenshot.delayed = qtrue;
|
||||
RB_RemoveRenderCommand( ssCmd, sizeof(screenshotCommand_t) );
|
||||
delayScreenshot = qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( render ) {
|
||||
R_CMD( swapBuffersCommand_t, RC_SWAP_BUFFERS );
|
||||
if ( delayScreenshot ) {
|
||||
R_CMD( screenshotCommand_t, RC_SCREENSHOT );
|
||||
*cmd = r_delayedScreenshot;
|
||||
}
|
||||
} else {
|
||||
R_ClearFrame();
|
||||
}
|
||||
|
||||
R_IssueRenderCommands();
|
||||
|
||||
|
|
|
@ -366,9 +366,11 @@ const void* RB_TakeScreenshotCmd( const screenshotCommand_t* cmd )
|
|||
switch (cmd->type) {
|
||||
case screenshotCommand_t::SS_JPG:
|
||||
RB_TakeScreenshotJPG( cmd->x, cmd->y, cmd->width, cmd->height, cmd->fileName );
|
||||
ri.Printf( PRINT_ALL, "Wrote %s\n", cmd->fileName );
|
||||
break;
|
||||
case screenshotCommand_t::SS_TGA:
|
||||
RB_TakeScreenshotTGA( cmd->x, cmd->y, cmd->width, cmd->height, cmd->fileName );
|
||||
ri.Printf( PRINT_ALL, "Wrote %s\n", cmd->fileName );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -387,7 +389,7 @@ const void* RB_TakeScreenshotCmd( const screenshotCommand_t* cmd )
|
|||
|
||||
static void R_TakeScreenshot( const char* ext, screenshotCommand_t::ss_type type, qbool hideConsole )
|
||||
{
|
||||
static char s[MAX_OSPATH]; // bad things may happen if we somehow manage to take 2 ss in 1 frame
|
||||
static char s[MAX_OSPATH];
|
||||
|
||||
const float conVis = hideConsole ? ri.SetConsoleVisibility( 0.0f ) : 0.0f;
|
||||
screenshotCommand_t* cmd;
|
||||
|
@ -395,10 +397,14 @@ static void R_TakeScreenshot( const char* ext, screenshotCommand_t::ss_type type
|
|||
cmd = &r_delayedScreenshot;
|
||||
r_delayedScreenshotPending = qtrue;
|
||||
r_delayedScreenshotFrame = 0;
|
||||
cmd->delayed = qtrue;
|
||||
} else {
|
||||
if ( RB_FindRenderCommand( RC_SCREENSHOT ) )
|
||||
return;
|
||||
cmd = (screenshotCommand_t*)R_GetCommandBuffer( sizeof(screenshotCommand_t) );
|
||||
if ( !cmd )
|
||||
return;
|
||||
cmd->delayed = qfalse;
|
||||
}
|
||||
|
||||
if (ri.Cmd_Argc() == 2) {
|
||||
|
@ -410,7 +416,6 @@ static void R_TakeScreenshot( const char* ext, screenshotCommand_t::ss_type type
|
|||
Com_sprintf( s, sizeof(s), "screenshots/%d_%02d_%02d-%02d_%02d_%02d-%03d.%s",
|
||||
1900+t.tm_year, 1+t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, ms, ext );
|
||||
}
|
||||
ri.Printf( PRINT_ALL, "Wrote %s\n", s );
|
||||
|
||||
cmd->commandId = RC_SCREENSHOT;
|
||||
cmd->x = 0;
|
||||
|
|
|
@ -1438,6 +1438,7 @@ typedef struct {
|
|||
enum ss_type { SS_TGA, SS_JPG } type;
|
||||
float conVis; // if > 0, this is a delayed screenshot and we need to
|
||||
// restore the console visibility to that value
|
||||
qbool delayed;
|
||||
} screenshotCommand_t;
|
||||
|
||||
const void* RB_TakeScreenshotCmd( const screenshotCommand_t* cmd );
|
||||
|
@ -1487,13 +1488,15 @@ extern backEndData_t *backEndData;
|
|||
|
||||
void *R_GetCommandBuffer( int bytes );
|
||||
void RB_ExecuteRenderCommands( const void *data );
|
||||
void* RB_FindRenderCommand( renderCommand_t type );
|
||||
void RB_RemoveRenderCommand( void* cmd, int cmdSize );
|
||||
|
||||
void R_SyncRenderThread( void );
|
||||
|
||||
void R_AddDrawSurfCmd( drawSurf_t* drawSurfs, int numDrawSurfs );
|
||||
|
||||
void RE_BeginFrame( stereoFrame_t stereoFrame );
|
||||
void RE_EndFrame( int* pcFE, int* pc2D, int* pc3D );
|
||||
void RE_EndFrame( int* pcFE, int* pc2D, int* pc3D, qbool render );
|
||||
void RE_SetColor( const float* rgba );
|
||||
void RE_StretchPic( float x, float y, float w, float h,
|
||||
float s1, float t1, float s2, float t2, qhandle_t hShader );
|
||||
|
|
|
@ -146,7 +146,7 @@ typedef struct {
|
|||
void (*BeginFrame)( stereoFrame_t stereoFrame );
|
||||
|
||||
// if the pointers are not NULL, they will be filled with stats tables
|
||||
void (*EndFrame)( int* pcFE, int* pc2D, int* pc3D );
|
||||
void (*EndFrame)( int* pcFE, int* pc2D, int* pc3D, qbool render );
|
||||
|
||||
int (*MarkFragments)( int numPoints, const vec3_t *points, const vec3_t projection,
|
||||
int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t *fragmentBuffer );
|
||||
|
|
Loading…
Reference in a new issue