From 14fc68059c5d533669d9d476814368feb9c49047 Mon Sep 17 00:00:00 2001 From: Sam Pepose Date: Sun, 8 Jun 2025 17:13:42 -0400 Subject: [PATCH] Add video renderer pool prewarming API - Add VideoRendererConfiguration public API for prewarming video renderers - Add internal configure method to VideoRendererPool for capacity management - Fix thread safety issue in ReusePool initialization - Eliminates 150-200ms UI hangs when video views are first created --- .../StreamVideoSwiftUI/Utils/ReusePool.swift | 21 +++++++++++--- .../VideoRendererPool/VideoRendererPool.swift | 19 ++++++++++++ .../VideoRendererConfiguration.swift | 29 +++++++++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 Sources/StreamVideoSwiftUI/VideoRendererConfiguration.swift diff --git a/Sources/StreamVideoSwiftUI/Utils/ReusePool.swift b/Sources/StreamVideoSwiftUI/Utils/ReusePool.swift index 24884793c..e6ebb0068 100644 --- a/Sources/StreamVideoSwiftUI/Utils/ReusePool.swift +++ b/Sources/StreamVideoSwiftUI/Utils/ReusePool.swift @@ -30,10 +30,12 @@ final class ReusePool { self.initialCapacity = initialCapacity self.factory = factory - // Initialize the pool with a set number of elements - for _ in 0.. { } } } + + /// Adds a pre-created element to the available pool. + /// Used for prewarming to add elements beyond initial capacity. + /// + /// - Parameter element: The pre-created element to add to the pool. + func addToAvailable(_ element: Element) { + queue.sync { + available.append(element) + log.debug("Added prewarmed \(type(of: element)):\(String(describing: element)) to available pool.") + } + } } diff --git a/Sources/StreamVideoSwiftUI/Utils/VideoRendererPool/VideoRendererPool.swift b/Sources/StreamVideoSwiftUI/Utils/VideoRendererPool/VideoRendererPool.swift index 359e725b2..132d9dcf1 100644 --- a/Sources/StreamVideoSwiftUI/Utils/VideoRendererPool/VideoRendererPool.swift +++ b/Sources/StreamVideoSwiftUI/Utils/VideoRendererPool/VideoRendererPool.swift @@ -47,6 +47,25 @@ final class VideoRendererPool: @unchecked Sendable { func releaseRenderer(_ renderer: VideoRenderer) { pool.release(renderer) } + + /// Configures the global video renderer pool with the specified initial capacity. + /// This method is intended for internal use by StreamVideo. + /// + /// - Parameter initialCapacity: The number of video renderers to pre-create. + @MainActor + static func configure(initialCapacity: Int) async { + // Create pool with 0 initial capacity first + currentValue = VideoRendererPool(initialCapacity: 0) + + // Then add renderers one by one with yielding + for _ in 0..