diff --git a/internal/restorable/image.go b/internal/restorable/image.go index 3b9f02630..960890009 100644 --- a/internal/restorable/image.go +++ b/internal/restorable/image.go @@ -384,7 +384,6 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16, if (img != nil && (img.stale || img.volatile)) || i.screen || !needsRestoring() || i.volatile { i.makeStale() } else { - // TODO: Need to copy uniform variables? i.appendDrawTrianglesHistory(img, vertices, indices, colorm, mode, filter, address, shader, uniforms) } var s *graphicscommand.Shader @@ -502,7 +501,7 @@ func (i *Image) resolveStale() error { return i.readPixelsFromGPU() } -// dependsOn returns a boolean value indicating whether the image depends on target. +// dependsOn reports whether the image depends on target. func (i *Image) dependsOn(target *Image) bool { for _, c := range i.drawTrianglesHistory { if c.image == target { diff --git a/internal/restorable/images.go b/internal/restorable/images.go index c56dfa1fa..26e770d0b 100644 --- a/internal/restorable/images.go +++ b/internal/restorable/images.go @@ -150,10 +150,9 @@ func (i *images) resolveStaleImages() error { // makeStaleIfDependingOn makes all the images stale that depend on target. // -// When target is changed, all images depending on target can't be restored with target. +// When target is modified, all images depending on target can't be restored with target. // makeStaleIfDependingOn is called in such situation. func (i *images) makeStaleIfDependingOn(target *Image) { - // Avoid defer for performance i.makeStaleIfDependingOnImpl(target) } diff --git a/internal/restorable/shader_test.go b/internal/restorable/shader_test.go index d1adaea49..24dd41a68 100644 --- a/internal/restorable/shader_test.go +++ b/internal/restorable/shader_test.go @@ -94,3 +94,45 @@ func TestShaderChain(t *testing.T) { } } } + +func TestShaderMultipleSources(t *testing.T) { + if !graphicscommand.IsShaderAvailable() { + t.Skip("shader is not available on this environment") + } + + srcs := make([]*Image, 3) + for i := range srcs { + srcs[i] = NewImage(1, 1, false) + } + srcs[0].ReplacePixels([]byte{0x40, 0, 0, 0xff}, 0, 0, 1, 1) + srcs[1].ReplacePixels([]byte{0, 0x80, 0, 0xff}, 0, 0, 1, 1) + srcs[2].ReplacePixels([]byte{0, 0, 0xc0, 0xff}, 0, 0, 1, 1) + + dst := NewImage(1, 1, false) + + ir := etesting.ShaderProgramImages(3) + s := NewShader(&ir) + us := map[int]interface{}{ + 0: []float32{1, 1}, + 1: srcs[0], + 2: srcs[1], + 5: srcs[2], + } + dst.DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, s, us) + + // Clear one of the sources after DrawTriangles. dst should not be affected. + srcs[0].Fill(color.RGBA{}) + + if err := ResolveStaleImages(); err != nil { + t.Fatal(err) + } + if err := RestoreIfNeeded(); err != nil { + t.Fatal(err) + } + + want := color.RGBA{0x40, 0x80, 0xc0, 0xff} + got := pixelsToColor(dst.BasePixelsForTesting(), 0, 0) + if !sameColors(got, want, 1) { + t.Errorf("got %v, want %v", got, want) + } +}