internal/graphicscommand: bug fix: suppress test flakiness on browsers

Closes #2391
This commit is contained in:
Hajime Hoshi 2022-10-16 17:55:21 +09:00
parent 4b22781d01
commit 89471701fc
6 changed files with 31 additions and 26 deletions

View File

@ -743,7 +743,7 @@ func (i *Image) DumpScreenshot(graphicsDriver graphicsdriver.Graphics, path stri
func EndFrame(graphicsDriver graphicsdriver.Graphics) error {
backendsM.Lock()
if err := restorable.ResolveStaleImages(graphicsDriver); err != nil {
if err := restorable.ResolveStaleImages(graphicsDriver, true); err != nil {
return err
}

View File

@ -271,9 +271,14 @@ func (q *commandQueue) flush(graphicsDriver graphicsdriver.Graphics) error {
return nil
}
// FlushCommands flushes the command queue.
func FlushCommands(graphicsDriver graphicsdriver.Graphics) error {
resolveImages()
// FlushCommands flushes the command queue and present the screen if needed.
func FlushCommands(graphicsDriver graphicsdriver.Graphics, endFrame bool) error {
// Resolve unresolved images only when the frame ends.
// Resolving in tests might cause test flakiness on browsers (#2391).
// TODO: Investigate why.
if endFrame {
resolveImages()
}
return theCommandQueue.Flush(graphicsDriver)
}

View File

@ -439,7 +439,7 @@ func (i *Image) appendDrawTrianglesHistory(srcs [graphics.ShaderImageCount]*Imag
func (i *Image) readPixelsFromGPUIfNeeded(graphicsDriver graphicsdriver.Graphics) error {
if len(i.drawTrianglesHistory) > 0 || i.stale {
if err := graphicscommand.FlushCommands(graphicsDriver); err != nil {
if err := graphicscommand.FlushCommands(graphicsDriver, false); err != nil {
return err
}
if err := i.readPixelsFromGPU(graphicsDriver); err != nil {
@ -638,7 +638,7 @@ func (i *Image) Dispose() {
// If an image is invalidated, GL context is lost and all the images should be restored asap.
func (i *Image) isInvalidated(graphicsDriver graphicsdriver.Graphics) (bool, error) {
// FlushCommands is required because c.offscreen.impl might not have an actual texture.
if err := graphicscommand.FlushCommands(graphicsDriver); err != nil {
if err := graphicscommand.FlushCommands(graphicsDriver, false); err != nil {
return false, err
}
return i.image.IsInvalidated(), nil

View File

@ -57,7 +57,7 @@ var theImages = &images{
// all stale images.
//
// ResolveStaleImages is intended to be called at the end of a frame.
func ResolveStaleImages(graphicsDriver graphicsdriver.Graphics) error {
func ResolveStaleImages(graphicsDriver graphicsdriver.Graphics, endFrame bool) error {
if debug.IsDebug {
debug.Logf("Internal image sizes:\n")
imgs := make([]*graphicscommand.Image, 0, len(theImages.images))
@ -67,7 +67,7 @@ func ResolveStaleImages(graphicsDriver graphicsdriver.Graphics) error {
graphicscommand.LogImagesInfo(imgs)
}
if err := graphicscommand.FlushCommands(graphicsDriver); err != nil {
if err := graphicscommand.FlushCommands(graphicsDriver, endFrame); err != nil {
return err
}
if !needsRestoring() {

View File

@ -63,7 +63,7 @@ func TestRestore(t *testing.T) {
clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff}
img0.WritePixels([]byte{clr0.R, clr0.G, clr0.B, clr0.A}, 0, 0, 1, 1)
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -82,7 +82,7 @@ func TestRestoreWithoutDraw(t *testing.T) {
// If there is no drawing command on img0, img0 is cleared when restored.
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -148,7 +148,7 @@ func TestRestoreChain(t *testing.T) {
}
imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, [graphics.ShaderImageCount - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
}
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -200,7 +200,7 @@ func TestRestoreChain2(t *testing.T) {
imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, [graphics.ShaderImageCount - 1][2]float32{}, quadVertices(imgs[i], w, h, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
}
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -247,7 +247,7 @@ func TestRestoreOverrideSource(t *testing.T) {
img3.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, [graphics.ShaderImageCount - 1][2]float32{}, quadVertices(img2, w, h, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
img0.WritePixels([]byte{clr1.R, clr1.G, clr1.B, clr1.A}, 0, 0, w, h)
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, [graphics.ShaderImageCount - 1][2]float32{}, quadVertices(img0, w, h, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -349,7 +349,7 @@ func TestRestoreComplexGraph(t *testing.T) {
img7.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, offsets, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
vs = quadVertices(img3, w, h, 2, 0)
img7.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img3}, offsets, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -448,7 +448,7 @@ func TestRestoreRecursive(t *testing.T) {
}
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, [graphics.ShaderImageCount - 1][2]float32{}, quadVertices(img0, w, h, 1, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
img0.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, [graphics.ShaderImageCount - 1][2]float32{}, quadVertices(img1, w, h, 1, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -510,7 +510,7 @@ func TestWritePixels(t *testing.T) {
}
}
}
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -553,7 +553,7 @@ func TestDrawTrianglesAndWritePixels(t *testing.T) {
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, [graphics.ShaderImageCount - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
img1.WritePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, 0, 2, 1)
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -597,7 +597,7 @@ func TestDispose(t *testing.T) {
img0.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, [graphics.ShaderImageCount - 1][2]float32{}, quadVertices(img1, 1, 1, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
img1.Dispose()
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -729,7 +729,7 @@ func TestWritePixelsOnly(t *testing.T) {
}
}
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -900,7 +900,7 @@ func TestMutateSlices(t *testing.T) {
for i := range is {
is[i] = 0
}
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -1052,7 +1052,7 @@ func TestOverlappedPixels(t *testing.T) {
}
}
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {

View File

@ -67,7 +67,7 @@ func TestShader(t *testing.T) {
}
img.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{}, [graphics.ShaderImageCount - 1][2]float32{}, quadVertices(nil, 1, 1, 0, 0), graphics.QuadIndices(), nil, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, s, nil, false)
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -103,7 +103,7 @@ func TestShaderChain(t *testing.T) {
imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, [graphics.ShaderImageCount - 1][2]float32{}, quadVertices(imgs[i], 1, 1, 0, 0), graphics.QuadIndices(), nil, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, s, nil, false)
}
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -143,7 +143,7 @@ func TestShaderMultipleSources(t *testing.T) {
// Clear one of the sources after DrawTriangles. dst should not be affected.
clearImage(srcs[0], 1, 1)
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -184,7 +184,7 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) {
// Clear one of the sources after DrawTriangles. dst should not be affected.
clearImage(srcs[0], 3, 1)
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
@ -215,7 +215,7 @@ func TestShaderDispose(t *testing.T) {
// stale.
s.Dispose()
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
t.Fatal(err)
}
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {