From 0f8233000910c0ed76963a5509f2637b711c275b Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 29 Jul 2018 23:54:46 +0900 Subject: [PATCH] graphics: Bug fix: mipmap images should be volatile when the base image is volatile --- image.go | 9 ++++++++- internal/restorable/image.go | 4 ++++ internal/shareable/shareable.go | 10 ++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/image.go b/image.go index 5981efe73..e5d0047ec 100644 --- a/image.go +++ b/image.go @@ -45,6 +45,8 @@ type Image struct { // See strings.Builder for similar examples. addr *Image + // shareableImages is a set of shareable.Image sorted by the order of mipmap level. + // The level 0 image is a regular image and higher-level images are used for mipmap. shareableImages []*shareable.Image filter Filter @@ -282,7 +284,12 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error { if w2 == 0 || h2 == 0 { break } - s := shareable.NewImage(w2, h2) + var s *shareable.Image + if img.shareableImages[0].IsVolatile() { + s = shareable.NewVolatileImage(w2, h2) + } else { + s = shareable.NewImage(w2, h2) + } vs := src.QuadVertices(0, 0, w, h, 0.5, 0, 0, 0.5, 0, 0, nil) is := graphicsutil.QuadIndices() s.DrawImage(src, vs, is, opengl.CompositeModeCopy, graphics.FilterLinear) diff --git a/internal/restorable/image.go b/internal/restorable/image.go index a2625dd28..917b1a519 100644 --- a/internal/restorable/image.go +++ b/internal/restorable/image.go @@ -99,6 +99,10 @@ func NewScreenFramebufferImage(width, height int) *Image { return i } +func (i *Image) IsVolatile() bool { + return i.volatile +} + // BasePixelsForTesting returns the image's basePixels for testing. func (i *Image) BasePixelsForTesting() []byte { return i.basePixels diff --git a/internal/shareable/shareable.go b/internal/shareable/shareable.go index 8e8ba13b2..21788106a 100644 --- a/internal/shareable/shareable.go +++ b/internal/shareable/shareable.go @@ -323,6 +323,16 @@ func (i *Image) dispose(markDisposed bool) { theBackends = append(theBackends[:index], theBackends[index+1:]...) } +func (i *Image) IsVolatile() bool { + backendsM.Lock() + defer backendsM.Unlock() + if i.backend == nil { + // Not allocated yet. Only non-volatile images can do lazy allocation so far. + return false + } + return i.backend.restorable.IsVolatile() +} + func (i *Image) IsInvalidated() (bool, error) { backendsM.Lock() defer backendsM.Unlock()