Ejemplo n.º 1
0
void FOpenGLDynamicRHI::RHIResizeViewport(FViewportRHIParamRef ViewportRHI,uint32 SizeX,uint32 SizeY,bool bIsFullscreen)
{
	FOpenGLViewport* Viewport = ResourceCast(ViewportRHI);
	check( IsInGameThread() );

//#if !PLATFORM_MAC
//	SCOPED_SUSPEND_RENDERING_THREAD(true);
//#endif

	Viewport->Resize(SizeX,SizeY,bIsFullscreen);
}
Ejemplo n.º 2
0
bool PlatformBlitToViewport( FPlatformOpenGLDevice* Device, const FOpenGLViewport& Viewport, uint32 BackbufferSizeX, uint32 BackbufferSizeY, bool bPresent,bool bLockToVsync, int32 SyncInterval )
{
	if (Viewport.GetCustomPresent())
	{
		Viewport.GetCustomPresent()->Present(SyncInterval);
	}
	else
	{
		AndroidEGL::GetInstance()->SwapBuffers();
	}
	return true;
}
Ejemplo n.º 3
0
bool PlatformBlitToViewport( FPlatformOpenGLDevice* Device, const FOpenGLViewport& Viewport, uint32 BackbufferSizeX, uint32 BackbufferSizeY, bool bPresent,bool bLockToVsync, int32 SyncInterval )
{
	if (FOpenGL::IsES2())
	{
		AndroidEGL::GetInstance()->SwapBuffers();
	}
	else
	{
		FPlatformOpenGLContext* const Context = Viewport.GetGLContext();

		check(Context && Context->eglContext );

		FScopeContext ScopeContext(Context);

		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
		//Disabling for now to work around a GL_INVALID_OPERATION which might or might not be legit in the context of EGL.
		//Note that the drawbuffer state is part of the FBO state, so we don't need to touch it per frame.
		//glDrawBuffer(GL_BACK);
		glBindFramebuffer(GL_READ_FRAMEBUFFER, Context->ViewportFramebuffer);
		glReadBuffer(GL_COLOR_ATTACHMENT0);
		
		//LOGD("PlatformBlitToViewport: backbuffer (%d, %d) to screen (%d, %d)", BackbufferSizeX, BackbufferSizeY, GRealScreenWidth, GRealScreenHeight);

		uint32 GRealScreenHeight, GRealScreenWidth;
		AndroidEGL::GetInstance()->GetDimensions( GRealScreenWidth, GRealScreenHeight);

		glBlitFramebuffer(
			0, 0, BackbufferSizeX, BackbufferSizeY,
			0, GRealScreenHeight, GRealScreenWidth, 0,
			GL_COLOR_BUFFER_BIT,
			GL_LINEAR
		);

		if (bPresent)
		{
			uint32 IdleStart = FPlatformTime::Cycles();

			AndroidEGL::GetInstance()->SwapBuffers();
			REPORT_GL_END_BUFFER_EVENT_FOR_FRAME_DUMP();
//			INITIATE_GL_FRAME_DUMP_EVERY_X_CALLS( 1000 );

			GRenderThreadIdle[ERenderThreadIdleTypes::WaitingForGPUPresent] += FPlatformTime::Cycles() - IdleStart;
			GRenderThreadNumIdle[ERenderThreadIdleTypes::WaitingForGPUPresent]++;
		}
	}
//	return true;
	//Do not want WaitForFrameEventCompletion
	return false;
}
Ejemplo n.º 4
0
FTexture2DRHIRef FOpenGLDynamicRHI::RHIGetViewportBackBuffer(FViewportRHIParamRef ViewportRHI)
{
	FOpenGLViewport* Viewport = ResourceCast(ViewportRHI);
	return Viewport->GetBackBuffer();
}
Ejemplo n.º 5
0
void FOpenGLDynamicRHI::RHIEndDrawingViewport(FViewportRHIParamRef ViewportRHI,bool bPresent,bool bLockToVsync)
{
	VERIFY_GL_SCOPE();

	FOpenGLViewport* Viewport = ResourceCast(ViewportRHI);

	SCOPE_CYCLE_COUNTER(STAT_OpenGLPresentTime);

	check(DrawingViewport.GetReference() == Viewport);

	FOpenGLTexture2D* BackBuffer = Viewport->GetBackBuffer();

	bool bNeedFinishFrame = PlatformBlitToViewport(PlatformDevice,
		*Viewport, 
		BackBuffer->GetSizeX(),
		BackBuffer->GetSizeY(),
		bPresent,
		bLockToVsync,
		RHIOpenGLConsoleVariables::SyncInterval
	);

	// Always consider the Framebuffer in the rendering context dirty after the blit
	RenderingContextState.Framebuffer = -1;

	DrawingViewport = NULL;

	// Don't wait on the GPU when using SLI, let the driver determine how many frames behind the GPU should be allowed to get
	if (GNumActiveGPUsForRendering == 1)
	{
		if (bNeedFinishFrame)
		{
			static const auto CFinishFrameVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.FinishCurrentFrame"));
			if (!CFinishFrameVar->GetValueOnRenderThread())
			{
				// Wait for the GPU to finish rendering the previous frame before finishing this frame.
				Viewport->WaitForFrameEventCompletion();
				Viewport->IssueFrameEvent();
			}
			else
			{
				// Finish current frame immediately to reduce latency
				Viewport->IssueFrameEvent();
				Viewport->WaitForFrameEventCompletion();
			}
		}
		
		// If the input latency timer has been triggered, block until the GPU is completely
		// finished displaying this frame and calculate the delta time.
		if ( GInputLatencyTimer.RenderThreadTrigger )
		{
			Viewport->WaitForFrameEventCompletion();
			uint32 EndTime = FPlatformTime::Cycles();
			GInputLatencyTimer.DeltaTime = EndTime - GInputLatencyTimer.StartTime;
			GInputLatencyTimer.RenderThreadTrigger = false;
		}
	}

	if (bRevertToSharedContextAfterDrawingViewport)
	{
		PlatformSharedContextSetup(PlatformDevice);
		bRevertToSharedContextAfterDrawingViewport = false;
	}
}
Ejemplo n.º 6
0
/**
 * Main function for transferring data to on-screen buffers.
 * On Windows it temporarily switches OpenGL context, on Mac only context's output view.
 */
bool PlatformBlitToViewport( FPlatformOpenGLDevice* Device, const FOpenGLViewport& Viewport, uint32 BackbufferSizeX, uint32 BackbufferSizeY, bool bPresent,bool bLockToVsync, int32 SyncInterval )
{
	FPlatformOpenGLContext* const Context = Viewport.GetGLContext();

	check(Context && Context->DeviceContext);

	FScopeLock ScopeLock(Device->ContextUsageGuard);
	{
		FPlatformOpenGLContext TempContext = *Context;
		if (Device->ViewportContexts.Num() == 1)
		{
			TempContext.OpenGLContext = Device->RenderingContext.OpenGLContext;
			TempContext.ViewportFramebuffer = Device->RenderingContext.ViewportFramebuffer;
		}
		FScopeContext ScopeContext(&TempContext);

		GLuint vfb = TempContext.ViewportFramebuffer;
		if (Viewport.GetCustomPresent())
		{
			Device->TargetDirty = false;
			glDisable(GL_FRAMEBUFFER_SRGB);
			bool bShouldPresent = Viewport.GetCustomPresent()->Present(SyncInterval);
			glEnable(GL_FRAMEBUFFER_SRGB);
			if (!bShouldPresent)
			{
				return false;
			}
			else
			{
				Device->TargetDirty = true;
			}
		}

		if (Device->ViewportContexts.Num() == 1 && Device->TargetDirty)
		{
			glBindFramebuffer(GL_FRAMEBUFFER, TempContext.ViewportFramebuffer);
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, Context->BackBufferTarget, Context->BackBufferResource, 0);

			FOpenGL::CheckFrameBuffer();
			Device->TargetDirty = false;
		}

		glDisable(GL_FRAMEBUFFER_SRGB);
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
		FOpenGL::DrawBuffer(GL_BACK);
		glBindFramebuffer(GL_READ_FRAMEBUFFER, TempContext.ViewportFramebuffer);
		glReadBuffer(GL_COLOR_ATTACHMENT0);

		glBlitFramebuffer(
			0, 0, BackbufferSizeX, BackbufferSizeY,
			0, BackbufferSizeY, BackbufferSizeX, 0,
			GL_COLOR_BUFFER_BIT,
			GL_NEAREST
		);
		glEnable(GL_FRAMEBUFFER_SRGB);

		if (bPresent)
		{
			int32 RealSyncInterval = bLockToVsync ? SyncInterval : 0;
			if (wglSwapIntervalEXT_ProcAddress && Context->SyncInterval != RealSyncInterval)
			{
				wglSwapIntervalEXT_ProcAddress(RealSyncInterval);
				Context->SyncInterval = RealSyncInterval;
			}

			::SwapBuffers(Context->DeviceContext);
			REPORT_GL_END_BUFFER_EVENT_FOR_FRAME_DUMP();
//			INITIATE_GL_FRAME_DUMP_EVERY_X_CALLS( 1000 );
		}
	}
	return true;
}