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()