From 31d1af974089403aa213ec052bae4d16f42c2398 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Tue, 5 Jul 2016 03:40:40 +0900 Subject: [PATCH] graphics: Add NewVolatileImage (#235) --- graphicscontext.go | 6 ++---- image.go | 29 ++++++++++++++++++++++++++++- imageimpl.go | 11 ++++++----- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/graphicscontext.go b/graphicscontext.go index 0204c9101..b258ab863 100644 --- a/graphicscontext.go +++ b/graphicscontext.go @@ -43,20 +43,18 @@ func (c *graphicsContext) SetSize(screenWidth, screenHeight int, screenScale flo if c.offscreen != nil { c.offscreen.Dispose() } - offscreen, err := NewImage(screenWidth, screenHeight, FilterNearest) + offscreen, err := NewVolatileImage(screenWidth, screenHeight, FilterNearest) if err != nil { return err } - offscreen.impl.volatile = true intScreenScale := int(math.Ceil(screenScale)) w := screenWidth * intScreenScale h := screenHeight * intScreenScale - offscreen2, err := NewImage(w, h, FilterLinear) + offscreen2, err := NewVolatileImage(w, h, FilterLinear) if err != nil { return err } - offscreen2.impl.volatile = true w = int(float64(screenWidth) * screenScale) h = int(float64(screenHeight) * screenScale) diff --git a/image.go b/image.go index 4f745ec24..d3d88cece 100644 --- a/image.go +++ b/image.go @@ -194,7 +194,34 @@ type DrawImageOptions struct { // // This function is concurrent-safe. func NewImage(width, height int, filter Filter) (*Image, error) { - img, err := newImageImpl(width, height, filter) + img, err := newImageImpl(width, height, filter, false) + if err != nil { + return nil, err + } + if err := img.Fill(color.Transparent); err != nil { + return nil, err + } + eimg, err := theImagesForRestoring.add(img) + if err != nil { + return nil, err + } + return eimg, nil +} + +// NewVolatileImage returns an empty 'volatile' image. +// A volatile image is an image that pixels might be lost at the next frame. +// +// This is suitable for offscreen images that pixels are changed every frame. +// +// Pixels in regular non-volatile images are saved at each end of a frame if necessary +// and restored automatically on GL context lost. +// On the other hand, pixels in volatile images are not saved and can be lost +// on GL context lost. +// Saving pixels is an expensive operation, and it is desirable to avoid it if possible. +// +// This function is concurrent-safe. +func NewVolatileImage(width, height int, filter Filter) (*Image, error) { + img, err := newImageImpl(width, height, filter, true) if err != nil { return nil, err } diff --git a/imageimpl.go b/imageimpl.go index 03bc89664..98727d12e 100644 --- a/imageimpl.go +++ b/imageimpl.go @@ -41,16 +41,17 @@ type imageImpl struct { m sync.Mutex } -func newImageImpl(width, height int, filter Filter) (*imageImpl, error) { +func newImageImpl(width, height int, filter Filter, volatile bool) (*imageImpl, error) { img, err := graphics.NewImage(width, height, glFilter(filter)) if err != nil { return nil, err } i := &imageImpl{ - image: img, - width: width, - height: height, - filter: filter, + image: img, + width: width, + height: height, + filter: filter, + volatile: volatile, } runtime.SetFinalizer(i, (*imageImpl).Dispose) return i, nil