mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
graphics: Avoid copying images twice
This commit is contained in:
parent
260b938422
commit
5c403d9969
@ -84,7 +84,7 @@ func TestImagePixels(t *testing.T) {
|
||||
}
|
||||
|
||||
if got := img0.Bounds().Size(); got != img.Bounds().Size() {
|
||||
t.Errorf("img size: got %d; want %d", got, img.Bounds().Size())
|
||||
t.Fatalf("img size: got %d; want %d", got, img.Bounds().Size())
|
||||
}
|
||||
|
||||
for j := 0; j < img0.Bounds().Size().Y; j++ {
|
||||
|
@ -81,7 +81,7 @@ func newImageImplFromImage(source image.Image, filter Filter) (*imageImpl, error
|
||||
for j := 0; j < h; j++ {
|
||||
copy(p[j*w*4:(j+1)*w*4], rgbaImg.Pix[j*rgbaImg.Stride:])
|
||||
}
|
||||
img, err := restorable.NewImageFromImage(rgbaImg, glFilter(filter))
|
||||
img, err := restorable.NewImageFromImage(rgbaImg, w, h, glFilter(filter))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -180,9 +180,7 @@ func (i *imageImpl) At(x, y int, context *opengl.Context) color.Color {
|
||||
if i.restorable == nil {
|
||||
return color.Transparent
|
||||
}
|
||||
w, _ := i.restorable.Size()
|
||||
idx := 4*x + 4*y*w
|
||||
clr, err := i.restorable.At(idx, context)
|
||||
clr, err := i.restorable.At(x, y, context)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/draw"
|
||||
"math"
|
||||
"sync"
|
||||
|
||||
@ -287,28 +286,6 @@ type newImageFromImageCommand struct {
|
||||
filter opengl.Filter
|
||||
}
|
||||
|
||||
func adjustImageForTexture(img *image.RGBA) *image.RGBA {
|
||||
width, height := img.Bounds().Size().X, img.Bounds().Size().Y
|
||||
adjustedImageBounds := image.Rectangle{
|
||||
image.ZP,
|
||||
image.Point{
|
||||
NextPowerOf2Int(width),
|
||||
NextPowerOf2Int(height),
|
||||
},
|
||||
}
|
||||
if img.Bounds() == adjustedImageBounds {
|
||||
return img
|
||||
}
|
||||
|
||||
adjustedImage := image.NewRGBA(adjustedImageBounds)
|
||||
dstBounds := image.Rectangle{
|
||||
image.ZP,
|
||||
img.Bounds().Size(),
|
||||
}
|
||||
draw.Draw(adjustedImage, dstBounds, img, img.Bounds().Min, draw.Src)
|
||||
return adjustedImage
|
||||
}
|
||||
|
||||
func (c *newImageFromImageCommand) Exec(context *opengl.Context, indexOffsetInBytes int) error {
|
||||
origSize := c.img.Bounds().Size()
|
||||
if origSize.X < 1 {
|
||||
@ -317,9 +294,11 @@ func (c *newImageFromImageCommand) Exec(context *opengl.Context, indexOffsetInBy
|
||||
if origSize.Y < 1 {
|
||||
return errors.New("graphics: height must be equal or more than 1.")
|
||||
}
|
||||
adjustedImage := adjustImageForTexture(c.img)
|
||||
size := adjustedImage.Bounds().Size()
|
||||
native, err := context.NewTexture(size.X, size.Y, adjustedImage.Pix, c.filter)
|
||||
w, h := c.img.Bounds().Size().X, c.img.Bounds().Size().Y
|
||||
if c.img.Bounds() != image.Rect(0, 0, NextPowerOf2Int(w), NextPowerOf2Int(h)) {
|
||||
panic(fmt.Sprintf("graphics: invalid image bounds: %v", c.img.Bounds()))
|
||||
}
|
||||
native, err := context.NewTexture(w, h, c.img.Pix, c.filter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ import (
|
||||
func CopyImage(origImg image.Image) *image.RGBA {
|
||||
size := origImg.Bounds().Size()
|
||||
w, h := size.X, size.Y
|
||||
newImg := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||
newImg := image.NewRGBA(image.Rect(0, 0, NextPowerOf2Int(w), NextPowerOf2Int(h)))
|
||||
switch origImg := origImg.(type) {
|
||||
case *image.Paletted:
|
||||
b := origImg.Bounds()
|
||||
@ -63,7 +63,7 @@ func CopyImage(origImg image.Image) *image.RGBA {
|
||||
index1 += d1
|
||||
}
|
||||
default:
|
||||
draw.Draw(newImg, newImg.Bounds(), origImg, origImg.Bounds().Min, draw.Src)
|
||||
draw.Draw(newImg, image.Rect(0, 0, w, h), origImg, origImg.Bounds().Min, draw.Src)
|
||||
}
|
||||
runtime.Gosched()
|
||||
return newImg
|
||||
@ -93,11 +93,10 @@ func NewImage(width, height int, filter opengl.Filter) (*Image, error) {
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func NewImageFromImage(img *image.RGBA, filter opengl.Filter) (*Image, error) {
|
||||
s := img.Bounds().Size()
|
||||
func NewImageFromImage(img *image.RGBA, width, height int, filter opengl.Filter) (*Image, error) {
|
||||
i := &Image{
|
||||
width: s.X,
|
||||
height: s.Y,
|
||||
width: width,
|
||||
height: height,
|
||||
}
|
||||
c := &newImageFromImageCommand{
|
||||
result: i,
|
||||
|
@ -62,14 +62,12 @@ func NewImage(width, height int, filter opengl.Filter, volatile bool) (*Image, e
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewImageFromImage(source *image.RGBA, filter opengl.Filter) (*Image, error) {
|
||||
img, err := graphics.NewImageFromImage(source, filter)
|
||||
func NewImageFromImage(source *image.RGBA, width, height int, filter opengl.Filter) (*Image, error) {
|
||||
img, err := graphics.NewImageFromImage(source, width, height, filter)
|
||||
if err != nil {
|
||||
// TODO: texture should be removed here?
|
||||
return nil, err
|
||||
}
|
||||
size := source.Bounds().Size()
|
||||
width, height := size.X, size.Y
|
||||
return &Image{
|
||||
image: img,
|
||||
width: width,
|
||||
@ -172,11 +170,12 @@ func (p *Image) appendDrawImageHistory(image *graphics.Image, vertices []float32
|
||||
p.drawImageHistory = append(p.drawImageHistory, item)
|
||||
}
|
||||
|
||||
// At returns a color value at idx.
|
||||
// At returns a color value at (x, y).
|
||||
//
|
||||
// Note that this must not be called until context is available.
|
||||
// This means Pixels members must match with acutal state in VRAM.
|
||||
func (p *Image) At(idx int, context *opengl.Context) (color.RGBA, error) {
|
||||
func (p *Image) At(x, y int, context *opengl.Context) (color.RGBA, error) {
|
||||
idx := 4*x + 4*y*p.width
|
||||
if p.basePixels == nil || p.drawImageHistory != nil || p.stale {
|
||||
if err := p.readPixelsFromVRAM(p.image, context); err != nil {
|
||||
return color.RGBA{}, err
|
||||
@ -260,13 +259,13 @@ func (p *Image) Restore(context *opengl.Context) error {
|
||||
if p.stale {
|
||||
return errors.New("restorable: pixels must not be stale when restoring")
|
||||
}
|
||||
img := image.NewRGBA(image.Rect(0, 0, p.width, p.height))
|
||||
img := image.NewRGBA(image.Rect(0, 0, graphics.NextPowerOf2Int(p.width), graphics.NextPowerOf2Int(p.height)))
|
||||
if p.basePixels != nil {
|
||||
for j := 0; j < p.height; j++ {
|
||||
copy(img.Pix[j*img.Stride:], p.basePixels[j*p.width*4:(j+1)*p.width*4])
|
||||
}
|
||||
}
|
||||
gimg, err := graphics.NewImageFromImage(img, p.filter)
|
||||
gimg, err := graphics.NewImageFromImage(img, p.width, p.height, p.filter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user