void PlatformResizeGLContext( FPlatformOpenGLDevice* Device, FPlatformOpenGLContext* Context, uint32 SizeX, uint32 SizeY, bool bFullscreen, bool bWasFullscreen, GLenum BackBufferTarget, GLuint BackBufferResource) { check(Context); FScopeContext ScopeContext(Context); if (FOpenGL::IsES2()) { glViewport(0, 0, SizeX, SizeY); VERIFY_GL(glViewport); } else { if (Context->ViewportFramebuffer == 0) { glGenFramebuffers(1, &Context->ViewportFramebuffer); } glBindFramebuffer(GL_FRAMEBUFFER, Context->ViewportFramebuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, BackBufferTarget, BackBufferResource, 0); #if UE_BUILD_DEBUG glReadBuffer(GL_COLOR_ATTACHMENT0); FOpenGL::DrawBuffer(GL_COLOR_ATTACHMENT0); GLenum CompleteResult = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (CompleteResult != GL_FRAMEBUFFER_COMPLETE) { UE_LOG(LogRHI, Fatal, TEXT("PlatformResizeGLContext: Framebuffer not complete. Status = 0x%x"), CompleteResult); } #endif glViewport(0, 0, SizeX, SizeY); static GLfloat ZeroColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; glClearBufferfv(GL_COLOR, 0, ZeroColor); } }
/** * Resize the GL context. */ void PlatformResizeGLContext( FPlatformOpenGLDevice* Device, FPlatformOpenGLContext* Context, uint32 SizeX, uint32 SizeY, bool bFullscreen, bool bWasFullscreen, GLenum BackBufferTarget, GLuint BackBufferResource) { FScopeLock ScopeLock(Device->ContextUsageGuard); { uint32 WindowStyle = WS_CAPTION | WS_SYSMENU; uint32 WindowStyleEx = 0; HWND InsertAfter = HWND_NOTOPMOST; if (bFullscreen) { // Get the monitor info from the window handle. HMONITOR hMonitor = MonitorFromWindow(Context->WindowHandle, MONITOR_DEFAULTTOPRIMARY); MONITORINFOEX MonitorInfo; memset(&MonitorInfo, 0, sizeof(MONITORINFOEX)); MonitorInfo.cbSize = sizeof(MONITORINFOEX); GetMonitorInfo(hMonitor, &MonitorInfo); DEVMODE Mode; Mode.dmSize = sizeof(DEVMODE); Mode.dmBitsPerPel = 32; Mode.dmPelsWidth = SizeX; Mode.dmPelsHeight = SizeY; Mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; // Turn on fullscreen mode for the current monitor ChangeDisplaySettingsEx(MonitorInfo.szDevice, &Mode, NULL, CDS_FULLSCREEN, NULL); WindowStyle = WS_POPUP; WindowStyleEx = WS_EX_APPWINDOW | WS_EX_TOPMOST; InsertAfter = HWND_TOPMOST; } else if (bWasFullscreen) { ChangeDisplaySettings(NULL, 0); } //SetWindowLong(Context->WindowHandle, GWL_STYLE, WindowStyle); //SetWindowLong(Context->WindowHandle, GWL_EXSTYLE, WindowStyleEx); { FScopeContext ScopeContext(Context); if (Context->ViewportFramebuffer == 0) { glGenFramebuffers(1, &Context->ViewportFramebuffer); } glBindFramebuffer(GL_FRAMEBUFFER, Context->ViewportFramebuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, BackBufferTarget, BackBufferResource, 0); #if UE_BUILD_DEBUG glReadBuffer(GL_COLOR_ATTACHMENT0); glDrawBuffer(GL_COLOR_ATTACHMENT0); #endif FOpenGL::CheckFrameBuffer(); glViewport(0, 0, SizeX, SizeY); static GLfloat ZeroColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; glClearBufferfv(GL_COLOR, 0, ZeroColor ); } } }
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; }
/** * Release an OpenGL context. */ void PlatformReleaseOpenGLContext(FPlatformOpenGLDevice* Device, FPlatformOpenGLContext* Context) { check(Context && Context->OpenGLContext); Device->ViewportContexts.RemoveSingle(Context); Device->TargetDirty = true; { FScopeLock ScopeLock(Device->ContextUsageGuard); { FScopeContext ScopeContext(Context); DeleteQueriesForCurrentContext(Context->OpenGLContext); glBindVertexArray(0); glDeleteVertexArrays(1, &Context->VertexArrayObject); if (Context->ViewportFramebuffer) { glDeleteFramebuffers(1,&Context->ViewportFramebuffer); // this can be done from any context shared with ours, as long as it's not nil. Context->ViewportFramebuffer = 0; } } wglDeleteContext(Context->OpenGLContext); Context->OpenGLContext = NULL; } check(Context->DeviceContext); if (wglGetCurrentDC() == Context->DeviceContext) { wglMakeCurrent( NULL, NULL ); } ReleaseDC(Context->WindowHandle, Context->DeviceContext); Context->DeviceContext = NULL; check(Context->WindowHandle); if (Context->bReleaseWindowOnDestroy) { DestroyWindow(Context->WindowHandle); } Context->WindowHandle = NULL; }
/** * 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]++; } } }
void BlockStatement::startScope() { tables_.localVariables_.push_back(ScopeContext()); }
/** * 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; }