Following as i'm curious about similar efficiencies. Its not clear in your use case what you know when.
The the sequence
DoFrequently {
KnownDrawsize -> MetalCreateBuffer -> MetalRender -> Set TexttureResource
}
I dont see specifics about the DrawableQueue implementation, but given the lack of specifics about load or update rate, i assume is scales the queue dynamically. (or may adjust according to the timeout property) The behavior seems implicit.
You might be able to do something like
DoFrequently {
KnownDrawsize -> TextureResourceCreate -> DrawableQueueCreate -> getNextDrawable(*blocking) -> MetalRender -> drawablePresent -> Set TexttureResource
}
I guess in both scenarios, the issue is that to create the texture resource, create the drawable queue, replace the DQ onto the TR, all of these are main actor concurrency.
IF the size/descriptor were known in advance, I have thought of creating a pool of textureresource/drawablequeue pairs that were preallocated and ready to use. ShaderGraphMaterial.SetParameter is not @MainActor so can likely be called anytime.
Allocate TR/DQ pool of TextureResource/DrawableQueue
DoFrequently {
if TR/DQ not needed: remove from SGM.Material -> return to TR/DQ pool
if TR/DQ needed get from pool -> set on SGM.Material
foreach TextureUpdate ready to draw
get TR/DQ from pool -> getNextDrawable -> do Metal Render -> drawablePresent -> set on SGM.Material
}
I'd have to double check, i think this avoids blocking mainactor calls on the DoFrquently loop.
This is assuming a number of things with having read the DrawableQueue code.
Food for thought anyway.