diff --git a/gameforui.go b/gameforui.go index e496e7843..d86e4fda8 100644 --- a/gameforui.go +++ b/gameforui.go @@ -66,6 +66,10 @@ func (g *gameForUI) NewOffscreenImage(width, height int) *ui.Image { // An image on an atlas is surrounded by a transparent edge, // and the shader program unexpectedly picks the pixel on the edges. imageType := atlas.ImageTypeUnmanaged + if ui.Get().IsScreenClearedEveryFrame() { + // A volatile image is also always isolated. + imageType = atlas.ImageTypeVolatile + } g.offscreen = newImage(image.Rect(0, 0, width, height), imageType) return g.offscreen.image } diff --git a/internal/atlas/image.go b/internal/atlas/image.go index ff6d8d75f..980d24100 100644 --- a/internal/atlas/image.go +++ b/internal/atlas/image.go @@ -224,6 +224,8 @@ const ( // A screen image is also unmanaged. ImageTypeScreen + ImageTypeVolatile + // ImageTypeUnmanaged is an unmanaged image that is not on an atlas. ImageTypeUnmanaged ) diff --git a/internal/atlas/image_test.go b/internal/atlas/image_test.go index 3c5c351ab..1a7d1d300 100644 --- a/internal/atlas/image_test.go +++ b/internal/atlas/image_test.go @@ -174,8 +174,8 @@ func TestReputOnSourceBackend(t *testing.T) { } img2.WritePixels(pix, image.Rect(0, 0, size, size)) - // Create an unmanaged image. This should always be on a non-source backend. - img3 := atlas.NewImage(size, size, atlas.ImageTypeUnmanaged) + // Create a volatile image. This should always be on a non-source backend. + img3 := atlas.NewImage(size, size, atlas.ImageTypeVolatile) defer img3.Deallocate() img3.WritePixels(make([]byte, 4*size*size), image.Rect(0, 0, size, size)) if got, want := img3.IsOnSourceBackendForTesting(), false; got != want { @@ -685,7 +685,7 @@ func TestImageIsNotReputOnSourceBackendWithoutUsingAsSource(t *testing.T) { } func TestImageWritePixelsModify(t *testing.T) { - for _, typ := range []atlas.ImageType{atlas.ImageTypeRegular, atlas.ImageTypeRegular, atlas.ImageTypeUnmanaged} { + for _, typ := range []atlas.ImageType{atlas.ImageTypeRegular, atlas.ImageTypeVolatile, atlas.ImageTypeUnmanaged} { const size = 16 img := atlas.NewImage(size, size, typ) defer img.Deallocate() diff --git a/internal/ui/context.go b/internal/ui/context.go index 7f94b2d5d..c1af72c37 100644 --- a/internal/ui/context.go +++ b/internal/ui/context.go @@ -180,6 +180,12 @@ func (c *context) newOffscreenImage(w, h int) *Image { } func (c *context) drawGame(graphicsDriver graphicsdriver.Graphics, ui *UserInterface, forceDraw bool) error { + if (c.offscreen.imageType == atlas.ImageTypeVolatile) != ui.IsScreenClearedEveryFrame() { + w, h := c.offscreen.width, c.offscreen.height + c.offscreen.Deallocate() + c.offscreen = c.newOffscreenImage(w, h) + } + // isOffscreenModified is updated when an offscreen's modifyCallback. c.isOffscreenModified = false diff --git a/internal/ui/image.go b/internal/ui/image.go index 987d0bcc3..2b56f0e0f 100644 --- a/internal/ui/image.go +++ b/internal/ui/image.go @@ -15,6 +15,7 @@ package ui import ( + "fmt" "image" "math" @@ -85,7 +86,16 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderSrcImageCount]*Image, vertice if antialias { if i.bigOffscreenBuffer == nil { - i.bigOffscreenBuffer = i.ui.newBigOffscreenImage(i, atlas.ImageTypeUnmanaged) + var imageType atlas.ImageType + switch i.imageType { + case atlas.ImageTypeRegular, atlas.ImageTypeUnmanaged: + imageType = atlas.ImageTypeUnmanaged + case atlas.ImageTypeScreen, atlas.ImageTypeVolatile: + imageType = atlas.ImageTypeVolatile + default: + panic(fmt.Sprintf("ui: unexpected image type: %d", imageType)) + } + i.bigOffscreenBuffer = i.ui.newBigOffscreenImage(i, imageType) } i.bigOffscreenBuffer.drawTriangles(srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule, canSkipMipmap)