graphics: Add newImageImplFromImage; Rename theImages -> theImagesForRestoring

This commit is contained in:
Hajime Hoshi 2016-07-05 01:34:40 +09:00
parent eac816ca47
commit 760e1aa288
3 changed files with 40 additions and 26 deletions

View File

@ -151,7 +151,7 @@ func (c *graphicsContext) UpdateAndDraw(context *opengl.Context, updateCount int
return err
}
if 0 < updateCount {
if err := theImages.savePixels(context); err != nil {
if err := theImagesForRestoring.savePixels(context); err != nil {
return err
}
}
@ -162,7 +162,7 @@ func (c *graphicsContext) restore(context *opengl.Context) error {
if err := graphics.Reset(context); err != nil {
return err
}
if err := theImages.restorePixels(context); err != nil {
if err := theImagesForRestoring.restorePixels(context); err != nil {
return err
}
return nil

View File

@ -17,7 +17,6 @@ package ebiten
import (
"image"
"image/color"
"image/draw"
"runtime"
"sync"
@ -30,7 +29,7 @@ type images struct {
m sync.Mutex
}
var theImages = images{
var theImagesForRestoring = images{
images: map[*imageImpl]struct{}{},
}
@ -39,7 +38,7 @@ func (i *images) add(img *imageImpl) (*Image, error) {
defer i.m.Unlock()
i.images[img] = struct{}{}
eimg := &Image{img}
runtime.SetFinalizer(eimg, theImages.remove)
runtime.SetFinalizer(eimg, theImagesForRestoring.remove)
return eimg, nil
}
@ -206,7 +205,7 @@ func NewImage(width, height int, filter Filter) (*Image, error) {
if err := img.Fill(color.Transparent); err != nil {
return nil, err
}
eimg, err := theImages.add(img)
eimg, err := theImagesForRestoring.add(img)
if err != nil {
return nil, err
}
@ -219,29 +218,11 @@ func NewImage(width, height int, filter Filter) (*Image, error) {
//
// This function is concurrent-safe.
func NewImageFromImage(source image.Image, filter Filter) (*Image, error) {
size := source.Bounds().Size()
w, h := size.X, size.Y
// TODO: Return error when the image is too big!
// Don't lock while manipulating an image.Image interface.
rgbaImg, ok := source.(*image.RGBA)
if !ok || source.Bounds().Min != image.ZP {
origImg := source
newImg := image.NewRGBA(image.Rect(0, 0, w, h))
draw.Draw(newImg, newImg.Bounds(), origImg, origImg.Bounds().Min, draw.Src)
rgbaImg = newImg
}
pixels := make([]uint8, 4*w*h)
for j := 0; j < h; j++ {
copy(pixels[j*w*4:(j+1)*w*4], rgbaImg.Pix[j*rgbaImg.Stride:])
}
i, err := graphics.NewImageFromImage(rgbaImg, glFilter(filter))
img, err := newImageImplFromImage(source, filter)
if err != nil {
// TODO: texture should be removed here?
return nil, err
}
img, err := newImageImpl(i, filter)
img.pixels = pixels
eimg, err := theImages.add(img)
eimg, err := theImagesForRestoring.add(img)
if err != nil {
return nil, err
}

View File

@ -19,6 +19,7 @@ import (
"fmt"
"image"
"image/color"
"image/draw"
"runtime"
"sync"
@ -51,6 +52,38 @@ func newImageImpl(image *graphics.Image, filter Filter) (*imageImpl, error) {
return i, nil
}
func newImageImplFromImage(source image.Image, filter Filter) (*imageImpl, error) {
size := source.Bounds().Size()
w, h := size.X, size.Y
// TODO: Return error when the image is too big!
// Don't lock while manipulating an image.Image interface.
rgbaImg, ok := source.(*image.RGBA)
if !ok || source.Bounds().Min != image.ZP {
origImg := source
newImg := image.NewRGBA(image.Rect(0, 0, w, h))
draw.Draw(newImg, newImg.Bounds(), origImg, origImg.Bounds().Min, draw.Src)
rgbaImg = newImg
}
pixels := make([]uint8, 4*w*h)
for j := 0; j < h; j++ {
copy(pixels[j*w*4:(j+1)*w*4], rgbaImg.Pix[j*rgbaImg.Stride:])
}
img, err := graphics.NewImageFromImage(rgbaImg, glFilter(filter))
if err != nil {
// TODO: texture should be removed here?
return nil, err
}
i := &imageImpl{
image: img,
width: w,
height: h,
filter: filter,
pixels: pixels,
}
runtime.SetFinalizer(i, (*imageImpl).Dispose)
return i, nil
}
func (i *imageImpl) Fill(clr color.Color) error {
i.m.Lock()
defer i.m.Unlock()