KiCad PCB EDA Suite
Loading...
Searching...
No Matches
KIGFX::RENDER_THREAD Class Reference

Thread that owns the RHI device. More...

#include <render_thread.h>

Public Member Functions

 RENDER_THREAD (RHI_DEVICE_FACTORY aDeviceFactory)
 
 ~RENDER_THREAD ()
 
 RENDER_THREAD (const RENDER_THREAD &)=delete
 
RENDER_THREAD & operator= (const RENDER_THREAD &)=delete
 
bool Start ()
 Block until the render thread has created the device and its pipelines.
 
bool IsRunning () const
 
void SetGlyphAtlas (std::shared_ptr< const RHI_GLYPH_ATLAS_DATA > aAtlas)
 Give the track shaders the font atlas glyph instances draw from.
 
bool SubmitControl (RHI_CONTROL_COMMAND aCmd)
 
void SubmitUpload (RHI_UPLOAD_COMMAND aCmd)
 Callable from any thread.
 
bool WaitForFence (std::chrono::milliseconds aTimeout=std::chrono::milliseconds(2000))
 Block until every command submitted before this call has been processed.
 
void Shutdown ()
 Block until the render thread exits.
 
RHI_BACKEND GetBackendType () const
 
uint32_t GetMaxTextureSize () const
 
RHI_BufferHandle ReserveBufferHandle ()
 Reserve a handle without creating the GPU resource, so RHI_DEVICE_PROXY can hand it out on the UI thread and create the resource on the render thread.
 
RHI_TextureHandle ReserveTextureHandle ()
 
bool ReadbackWindowPixels (RHI_WINDOW_ID aWindowId, wxImage &aImage)
 Read back a window's picture at backing resolution without the overlay and cursor.
 
int GetLoopPhase () const
 
bool IsDeviceLost () const
 
bool HasPresented (RHI_WINDOW_ID aWindowId) const
 
void AddDeviceLostListener (const void *aOwner, std::function< void()> aListener)
 Call aListener on the render thread when the device is lost.
 
void RemoveDeviceLostListener (const void *aOwner)
 Once this returns, the owner's listener is not running and will not be called.
 
void OnDeviceLost ()
 Stop drawing on a lost device.
 

Static Public Member Functions

static void ComputeBackingResolution (uint32_t aLogicalW, uint32_t aLogicalH, float aDpiScale, uint32_t &aBackingW, uint32_t &aBackingH)
 Compute the physical pixel backing size from logical size and DPI scale, at least 1x1.
 

Private Types

enum class  GEOMETRY_RANGES : uint8_t { ALL , NOT_OVERLAY , OVERLAY }
 The ranges of a draw descriptor one geometry pass draws. More...
 

Private Member Functions

void ThreadMain (std::promise< bool > aStarted)
 
void DrainControlQueue ()
 
void DrainUploadQueue ()
 
void HandleFrameRequest (const RHI_CMD_FRAME_REQUEST &aCmd)
 
void HandleSwapchainCreate (const RHI_CMD_SWAPCHAIN_CREATE &aCmd)
 
void HandleSwapchainResize (const RHI_CMD_SWAPCHAIN_RESIZE &aCmd)
 
void HandleSwapchainDestroy (const RHI_CMD_SWAPCHAIN_DESTROY &aCmd)
 
void HandleFence (const RHI_CMD_FENCE &aCmd)
 
void ProcessActiveWindows (bool aIgnorePacing=false)
 
bool EnsureSwapchain (WINDOW_STATE &aWS, const char *aReason)
 
void recreateSwapchainAfterOutOfDate (WINDOW_STATE &aWS, bool aSurfaceLost=false)
 Retire and recreate an out of date swapchain, and its surface too when aSurfaceLost.
 
bool RenderWindow (WINDOW_STATE &aWS)
 
void RenderGeometry (WINDOW_STATE &aWS)
 
void RenderGeometryInto (WINDOW_STATE &aWS, const FRAME_DRAW_DESC &aDesc, RHI_FramebufferHandle aFBO, bool aLogSummary, GEOMETRY_RANGES aRanges=GEOMETRY_RANGES::ALL, uint32_t aStaticDrawMargin=0)
 
bool prepareCursor (WINDOW_STATE &aWS)
 Fill the cursor's uniforms.
 
bool runFenced (std::function< void()> aWork, std::chrono::milliseconds aTimeout)
 Run work on the render thread after everything queued before it.
 
bool writeUniform (RHI_BufferHandle &aUBO, RHI_BindGroupHandle &aBG, RHI_BindGroupLayoutHandle aLayout, const void *aData, size_t aSize)
 Write a uniform block, making its buffer and bind group on first use.
 
void drawCursor (WINDOW_STATE &aWS)
 Draw the cursor into the open composite pass.
 
void DestroyAllWindows ()
 
void destroyWindow (WINDOW_STATE &aWS)
 Free a window's targets, uniforms, swapchain and surface.
 
bool InitRenderInfrastructure ()
 
void DestroyRenderInfrastructure ()
 
void CreateWindowFBOs (WINDOW_STATE &aWS)
 
void DestroyWindowFBOs (WINDOW_STATE &aWS)
 
void DestroyWindowUniforms (WINDOW_STATE &aWS)
 
void wakeRenderThread ()
 
void deferFrameUntil (WINDOW_STATE::Clock::time_point aDue)
 
RHI_BindGroupHandle glyphBindGroup ()
 
void destroyGlyphResources ()
 

Private Attributes

RHI_DEVICE_FACTORY m_deviceFactory
 
std::unique_ptr< RHI_DEVICE > m_device
 
std::mutex m_deviceMutex
 Guards the m_device pointer, not the device, against UI thread reads racing its creation or destruction.
 
std::atomic< RHI_BACKEND > m_backendType { RHI_BACKEND::NONE }
 
std::atomic< uint32_t > m_maxTextureSize { 0 }
 
SYNC_QUEUE< RHI_CONTROL_COMMAND > m_controlQueue
 
SYNC_QUEUE< RHI_UPLOAD_COMMAND > m_uploadQueue
 
std::thread m_thread
 
std::mutex m_workMutex
 
std::condition_variable m_workCV
 
std::atomic< bool > m_running { false }
 
std::atomic< bool > m_shutdownRequested { false }
 
bool m_acceptingWork = false
 Guarded by m_workMutex.
 
std::atomic< bool > m_uploadsPending { false }
 Set by producers and cleared by the drain so the loop can sleep without missing uploads.
 
std::atomic< bool > m_deviceLost { false }
 
std::mutex m_deviceLostMutex
 Held while a listener runs, so removing one waits for it to return.
 
std::unordered_map< const void *, std::function< void()> > m_deviceLostListeners
 
std::mutex m_presentedMutex
 Window IDs are never reused, so an entry outliving its window is harmless.
 
std::unordered_set< RHI_WINDOW_ID > m_presentedWindows
 
std::atomic< int > m_loopPhase { 0 }
 see GetLoopPhase()
 
std::unordered_map< RHI_WINDOW_ID, WINDOW_STATE > m_windows
 
std::vector< WINDOW_STATE * > m_activeWindowOrder
 
std::optional< WINDOW_STATE::Clock::time_point > m_deferredFrameDue
 Earliest time a window held to its display's refresh rate is due, so the loop wakes for it.
 
std::unique_ptr< RHI_GAL_PIPELINES > m_pipelines
 Shared by all windows and created once with the device.
 
std::unique_ptr< RHI_COMPOSITOR > m_compositor
 
RHI_BufferHandle m_unitQuadBuffer
 
RHI_BufferHandle m_quadCornerBuffer
 the unit quad's 4 corners
 
RHI_BufferHandle m_quadIndexBuffer
 its 2 triangles over those corners
 
RHI_TextureHandle m_glyphTexture
 The font atlas the track shaders draw glyphs from, its glyph table and their bind group.
 
RHI_BufferHandle m_glyphTable
 
RHI_BindGroupHandle m_glyphBG
 
bool m_glyphBGHasAtlas = false
 
std::mutex m_glyphAtlasMutex
 
std::shared_ptr< const RHI_GLYPH_ATLAS_DATA > m_glyphAtlas
 
RHI_RenderPassHandle m_geometryRenderPass
 
RHI_RenderPassHandle m_geometryLoadRenderPass
 
RHI_RenderPassHandle m_geometryDepthLoadRenderPass
 clears colour, keeps depth
 
RHI_RenderPassHandle m_geometryDepthDiscardRenderPass
 As m_geometryRenderPass and m_geometryDepthLoadRenderPass, without storing depth nothing reads later.
 
RHI_RenderPassHandle m_geometryDepthLoadDiscardRenderPass
 

Detailed Description

Thread that owns the RHI device.

Other threads talk to it through a control queue for lifecycle and frame commands and an upload queue for data transfers.

Definition at line 66 of file render_thread.h.

Member Enumeration Documentation

◆ GEOMETRY_RANGES

enum class KIGFX::RENDER_THREAD::GEOMETRY_RANGES : uint8_t
strongprivate

The ranges of a draw descriptor one geometry pass draws.

Enumerator
ALL 
NOT_OVERLAY 
OVERLAY 

Definition at line 206 of file render_thread.h.

Constructor & Destructor Documentation

◆ RENDER_THREAD() [1/2]

KIGFX::RENDER_THREAD::RENDER_THREAD ( RHI_DEVICE_FACTORY aDeviceFactory)
explicit

Definition at line 309 of file render_thread.cpp.

References m_deviceFactory, and move.

Referenced by operator=(), and RENDER_THREAD().

◆ ~RENDER_THREAD()

KIGFX::RENDER_THREAD::~RENDER_THREAD ( )

Definition at line 315 of file render_thread.cpp.

References Shutdown().

◆ RENDER_THREAD() [2/2]

KIGFX::RENDER_THREAD::RENDER_THREAD ( const RENDER_THREAD & )
delete

References RENDER_THREAD().

Member Function Documentation

◆ AddDeviceLostListener()

void KIGFX::RENDER_THREAD::AddDeviceLostListener ( const void * aOwner,
std::function< void()> aListener )

Call aListener on the render thread when the device is lost.

Each owner has one listener.

Definition at line 2536 of file render_thread.cpp.

References m_deviceLostListeners, and m_deviceLostMutex.

◆ ComputeBackingResolution()

void KIGFX::RENDER_THREAD::ComputeBackingResolution ( uint32_t aLogicalW,
uint32_t aLogicalH,
float aDpiScale,
uint32_t & aBackingW,
uint32_t & aBackingH )
static

Compute the physical pixel backing size from logical size and DPI scale, at least 1x1.

Definition at line 2499 of file render_thread.cpp.

Referenced by HandleSwapchainCreate(), and HandleSwapchainResize().

◆ CreateWindowFBOs()

◆ deferFrameUntil()

void KIGFX::RENDER_THREAD::deferFrameUntil ( WINDOW_STATE::Clock::time_point aDue)
inlineprivate

Definition at line 307 of file render_thread.h.

References m_deferredFrameDue.

Referenced by ProcessActiveWindows().

◆ DestroyAllWindows()

void KIGFX::RENDER_THREAD::DestroyAllWindows ( )
private

Definition at line 2405 of file render_thread.cpp.

References destroyWindow(), m_device, and m_windows.

Referenced by ThreadMain().

◆ destroyGlyphResources()

void KIGFX::RENDER_THREAD::destroyGlyphResources ( )
private

◆ DestroyRenderInfrastructure()

◆ destroyWindow()

void KIGFX::RENDER_THREAD::destroyWindow ( WINDOW_STATE & aWS)
private

Free a window's targets, uniforms, swapchain and surface.

Definition at line 2418 of file render_thread.cpp.

References DestroyWindowFBOs(), DestroyWindowUniforms(), m_device, KIGFX::WINDOW_STATE::surface, and KIGFX::WINDOW_STATE::swapchain.

Referenced by DestroyAllWindows(), and HandleSwapchainDestroy().

◆ DestroyWindowFBOs()

◆ DestroyWindowUniforms()

◆ DrainControlQueue()

void KIGFX::RENDER_THREAD::DrainControlQueue ( )
private

◆ DrainUploadQueue()

void KIGFX::RENDER_THREAD::DrainUploadQueue ( )
private

Definition at line 760 of file render_thread.cpp.

References IsDeviceLost(), m_device, m_uploadQueue, m_uploadsPending, and T.

Referenced by HandleFence(), ProcessActiveWindows(), and ThreadMain().

◆ drawCursor()

void KIGFX::RENDER_THREAD::drawCursor ( WINDOW_STATE & aWS)
private

Draw the cursor into the open composite pass.

Definition at line 2244 of file render_thread.cpp.

References KIGFX::WINDOW_STATE::FRAME_UNIFORMS::cursorBG, m_device, m_pipelines, m_unitQuadBuffer, and KIGFX::WINDOW_STATE::Uniforms().

◆ EnsureSwapchain()

◆ GetBackendType()

RHI_BACKEND KIGFX::RENDER_THREAD::GetBackendType ( ) const
inline
Returns
RHI_BACKEND::NONE before Start(). Safe from any thread.

Definition at line 116 of file render_thread.h.

References m_backendType.

◆ GetLoopPhase()

int KIGFX::RENDER_THREAD::GetLoopPhase ( ) const
inline
Returns
the render loop's phase, for diagnosing stalls. 0 idle, 1 control drain, 2 upload drain, 3 window processing, 4 geometry, 5 composite, 6 present.

Definition at line 140 of file render_thread.h.

References m_loopPhase.

◆ GetMaxTextureSize()

uint32_t KIGFX::RENDER_THREAD::GetMaxTextureSize ( ) const
inline
Returns
the device's RHI_DEVICE::MaxTextureSize(), or 0 before Start(). Safe from any thread.

Definition at line 121 of file render_thread.h.

References m_maxTextureSize.

◆ glyphBindGroup()

◆ HandleFence()

void KIGFX::RENDER_THREAD::HandleFence ( const RHI_CMD_FENCE & aCmd)
private

◆ HandleFrameRequest()

◆ HandleSwapchainCreate()

◆ HandleSwapchainDestroy()

void KIGFX::RENDER_THREAD::HandleSwapchainDestroy ( const RHI_CMD_SWAPCHAIN_DESTROY & aCmd)
private

◆ HandleSwapchainResize()

◆ HasPresented()

bool KIGFX::RENDER_THREAD::HasPresented ( RHI_WINDOW_ID aWindowId) const
Returns
true once a frame of aWindowId reached the screen, which tells a device that works for that window from one that cannot draw it. Other canvases may share the device.

Definition at line 2529 of file render_thread.cpp.

References m_presentedMutex, and m_presentedWindows.

◆ InitRenderInfrastructure()

◆ IsDeviceLost()

bool KIGFX::RENDER_THREAD::IsDeviceLost ( ) const
inline
Returns
true once the device was lost, after which nothing is drawn. See OnDeviceLost().

Definition at line 145 of file render_thread.h.

References m_deviceLost.

Referenced by DrainControlQueue(), DrainUploadQueue(), ProcessActiveWindows(), ReadbackWindowPixels(), RenderWindow(), and ThreadMain().

◆ IsRunning()

bool KIGFX::RENDER_THREAD::IsRunning ( ) const

Definition at line 345 of file render_thread.cpp.

References m_running.

◆ OnDeviceLost()

void KIGFX::RENDER_THREAD::OnDeviceLost ( )

Stop drawing on a lost device.

The GAL's buffers and textures died with it and only a new canvas remakes them, so the owner learns of the loss through IsDeviceLost(). Render thread only.

Definition at line 2514 of file render_thread.cpp.

References m_deviceLost, m_deviceLostListeners, m_deviceLostMutex, m_uploadQueue, and traceRhi.

Referenced by RenderWindow().

◆ operator=()

RENDER_THREAD & KIGFX::RENDER_THREAD::operator= ( const RENDER_THREAD & )
delete

References RENDER_THREAD().

◆ prepareCursor()

bool KIGFX::RENDER_THREAD::prepareCursor ( WINDOW_STATE & aWS)
private

◆ ProcessActiveWindows()

void KIGFX::RENDER_THREAD::ProcessActiveWindows ( bool aIgnorePacing = false)
private

◆ ReadbackWindowPixels()

◆ recreateSwapchainAfterOutOfDate()

void KIGFX::RENDER_THREAD::recreateSwapchainAfterOutOfDate ( WINDOW_STATE & aWS,
bool aSurfaceLost = false )
private

Retire and recreate an out of date swapchain, and its surface too when aSurfaceLost.

A failed recreation leaves the handle null so the retry backoff applies.

Definition at line 220 of file render_thread.cpp.

References EnsureSwapchain(), m_device, KIGFX::WINDOW_STATE::surface, and KIGFX::WINDOW_STATE::swapchain.

Referenced by HandleSwapchainResize(), ProcessActiveWindows(), and RenderWindow().

◆ RemoveDeviceLostListener()

void KIGFX::RENDER_THREAD::RemoveDeviceLostListener ( const void * aOwner)

Once this returns, the owner's listener is not running and will not be called.

Definition at line 2543 of file render_thread.cpp.

References m_deviceLostListeners, and m_deviceLostMutex.

◆ RenderGeometry()

void KIGFX::RENDER_THREAD::RenderGeometry ( WINDOW_STATE & aWS)
private

◆ RenderGeometryInto()

void KIGFX::RENDER_THREAD::RenderGeometryInto ( WINDOW_STATE & aWS,
const FRAME_DRAW_DESC & aDesc,
RHI_FramebufferHandle aFBO,
bool aLogSummary,
GEOMETRY_RANGES aRanges = GEOMETRY_RANGES::ALL,
uint32_t aStaticDrawMargin = 0 )
private
Parameters
aStaticDrawMarginhow much of the static target's margin to draw when aFBO is the static target. 0 draws only the view in its middle.

Definition at line 1646 of file render_thread.cpp.

References ALL, COMPOSITOR_PUSH_CONSTANTS::alpha, KIGFX::LAYER_RANGE::alpha, KIGFX::LAYER_RANGE::bitmapCount, KIGFX::FRAME_DRAW_DESC::bitmapDraws, KIGFX::LAYER_RANGE::bitmapStart, KIGFX::BLEND, KIGFX::FRAME_DRAW_DESC::buffer, KIGFX::LAYER_RANGE::buffer, copied, KIGFX::FRAME_DRAW_DESC::count, KIGFX::LAYER_RANGE::cullRuns, KIGFX::LAYER_RANGE::depthFar, KIGFX::LAYER_RANGE::depthKnockout, KIGFX::LAYER_RANGE::depthNear, KIGFX::WINDOW_STATE::diffBelowFBO, KIGFX::LAYER_RANGE::difference, KIGFX::LAYER_RANGE::dim, drawBitmap(), KIGFX::FRAME_DRAW_DESC::drawCursor, KIGFX::FRAME_DRAW_DESC::drawGrid, KIGFX::WINDOW_STATE::dynamicFBO, KIGFX::WINDOW_STATE::FRAME_UNIFORMS::dynamicUniforms, RHI_BIND_GROUP_DESC::entries, KIGFX::WINDOW_STATE::PASS_UNIFORMS::frameBG, RHI_RENDER_PASS_BEGIN_DESC::framebuffer, KIGFX::WINDOW_STATE::framesProcessed, KIGFX::FRAME_DRAW_DESC::frameUBO, KIGFX::WINDOW_STATE::PASS_UNIFORMS::frameUBO, KIGFX::WINDOW_STATE::geometryRenderPasses, glyphBindGroup(), KIGFX::WINDOW_STATE::PASS_UNIFORMS::gridBG, KIGFX::FRAME_DRAW_DESC::gridFirst, KIGFX::FRAME_DRAW_DESC::gridUBO, KIGFX::WINDOW_STATE::PASS_UNIFORMS::gridUBO, KIGFX::LAYER_RANGE::HasGeometry(), RHI_FRAMEBUFFER_DESC::height, RHI_SCISSOR_RECT::height, RHI_VIEWPORT::height, layerFramebufferDesc(), KIGFX::FRAME_DRAW_DESC::layerRanges, RHI_BIND_GROUP_DESC::layout, KIGFX::FRAME_DRAW_DESC::linePipelineKind, m_compositor, m_device, m_geometryDepthDiscardRenderPass, m_geometryDepthLoadDiscardRenderPass, m_geometryDepthLoadRenderPass, m_geometryLoadRenderPass, m_geometryRenderPass, m_pipelines, m_quadCornerBuffer, m_quadIndexBuffer, m_unitQuadBuffer, KIGFX::MARK, RHI_VIEWPORT::maxDepth, RHI_VIEWPORT::minDepth, KIGFX::LAYER_RANGE::NeedsTempFBO(), KIGFX::NEGATIVE, KIGFX::LAYER_RANGE::negBuffer, KIGFX::FRAME_DRAW_DESC::negCount, KIGFX::ONCE, OVERLAY, KIGFX::LAYER_RANGE::overlayAlpha, KIGFX::WINDOW_STATE::overlayMarginFBO, KIGFX::WINDOW_STATE::FRAME_UNIFORMS::overlayUniforms, KIGFX::FRAME_DRAW_DESC::polarityRuns, KIGFX::WINDOW_STATE::RenderHeight(), RHI_RENDER_PASS_BEGIN_DESC::renderPass, KIGFX::WINDOW_STATE::RenderWidth(), KIGFX::RHI_INSTANCED_SHAPES, KIGFX::RHI_SHAPE_ARC, KIGFX::RHI_SHAPE_PAD, KIGFX::RHI_SHAPE_POLYGON, KIGFX::RHI_SHAPE_TRACK, KIGFX::RhiCullRunLength(), KIGFX::RhiCullView(), KIGFX::RhiForVisibleStretches(), KIGFX::RhiPlanLayerDraws(), KIGFX::RhiSupersampleFrame(), KIGFX::RhiSupersampleGrid(), KIGFX::RhiWidenFrame(), KIGFX::RhiWidenGrid(), KIGFX::SCH_WIRES, KIGFX::WINDOW_STATE::ShownStaticFBO(), KIGFX::WINDOW_STATE::ShownStaticX(), KIGFX::WINDOW_STATE::ShownStaticY(), KIGFX::WINDOW_STATE::staticDiffBelowFBO, KIGFX::WINDOW_STATE::staticFBO, KIGFX::WINDOW_STATE::StaticHeight(), KIGFX::WINDOW_STATE::staticMargin, KIGFX::WINDOW_STATE::staticTempFBO, KIGFX::WINDOW_STATE::FRAME_UNIFORMS::staticUniforms, KIGFX::WINDOW_STATE::staticViewFBO, KIGFX::WINDOW_STATE::StaticWidth(), KIGFX::WINDOW_STATE::supersampleFactor, KIGFX::TARGET_OVERLAY, KIGFX::WINDOW_STATE::tempFBO, KIGFX::FRAME_DRAW_DESC::testAgainstStatic, traceRhi, KIGFX::WINDOW_STATE::Uniforms(), RHI_FRAMEBUFFER_DESC::width, RHI_SCISSOR_RECT::width, RHI_VIEWPORT::width, KIGFX::WINDOW_STATE::windowId, writeUniform(), RHI_SCISSOR_RECT::x, RHI_VIEWPORT::x, RHI_SCISSOR_RECT::y, and RHI_VIEWPORT::y.

Referenced by RenderGeometry(), and RenderWindow().

◆ RenderWindow()

bool KIGFX::RENDER_THREAD::RenderWindow ( WINDOW_STATE & aWS)
private
Returns
true only if a frame was presented, so a skipped or failed frame does not report its generation as complete.

Definition at line 1279 of file render_thread.cpp.

References KIGFX::WINDOW_STATE::accumulationFBO, ALL, KIGFX::FRAME_DRAW_DESC::backgroundColor, KIGFX::WINDOW_STATE::backingHeight, KIGFX::WINDOW_STATE::backingWidth, KIGFX::FRAME_DRAW_DESC::bitmapDraws, KIGFX::FRAME_DRAW_DESC::count, cursor, destroyDiffCopies(), DEVICE_LOST, KIGFX::WINDOW_STATE::diffBelowFBO, KIGFX::WINDOW_STATE::drawDesc, KIGFX::FRAME_DRAW_DESC::drawGrid, KIGFX::WINDOW_STATE::RENDERED_CONTENT::drawGrid, MARGIN_PLAN::drawMargin, KIGFX::WINDOW_STATE::dynamicChanged, KIGFX::WINDOW_STATE::dynamicDrawDesc, KIGFX::WINDOW_STATE::dynamicEpoch, KIGFX::WINDOW_STATE::dynamicFBO, KIGFX::WINDOW_STATE::dynamicGeometryDrawn, KIGFX::WINDOW_STATE::dynamicPasses, EnsureSwapchain(), KIGFX::WINDOW_STATE::RENDERED_CONTENT::epoch, KIGFX::FRAME_DRAW_DESC::frameUBO, KIGFX::WINDOW_STATE::RENDERED_CONTENT::frameUBO, KIGFX::WINDOW_STATE::geometryRenderPasses, KIGFX::WINDOW_STATE::RENDERED_CONTENT::gridUBO, KIGFX::FRAME_DRAW_DESC::HasGeometry(), RHI_SCISSOR_RECT::height, IsDeviceLost(), KIGFX::WINDOW_STATE::lastFrameRequestTime, KIGFX::WINDOW_STATE::lastPresentAttemptTime, KIGFX::WINDOW_STATE::lastPresentedGeneration, KIGFX::WINDOW_STATE::lastPresentFailureTime, KIGFX::WINDOW_STATE::lastPresentSuccessTime, KIGFX::WINDOW_STATE::lastRenderCompleteTime, KIGFX::WINDOW_STATE::lastRenderStartTime, layerFramebufferDesc(), KIGFX::FRAME_DRAW_DESC::layerRanges, m_compositor, m_device, m_geometryRenderPass, m_loopPhase, m_pipelines, m_presentedMutex, m_presentedWindows, KIGFX::WINDOW_STATE::RENDERED_CONTENT::margin, marginFramebufferDesc(), marginLayer(), PROF_TIMER::msecs(), KIGFX::WINDOW_STATE::needsStaticInvalidate, KIGFX::FRAME_DRAW_DESC::negCount, NOT_OVERLAY, OK, OnDeviceLost(), OUT_OF_DATE, OVERLAY, KIGFX::WINDOW_STATE::overlayGeometryDrawn, KIGFX::WINDOW_STATE::overlayGeometryFBO, KIGFX::WINDOW_STATE::overlayInMargin, KIGFX::WINDOW_STATE::overlayMarginFBO, KIGFX::WINDOW_STATE::overlayShift, plan(), planMarginTarget(), prepareCursor(), KIGFX::WINDOW_STATE::presentFailureCount, KIGFX::WINDOW_STATE::presentSuccessCount, recreateSwapchainAfterOutOfDate(), KIGFX::WINDOW_STATE::renderedDynamic, KIGFX::WINDOW_STATE::renderedOverlay, KIGFX::WINDOW_STATE::renderedStatic, RenderGeometry(), RenderGeometryInto(), KIGFX::WINDOW_STATE::RenderHeight(), KIGFX::WINDOW_STATE::RenderWidth(), KIGFX::WINDOW_STATE::requestedGeneration, MARGIN_PLAN::reuse, KIGFX::FRAME_DRAW_DESC::reuseDynamicFBO, KIGFX::FRAME_DRAW_DESC::reuseStaticFBO, KIGFX::RHI_SHAPE_ARC, KIGFX::RHI_SHAPE_PAD, KIGFX::RHI_SHAPE_POLYGON, KIGFX::RHI_SHAPE_TRACK, KIGFX::RhiCullView(), KIGFX::RhiWidenFrame(), MARGIN_PLAN::shift, KIGFX::WINDOW_STATE::ShownStaticFBO(), KIGFX::WINDOW_STATE::ShownStaticX(), KIGFX::WINDOW_STATE::ShownStaticY(), KIGFX::WINDOW_STATE::staticChanged, KIGFX::WINDOW_STATE::staticDiffBelowFBO, KIGFX::WINDOW_STATE::staticDrawDesc, KIGFX::WINDOW_STATE::staticEpoch, KIGFX::WINDOW_STATE::staticFBO, KIGFX::WINDOW_STATE::staticInMargin, KIGFX::WINDOW_STATE::staticMargin, KIGFX::WINDOW_STATE::staticPasses, KIGFX::WINDOW_STATE::staticShift, KIGFX::WINDOW_STATE::staticViewFBO, SURFACE_LOST, KIGFX::WINDOW_STATE::swapchain, traceRhi, KIGFX::WINDOW_STATE::UNIFORM_GENERATIONS, KIGFX::WINDOW_STATE::uniformGeneration, KIGFX::WINDOW_STATE::RENDERED_CONTENT::valid, RHI_SCISSOR_RECT::width, KIGFX::WINDOW_STATE::windowId, WindowStateAgeMs(), WindowStateDurationMs(), RHI_SCISSOR_RECT::x, and RHI_SCISSOR_RECT::y.

Referenced by ProcessActiveWindows().

◆ ReserveBufferHandle()

RHI_BufferHandle KIGFX::RENDER_THREAD::ReserveBufferHandle ( )

Reserve a handle without creating the GPU resource, so RHI_DEVICE_PROXY can hand it out on the UI thread and create the resource on the render thread.

Null when there is no device.

Definition at line 396 of file render_thread.cpp.

References m_device, and m_deviceMutex.

◆ ReserveTextureHandle()

RHI_TextureHandle KIGFX::RENDER_THREAD::ReserveTextureHandle ( )

Definition at line 403 of file render_thread.cpp.

References m_device, and m_deviceMutex.

◆ runFenced()

bool KIGFX::RENDER_THREAD::runFenced ( std::function< void()> aWork,
std::chrono::milliseconds aTimeout )
private

Run work on the render thread after everything queued before it.

Returns
false on timeout.

Definition at line 416 of file render_thread.cpp.

References RHI_CMD_FENCE::flushFrames, RHI_CMD_FENCE::onComplete, and SubmitControl().

Referenced by ReadbackWindowPixels(), and WaitForFence().

◆ SetGlyphAtlas()

void KIGFX::RENDER_THREAD::SetGlyphAtlas ( std::shared_ptr< const RHI_GLYPH_ATLAS_DATA > aAtlas)

Give the track shaders the font atlas glyph instances draw from.

Only the first atlas is kept. Callable from any thread.

Definition at line 956 of file render_thread.cpp.

References m_glyphAtlas, and m_glyphAtlasMutex.

◆ Shutdown()

void KIGFX::RENDER_THREAD::Shutdown ( )

Block until the render thread exits.

Safe to call repeatedly or if the thread never started.

Definition at line 530 of file render_thread.cpp.

References m_running, m_shutdownRequested, m_thread, traceRhi, and wakeRenderThread().

Referenced by ~RENDER_THREAD().

◆ Start()

bool KIGFX::RENDER_THREAD::Start ( )

Block until the render thread has created the device and its pipelines.

Returns
false if either could not be created.

Definition at line 321 of file render_thread.cpp.

References m_running, m_shutdownRequested, m_thread, and ThreadMain().

◆ SubmitControl()

bool KIGFX::RENDER_THREAD::SubmitControl ( RHI_CONTROL_COMMAND aCmd)
Returns
true if the command was enqueued, which it is until the thread starts shutting down.

Definition at line 363 of file render_thread.cpp.

References m_acceptingWork, m_controlQueue, m_workCV, and m_workMutex.

Referenced by runFenced().

◆ SubmitUpload()

void KIGFX::RENDER_THREAD::SubmitUpload ( RHI_UPLOAD_COMMAND aCmd)

Callable from any thread.

Definition at line 380 of file render_thread.cpp.

References m_acceptingWork, m_uploadQueue, m_uploadsPending, m_workCV, and m_workMutex.

◆ ThreadMain()

◆ WaitForFence()

bool KIGFX::RENDER_THREAD::WaitForFence ( std::chrono::milliseconds aTimeout = std::chrono::milliseconds( 2000 ))

Block until every command submitted before this call has been processed.

Returns
true if the fence completed within the timeout.

Definition at line 410 of file render_thread.cpp.

References runFenced().

◆ wakeRenderThread()

void KIGFX::RENDER_THREAD::wakeRenderThread ( )
private

Definition at line 351 of file render_thread.cpp.

References m_workCV, and m_workMutex.

Referenced by Shutdown().

◆ writeUniform()

bool KIGFX::RENDER_THREAD::writeUniform ( RHI_BufferHandle & aUBO,
RHI_BindGroupHandle & aBG,
RHI_BindGroupLayoutHandle aLayout,
const void * aData,
size_t aSize )
private

Write a uniform block, making its buffer and bind group on first use.

Returns
false when either could not be made.

Definition at line 2214 of file render_thread.cpp.

References RHI_BIND_GROUP_DESC::entries, RHI_BIND_GROUP_DESC::layout, m_device, RHI_BUFFER_DESC::mappable, RHI_UBO_BINDING, RHI_BUFFER_DESC::sizeBytes, RHI_BUFFER_DESC::type, and UNIFORM.

Referenced by prepareCursor(), and RenderGeometryInto().

Member Data Documentation

◆ m_acceptingWork

bool KIGFX::RENDER_THREAD::m_acceptingWork = false
private

Guarded by m_workMutex.

Cleared before the shutdown drain so nothing queued later is lost.

Definition at line 284 of file render_thread.h.

Referenced by SubmitControl(), SubmitUpload(), and ThreadMain().

◆ m_activeWindowOrder

std::vector<WINDOW_STATE*> KIGFX::RENDER_THREAD::m_activeWindowOrder
private

Definition at line 302 of file render_thread.h.

Referenced by ProcessActiveWindows().

◆ m_backendType

std::atomic<RHI_BACKEND> KIGFX::RENDER_THREAD::m_backendType { RHI_BACKEND::NONE }
private

Definition at line 269 of file render_thread.h.

Referenced by GetBackendType(), and ThreadMain().

◆ m_compositor

std::unique_ptr<RHI_COMPOSITOR> KIGFX::RENDER_THREAD::m_compositor
private

◆ m_controlQueue

SYNC_QUEUE<RHI_CONTROL_COMMAND> KIGFX::RENDER_THREAD::m_controlQueue
private

Definition at line 272 of file render_thread.h.

Referenced by DrainControlQueue(), SubmitControl(), and ThreadMain().

◆ m_deferredFrameDue

std::optional<WINDOW_STATE::Clock::time_point> KIGFX::RENDER_THREAD::m_deferredFrameDue
private

Earliest time a window held to its display's refresh rate is due, so the loop wakes for it.

Definition at line 305 of file render_thread.h.

Referenced by deferFrameUntil(), ProcessActiveWindows(), and ThreadMain().

◆ m_device

◆ m_deviceFactory

RHI_DEVICE_FACTORY KIGFX::RENDER_THREAD::m_deviceFactory
private

Definition at line 259 of file render_thread.h.

Referenced by RENDER_THREAD(), and ThreadMain().

◆ m_deviceLost

std::atomic<bool> KIGFX::RENDER_THREAD::m_deviceLost { false }
private

Definition at line 288 of file render_thread.h.

Referenced by IsDeviceLost(), and OnDeviceLost().

◆ m_deviceLostListeners

std::unordered_map<const void*, std::function<void()> > KIGFX::RENDER_THREAD::m_deviceLostListeners
private

Definition at line 292 of file render_thread.h.

Referenced by AddDeviceLostListener(), OnDeviceLost(), and RemoveDeviceLostListener().

◆ m_deviceLostMutex

std::mutex KIGFX::RENDER_THREAD::m_deviceLostMutex
private

Held while a listener runs, so removing one waits for it to return.

Definition at line 291 of file render_thread.h.

Referenced by AddDeviceLostListener(), OnDeviceLost(), and RemoveDeviceLostListener().

◆ m_deviceMutex

std::mutex KIGFX::RENDER_THREAD::m_deviceMutex
mutableprivate

Guards the m_device pointer, not the device, against UI thread reads racing its creation or destruction.

The device's pools are thread-safe and its maps are render thread only.

Definition at line 267 of file render_thread.h.

Referenced by ReserveBufferHandle(), ReserveTextureHandle(), and ThreadMain().

◆ m_geometryDepthDiscardRenderPass

RHI_RenderPassHandle KIGFX::RENDER_THREAD::m_geometryDepthDiscardRenderPass
private

As m_geometryRenderPass and m_geometryDepthLoadRenderPass, without storing depth nothing reads later.

Definition at line 336 of file render_thread.h.

Referenced by DestroyRenderInfrastructure(), InitRenderInfrastructure(), and RenderGeometryInto().

◆ m_geometryDepthLoadDiscardRenderPass

RHI_RenderPassHandle KIGFX::RENDER_THREAD::m_geometryDepthLoadDiscardRenderPass
private

◆ m_geometryDepthLoadRenderPass

RHI_RenderPassHandle KIGFX::RENDER_THREAD::m_geometryDepthLoadRenderPass
private

clears colour, keeps depth

Definition at line 333 of file render_thread.h.

Referenced by DestroyRenderInfrastructure(), InitRenderInfrastructure(), and RenderGeometryInto().

◆ m_geometryLoadRenderPass

RHI_RenderPassHandle KIGFX::RENDER_THREAD::m_geometryLoadRenderPass
private

◆ m_geometryRenderPass

RHI_RenderPassHandle KIGFX::RENDER_THREAD::m_geometryRenderPass
private

◆ m_glyphAtlas

std::shared_ptr<const RHI_GLYPH_ATLAS_DATA> KIGFX::RENDER_THREAD::m_glyphAtlas
private

Definition at line 326 of file render_thread.h.

Referenced by glyphBindGroup(), and SetGlyphAtlas().

◆ m_glyphAtlasMutex

std::mutex KIGFX::RENDER_THREAD::m_glyphAtlasMutex
mutableprivate

Definition at line 325 of file render_thread.h.

Referenced by glyphBindGroup(), and SetGlyphAtlas().

◆ m_glyphBG

RHI_BindGroupHandle KIGFX::RENDER_THREAD::m_glyphBG
private

Definition at line 322 of file render_thread.h.

Referenced by destroyGlyphResources(), and glyphBindGroup().

◆ m_glyphBGHasAtlas

bool KIGFX::RENDER_THREAD::m_glyphBGHasAtlas = false
private

Definition at line 323 of file render_thread.h.

Referenced by destroyGlyphResources(), and glyphBindGroup().

◆ m_glyphTable

RHI_BufferHandle KIGFX::RENDER_THREAD::m_glyphTable
private

Definition at line 321 of file render_thread.h.

Referenced by destroyGlyphResources(), and glyphBindGroup().

◆ m_glyphTexture

RHI_TextureHandle KIGFX::RENDER_THREAD::m_glyphTexture
private

The font atlas the track shaders draw glyphs from, its glyph table and their bind group.

Definition at line 320 of file render_thread.h.

Referenced by destroyGlyphResources(), and glyphBindGroup().

◆ m_loopPhase

std::atomic<int> KIGFX::RENDER_THREAD::m_loopPhase { 0 }
private

◆ m_maxTextureSize

std::atomic<uint32_t> KIGFX::RENDER_THREAD::m_maxTextureSize { 0 }
private

Definition at line 270 of file render_thread.h.

Referenced by GetMaxTextureSize(), and ThreadMain().

◆ m_pipelines

std::unique_ptr<RHI_GAL_PIPELINES> KIGFX::RENDER_THREAD::m_pipelines
private

Shared by all windows and created once with the device.

Definition at line 313 of file render_thread.h.

Referenced by DestroyRenderInfrastructure(), drawCursor(), glyphBindGroup(), InitRenderInfrastructure(), prepareCursor(), RenderGeometryInto(), and RenderWindow().

◆ m_presentedMutex

std::mutex KIGFX::RENDER_THREAD::m_presentedMutex
mutableprivate

Window IDs are never reused, so an entry outliving its window is harmless.

Definition at line 295 of file render_thread.h.

Referenced by HasPresented(), and RenderWindow().

◆ m_presentedWindows

std::unordered_set<RHI_WINDOW_ID> KIGFX::RENDER_THREAD::m_presentedWindows
private

Definition at line 296 of file render_thread.h.

Referenced by HasPresented(), and RenderWindow().

◆ m_quadCornerBuffer

RHI_BufferHandle KIGFX::RENDER_THREAD::m_quadCornerBuffer
private

the unit quad's 4 corners

Definition at line 316 of file render_thread.h.

Referenced by DestroyRenderInfrastructure(), InitRenderInfrastructure(), and RenderGeometryInto().

◆ m_quadIndexBuffer

RHI_BufferHandle KIGFX::RENDER_THREAD::m_quadIndexBuffer
private

its 2 triangles over those corners

Definition at line 317 of file render_thread.h.

Referenced by DestroyRenderInfrastructure(), InitRenderInfrastructure(), and RenderGeometryInto().

◆ m_running

std::atomic<bool> KIGFX::RENDER_THREAD::m_running { false }
private

Definition at line 280 of file render_thread.h.

Referenced by IsRunning(), Shutdown(), Start(), and ThreadMain().

◆ m_shutdownRequested

std::atomic<bool> KIGFX::RENDER_THREAD::m_shutdownRequested { false }
private

Definition at line 281 of file render_thread.h.

Referenced by DrainControlQueue(), Shutdown(), Start(), and ThreadMain().

◆ m_thread

std::thread KIGFX::RENDER_THREAD::m_thread
private

Definition at line 275 of file render_thread.h.

Referenced by Shutdown(), and Start().

◆ m_unitQuadBuffer

RHI_BufferHandle KIGFX::RENDER_THREAD::m_unitQuadBuffer
private

◆ m_uploadQueue

SYNC_QUEUE<RHI_UPLOAD_COMMAND> KIGFX::RENDER_THREAD::m_uploadQueue
private

Definition at line 273 of file render_thread.h.

Referenced by DrainUploadQueue(), OnDeviceLost(), SubmitUpload(), and ThreadMain().

◆ m_uploadsPending

std::atomic<bool> KIGFX::RENDER_THREAD::m_uploadsPending { false }
private

Set by producers and cleared by the drain so the loop can sleep without missing uploads.

Definition at line 287 of file render_thread.h.

Referenced by DrainUploadQueue(), SubmitUpload(), and ThreadMain().

◆ m_windows

◆ m_workCV

std::condition_variable KIGFX::RENDER_THREAD::m_workCV
private

Definition at line 278 of file render_thread.h.

Referenced by SubmitControl(), SubmitUpload(), ThreadMain(), and wakeRenderThread().

◆ m_workMutex

std::mutex KIGFX::RENDER_THREAD::m_workMutex
private

Definition at line 277 of file render_thread.h.

Referenced by SubmitControl(), SubmitUpload(), ThreadMain(), and wakeRenderThread().


The documentation for this class was generated from the following files: