I have this code segment in a separate thread than the main:
if( DEBUG )
{
/* Grab system time */
clock_gettime(CLOCK_REALTIME, &hack_time);
fprintf( stderr, "poll returned %f
", Total_Inputs, ((float)hack_time.tv_nsec/1000000000.0) );
}
/* Check all requested fds for returned data */
for( request = 0; request < Inputs; request++ )
{
/* Check this requested fds for data */
if( fds[request].revents & (POLLIN | POLLPRI ) )
{
/* Default to not found */
Found = 0;
/* Determine which device gave us data */
for( idx = 0; idx < Total_Inputs; idx++ )
{
if( fds[request].fd == Capture_State.Inputs[Vid_Used_Index[idx]].fd )
{
Found = 1;
break;
}
}
if( !Found )
{
fprintf( stderr, "Could not determine which input yielded data. Request index = %d
", request );
continue;
}
/* de-queue the buffer */
if((ret_val = ioctl( fds[request].fd, VIDIOC_DQBUF, &buf[Vid_Used_Index[idx]] )) < 0 )
{
switch( errno )
{
case EAGAIN:
{
continue;
break;
}
case EIO:
default:
{
fprintf( stderr, "Failed to de-queue buffer[%d]: %d
", buf[Vid_Used_Index[idx]].index, ret_val);
Return_Value = EXIT_FAILURE;
goto realtime_failure;
}
}
}
/* Use buffer to update texture on all outputs that use it */
for( Output = Tracker; Output < Output_Count; Output = (Outputs)((int)Output + 1) )
{
/* Check if this output used this input */
if( Input_State[Vid_Used_Index[idx]].Used & (1 << Output) )
{
/* Make output context current */
glXMakeCurrent( X.display, X.window[Output], X.context[Output][CAPTURE_CONTEXT] );
/* Update the texture with new image */
glBindTexture( GL_TEXTURE_2D, Capture_Texture[Output][Vid_Used_Index[idx]] );
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, SOURCE_WIDTH, SOURCE_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE,
Capture_State.Frame_Buffers[Vid_Used_Index[idx]][buf[Vid_Used_Index[idx]].index].pData );
/* Insert fence into stream */
Texture_Sync[Output][Vid_Used_Index[idx]] = glFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 );
if( DEBUG )
{
/* Grab system time */
clock_gettime(CLOCK_REALTIME, &hack_time);
fprintf( stderr, "Fence[%s][%s] Created %f
", Output_Strings[Output], VID_Strings[Vid_Used_Index[idx]], ((float)hack_time.tv_nsec/1000000000.0) );
}
/* clear the input request bit for this output */
Input_State[Vid_Used_Index[idx]].Used &= ~(1 << Output);
}
}
Here is the output log:
poll returned 0.003716
Fence[Tracker][EOW] Created 0.006632
Fence[Operator][EOW] Created 0.009841
Frame Top Draw 0.010289
Fence[DGU][EOW] Created 0.013028
Why are the four gl calls taking 3+ milliseconds each? Each of the texture buffers is 6220800 bytes long. I’m creating the fence objects so I know when the data is done moving, but the other end always gets GL_ALREADY_SIGNALED.
I thought the glTexSubImage would return before the data was copied.