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;
}
/**
 * Main function for transferring data to on-screen buffers.
 * On Windows it temporarily switches OpenGL context, on Mac only context's output view.
 */
void PlatformBlitToViewport( FPlatformOpenGLDevice* Device, FPlatformOpenGLContext* Context, uint32 BackbufferSizeX, uint32 BackbufferSizeY, bool bPresent,bool bLockToVsync, int32 SyncInterval )
{
	check(Context && Context->DeviceContext);

	FScopeLock ScopeLock(Device->ContextUsageGuard);
	{
		FScopeContext ScopeContext(Context);

		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
		glDrawBuffer(GL_BACK);
		glBindFramebuffer(GL_READ_FRAMEBUFFER, Context->ViewportFramebuffer);
		glReadBuffer(GL_COLOR_ATTACHMENT0);

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

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

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

			GRenderThreadIdle[ERenderThreadIdleTypes::WaitingForGPUPresent] += FPlatformTime::Cycles() - IdleStart;
			GRenderThreadNumIdle[ERenderThreadIdleTypes::WaitingForGPUPresent]++;
		}
	}
}
Example #3
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;
}