void FSlate3DRenderer::DrawWindow_GameThread(FSlateDrawBuffer& DrawBuffer) { check( IsInGameThread() ); const TSharedRef<FSlateFontCache> FontCache = SlateFontServices->GetGameThreadFontCache(); TArray<TSharedPtr<FSlateWindowElementList>>& WindowElementLists = DrawBuffer.GetWindowElementLists(); for ( int32 WindowIndex = 0; WindowIndex < WindowElementLists.Num(); WindowIndex++ ) { FSlateWindowElementList& ElementList = *WindowElementLists[WindowIndex]; TSharedPtr<SWindow> Window = ElementList.GetWindow(); if ( Window.IsValid() ) { const FVector2D WindowSize = Window->GetSizeInScreen(); if ( WindowSize.X > 0 && WindowSize.Y > 0 ) { // Add all elements for this window to the element batcher ElementBatcher->AddElements(ElementList); // Update the font cache with new text after elements are batched FontCache->UpdateCache(); // All elements for this window have been batched and rendering data updated ElementBatcher->ResetBatches(); } } } }
/** * Creates necessary resources to render a window and sends draw commands to the rendering thread * * @param WindowDrawBuffer The buffer containing elements to draw */ void FSlateOpenGLRenderer::DrawWindows( FSlateDrawBuffer& InWindowDrawBuffer ) { // Update the font cache with new text before elements are batched FontCache->UpdateCache(); // Draw each window. For performance. All elements are batched before anything is rendered TArray<FSlateWindowElementList>& WindowElementLists = InWindowDrawBuffer.GetWindowElementLists(); for( int32 ListIndex = 0; ListIndex < WindowElementLists.Num(); ++ListIndex ) { FSlateWindowElementList& ElementList = WindowElementLists[ListIndex]; if ( ElementList.GetWindow().IsValid() ) { TSharedRef<SWindow> WindowToDraw = ElementList.GetWindow().ToSharedRef(); const FVector2D WindowSize = WindowToDraw->GetSizeInScreen(); FSlateOpenGLViewport* Viewport = WindowToViewportMap.Find( &WindowToDraw.Get() ); check(Viewport); //@todo Slate OpenGL: Move this to ResizeViewport if( WindowSize.X != Viewport->ViewportRect.Right || WindowSize.Y != Viewport->ViewportRect.Bottom ) { //@todo implement fullscreen const bool bFullscreen = false; Private_ResizeViewport( WindowSize, *Viewport, bFullscreen ); } Viewport->MakeCurrent(); // Batch elements. Note that we must set the current viewport before doing this so we have a valid rendering context when calling OpenGL functions ElementBatcher->AddElements( ElementList.GetDrawElements() ); //@ todo Slate: implement for opengl bool bRequiresStencilTest = false; ElementBatcher->FillBatchBuffers( ElementList, bRequiresStencilTest ); ElementBatcher->ResetBatches(); RenderingPolicy->UpdateBuffers( ElementList ); check(Viewport); glViewport( Viewport->ViewportRect.Left, Viewport->ViewportRect.Top, Viewport->ViewportRect.Right, Viewport->ViewportRect.Bottom ); // Draw all elements RenderingPolicy->DrawElements( ViewMatrix*Viewport->ProjectionMatrix, ElementList.GetRenderBatches() ); Viewport->SwapBuffers(); // Reset all batch data for this window ElementBatcher->ResetBatches(); } } FontCache->ConditionalFlushCache(); }
void FSlateD3DRenderer::DrawWindows( FSlateDrawBuffer& InWindowDrawBuffer ) { // Update the font cache with new text before elements are batched FontCache->UpdateCache(); // Iterate through each element list and set up an RHI window for it if needed TArray<FSlateWindowElementList>& WindowElementLists = InWindowDrawBuffer.GetWindowElementLists(); for( int32 ListIndex = 0; ListIndex < WindowElementLists.Num(); ++ListIndex ) { FSlateWindowElementList& ElementList = WindowElementLists[ListIndex]; if ( ElementList.GetWindow().IsValid() ) { TSharedRef<SWindow> WindowToDraw = ElementList.GetWindow().ToSharedRef(); // Add all elements for this window to the element batcher ElementBatcher->AddElements( ElementList.GetDrawElements() ); bool bUnused = false; ElementBatcher->FillBatchBuffers( ElementList, bUnused ); // All elements for this window have been batched and rendering data updated ElementBatcher->ResetBatches(); FVector2D WindowSize = WindowToDraw->GetSizeInScreen(); FSlateD3DViewport* Viewport = WindowToViewportMap.Find( &WindowToDraw.Get() ); check(Viewport); RenderingPolicy->UpdateBuffers( ElementList ); check(Viewport); GD3DDeviceContext->RSSetViewports(1, &Viewport->ViewportInfo ); ID3D11RenderTargetView* RTV = Viewport->RenderTargetView; ID3D11DepthStencilView* DSV = Viewport->DepthStencilView; GD3DDeviceContext->OMSetRenderTargets( 1, &RTV, NULL ); RenderingPolicy->DrawElements( ViewMatrix*Viewport->ProjectionMatrix, ElementList.GetRenderBatches() ); GD3DDeviceContext->OMSetRenderTargets(0, NULL, NULL); const bool bUseVSync = false; Viewport->D3DSwapChain->Present( bUseVSync ? 1 : 0, 0); // All elements have been drawn. Reset all cached data ElementBatcher->ResetBatches(); } } // flush the cache if needed FontCache->ConditionalFlushCache(); }
FSlateDrawBuffer& FSlate3DRenderer::GetDrawBuffer() { FreeBufferIndex = (FreeBufferIndex + 1) % NUM_DRAW_BUFFERS; FSlateDrawBuffer* Buffer = &DrawBuffers[FreeBufferIndex]; while (!Buffer->Lock()) { FlushRenderingCommands(); UE_LOG(LogSlate, Log, TEXT("Slate: Had to block on waiting for a draw buffer")); FreeBufferIndex = (FreeBufferIndex + 1) % NumDrawBuffers; Buffer = &DrawBuffers[FreeBufferIndex]; } Buffer->ClearBuffer(); return *Buffer; }
void FSlate3DRenderer::DrawWindowToTarget_RenderThread( FRHICommandListImmediate& InRHICmdList, FTextureRenderTarget2DResource* RenderTargetResource, FSlateDrawBuffer& WindowDrawBuffer, bool bInClearTarget) { SCOPED_DRAW_EVENT( InRHICmdList, SlateRenderToTarget ); SCOPED_GPU_STAT(InRHICmdList, Slate3D); checkSlow( RenderTargetResource ); TArray< TSharedPtr<FSlateWindowElementList> >& WindowsToDraw = WindowDrawBuffer.GetWindowElementLists(); // Enqueue a command to unlock the draw buffer after all windows have been drawn ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(SlateBeginDrawingWindowsCommand, FSlateRHIRenderingPolicy&, Policy, *RenderTargetPolicy, { Policy.BeginDrawingWindows(); });