From c7783b2ecff16190d87d0a3504a2fd37c82d6249 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Wed, 6 Jul 2016 01:30:49 +0900 Subject: [PATCH] graphics: Clear volatile images at the start of a frame --- graphicscontext.go | 3 ++- image.go | 16 +++++++++++++--- imageimpl.go | 13 +++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/graphicscontext.go b/graphicscontext.go index b258ab863..bd5c6efff 100644 --- a/graphicscontext.go +++ b/graphicscontext.go @@ -128,7 +128,8 @@ func (c *graphicsContext) UpdateAndDraw(context *opengl.Context, updateCount int return err } for i := 0; i < updateCount; i++ { - if err := c.offscreen.Clear(); err != nil { + // TODO: This clears images not needed to be cleared (e.g. c.screen). + if err := theImagesForRestoring.clearVolatileImages(); err != nil { return err } setRunningSlowly(i < updateCount-1) diff --git a/image.go b/image.go index cc415de82..c8bea2cc0 100644 --- a/image.go +++ b/image.go @@ -81,6 +81,17 @@ func (i *images) restore(context *opengl.Context) error { return nil } +func (i *images) clearVolatileImages() error { + i.m.Lock() + defer i.m.Unlock() + for img := range i.images { + if err := img.clearIfVolatile(); err != nil { + return err + } + } + return nil +} + // Image represents an image. // The pixel format is alpha-premultiplied. // Image implements image.Image. @@ -209,14 +220,13 @@ func NewImage(width, height int, filter Filter) (*Image, error) { } // NewVolatileImage returns an empty 'volatile' image. -// A volatile image is an image that pixels might be lost at another frame. +// A volatile image is always cleared at the start of a frame. // // This is suitable for offscreen images that pixels are changed often. // // Pixels in regular non-volatile images are saved at each end of a frame if the image // is changed, and restored automatically from the saved pixels on GL context lost. -// On the other hand, pixels in volatile images are not saved and can be lost -// on GL context lost. +// On the other hand, pixels in volatile images are not saved. // Saving pixels is an expensive operation, and it is desirable to avoid it if possible. // // This function is concurrent-safe. diff --git a/imageimpl.go b/imageimpl.go index 98727d12e..d493004eb 100644 --- a/imageimpl.go +++ b/imageimpl.go @@ -115,6 +115,19 @@ func (i *imageImpl) Fill(clr color.Color) error { return i.image.Fill(clr) } +func (i *imageImpl) clearIfVolatile() error { + i.m.Lock() + defer i.m.Unlock() + if i.disposed { + return nil + } + if !i.volatile { + return nil + } + i.pixels = nil + return i.image.Fill(color.Transparent) +} + func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error { // Calculate vertices before locking because the user can do anything in // options.ImageParts interface without deadlock (e.g. Call Image functions).