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:
myT 2018-01-07 00:03:42 +01:00
parent 95e7407688
commit 515ca0883e
6 changed files with 107 additions and 17 deletions

View file

@ -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();
}

View file

@ -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;
}

View file

@ -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();

View file

@ -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;

View file

@ -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 );

View file

@ -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 );