mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +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() {
|
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++ {
|
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++ {
|
for j := 0; j < h; j++ {
|
||||||
copy(p[j*w*4:(j+1)*w*4], rgbaImg.Pix[j*rgbaImg.Stride:])
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -180,9 +180,7 @@ func (i *imageImpl) At(x, y int, context *opengl.Context) color.Color {
|
|||||||
if i.restorable == nil {
|
if i.restorable == nil {
|
||||||
return color.Transparent
|
return color.Transparent
|
||||||
}
|
}
|
||||||
w, _ := i.restorable.Size()
|
clr, err := i.restorable.At(x, y, context)
|
||||||
idx := 4*x + 4*y*w
|
|
||||||
clr, err := i.restorable.At(idx, context)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"image/draw"
|
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -287,28 +286,6 @@ type newImageFromImageCommand struct {
|
|||||||
filter opengl.Filter
|
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 {
|
func (c *newImageFromImageCommand) Exec(context *opengl.Context, indexOffsetInBytes int) error {
|
||||||
origSize := c.img.Bounds().Size()
|
origSize := c.img.Bounds().Size()
|
||||||
if origSize.X < 1 {
|
if origSize.X < 1 {
|
||||||
@ -317,9 +294,11 @@ func (c *newImageFromImageCommand) Exec(context *opengl.Context, indexOffsetInBy
|
|||||||
if origSize.Y < 1 {
|
if origSize.Y < 1 {
|
||||||
return errors.New("graphics: height must be equal or more than 1.")
|
return errors.New("graphics: height must be equal or more than 1.")
|
||||||
}
|
}
|
||||||
adjustedImage := adjustImageForTexture(c.img)
|
w, h := c.img.Bounds().Size().X, c.img.Bounds().Size().Y
|
||||||
size := adjustedImage.Bounds().Size()
|
if c.img.Bounds() != image.Rect(0, 0, NextPowerOf2Int(w), NextPowerOf2Int(h)) {
|
||||||
native, err := context.NewTexture(size.X, size.Y, adjustedImage.Pix, c.filter)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
func CopyImage(origImg image.Image) *image.RGBA {
|
func CopyImage(origImg image.Image) *image.RGBA {
|
||||||
size := origImg.Bounds().Size()
|
size := origImg.Bounds().Size()
|
||||||
w, h := size.X, size.Y
|
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) {
|
switch origImg := origImg.(type) {
|
||||||
case *image.Paletted:
|
case *image.Paletted:
|
||||||
b := origImg.Bounds()
|
b := origImg.Bounds()
|
||||||
@ -63,7 +63,7 @@ func CopyImage(origImg image.Image) *image.RGBA {
|
|||||||
index1 += d1
|
index1 += d1
|
||||||
}
|
}
|
||||||
default:
|
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()
|
runtime.Gosched()
|
||||||
return newImg
|
return newImg
|
||||||
@ -93,11 +93,10 @@ func NewImage(width, height int, filter opengl.Filter) (*Image, error) {
|
|||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImageFromImage(img *image.RGBA, filter opengl.Filter) (*Image, error) {
|
func NewImageFromImage(img *image.RGBA, width, height int, filter opengl.Filter) (*Image, error) {
|
||||||
s := img.Bounds().Size()
|
|
||||||
i := &Image{
|
i := &Image{
|
||||||
width: s.X,
|
width: width,
|
||||||
height: s.Y,
|
height: height,
|
||||||
}
|
}
|
||||||
c := &newImageFromImageCommand{
|
c := &newImageFromImageCommand{
|
||||||
result: i,
|
result: i,
|
||||||
|
@ -62,14 +62,12 @@ func NewImage(width, height int, filter opengl.Filter, volatile bool) (*Image, e
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImageFromImage(source *image.RGBA, filter opengl.Filter) (*Image, error) {
|
func NewImageFromImage(source *image.RGBA, width, height int, filter opengl.Filter) (*Image, error) {
|
||||||
img, err := graphics.NewImageFromImage(source, filter)
|
img, err := graphics.NewImageFromImage(source, width, height, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: texture should be removed here?
|
// TODO: texture should be removed here?
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
size := source.Bounds().Size()
|
|
||||||
width, height := size.X, size.Y
|
|
||||||
return &Image{
|
return &Image{
|
||||||
image: img,
|
image: img,
|
||||||
width: width,
|
width: width,
|
||||||
@ -172,11 +170,12 @@ func (p *Image) appendDrawImageHistory(image *graphics.Image, vertices []float32
|
|||||||
p.drawImageHistory = append(p.drawImageHistory, item)
|
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.
|
// Note that this must not be called until context is available.
|
||||||
// This means Pixels members must match with acutal state in VRAM.
|
// 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 p.basePixels == nil || p.drawImageHistory != nil || p.stale {
|
||||||
if err := p.readPixelsFromVRAM(p.image, context); err != nil {
|
if err := p.readPixelsFromVRAM(p.image, context); err != nil {
|
||||||
return color.RGBA{}, err
|
return color.RGBA{}, err
|
||||||
@ -260,13 +259,13 @@ func (p *Image) Restore(context *opengl.Context) error {
|
|||||||
if p.stale {
|
if p.stale {
|
||||||
return errors.New("restorable: pixels must not be stale when restoring")
|
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 {
|
if p.basePixels != nil {
|
||||||
for j := 0; j < p.height; j++ {
|
for j := 0; j < p.height; j++ {
|
||||||
copy(img.Pix[j*img.Stride:], p.basePixels[j*p.width*4:(j+1)*p.width*4])
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user