internal/graphicscommand: use multiple command queues

This is a preparation for asynchronous rendering.

Updates #2664
This commit is contained in:
Hajime Hoshi 2023-07-30 18:47:45 +09:00
parent 5a64f8299e
commit a7e4665f71
3 changed files with 32 additions and 13 deletions

View File

@ -74,8 +74,23 @@ type commandQueue struct {
uint32sBuffer uint32sBuffer
}
// theCommandQueue is the command queue for the current process.
var theCommandQueue = &commandQueue{}
// theCommandQueues is the set of command queues for the current process.
var (
theCommandQueues = [...]*commandQueue{
{},
{},
}
commandQueueIndex int
)
func currentCommandQueue() *commandQueue {
return theCommandQueues[commandQueueIndex]
}
func switchCommandQueue() {
commandQueueIndex++
commandQueueIndex = commandQueueIndex % len(theCommandQueues)
}
func (q *commandQueue) appendIndices(indices []uint16, offset uint16) {
n := len(q.indices)
@ -263,7 +278,11 @@ func (q *commandQueue) flush(graphicsDriver graphicsdriver.Graphics, endFrame bo
// If endFrame is true, the current screen might be used to present.
func FlushCommands(graphicsDriver graphicsdriver.Graphics, endFrame bool, swapBuffersForGL func()) error {
flushImageBuffers()
return theCommandQueue.Flush(graphicsDriver, endFrame, swapBuffersForGL)
if err := currentCommandQueue().Flush(graphicsDriver, endFrame, swapBuffersForGL); err != nil {
return err
}
switchCommandQueue()
return nil
}
// drawTrianglesCommand represents a drawing command to draw an image on another image.

View File

@ -88,7 +88,7 @@ func NewImage(width, height int, screenFramebuffer bool) *Image {
height: height,
screen: screenFramebuffer,
}
theCommandQueue.Enqueue(c)
currentCommandQueue().Enqueue(c)
return i
}
@ -100,7 +100,7 @@ func (i *Image) flushBufferedWritePixels() {
dst: i,
args: i.bufferedWP,
}
theCommandQueue.Enqueue(c)
currentCommandQueue().Enqueue(c)
i.bufferedWP = nil
}
@ -109,7 +109,7 @@ func (i *Image) Dispose() {
c := &disposeImageCommand{
target: i,
}
theCommandQueue.Enqueue(c)
currentCommandQueue().Enqueue(c)
}
func (i *Image) InternalSize() (int, int) {
@ -158,7 +158,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, offsets [g
}
i.flushBufferedWritePixels()
theCommandQueue.EnqueueDrawTrianglesCommand(i, srcs, offsets, vertices, indices, blend, dstRegion, srcRegion, shader, uniforms, evenOdd)
currentCommandQueue().EnqueueDrawTrianglesCommand(i, srcs, offsets, vertices, indices, blend, dstRegion, srcRegion, shader, uniforms, evenOdd)
}
// ReadPixels reads the image's pixels.
@ -170,8 +170,8 @@ func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, buf []byte, r
region: region,
result: buf,
}
theCommandQueue.Enqueue(c)
if err := theCommandQueue.Flush(graphicsDriver, false, nil); err != nil {
currentCommandQueue().Enqueue(c)
if err := currentCommandQueue().Flush(graphicsDriver, false, nil); err != nil {
return err
}
return nil
@ -200,8 +200,8 @@ func (i *Image) IsInvalidated(graphicsDriver graphicsdriver.Graphics) (bool, err
c := &isInvalidatedCommand{
image: i,
}
theCommandQueue.Enqueue(c)
if err := theCommandQueue.Flush(graphicsDriver, false, nil); err != nil {
currentCommandQueue().Enqueue(c)
if err := currentCommandQueue().Flush(graphicsDriver, false, nil); err != nil {
return false, err
}
return c.result, nil

View File

@ -32,7 +32,7 @@ func NewShader(ir *shaderir.Program) *Shader {
result: s,
ir: ir,
}
theCommandQueue.Enqueue(c)
currentCommandQueue().Enqueue(c)
return s
}
@ -40,7 +40,7 @@ func (s *Shader) Dispose() {
c := &disposeShaderCommand{
target: s,
}
theCommandQueue.Enqueue(c)
currentCommandQueue().Enqueue(c)
}
func (s *Shader) unit() shaderir.Unit {