mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-26 03:38:55 +01:00
parent
b03c02dd28
commit
bc4e35a6c5
@ -22,10 +22,40 @@ import (
|
|||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/affine"
|
"github.com/hajimehoshi/ebiten/internal/affine"
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/hooks"
|
||||||
"github.com/hajimehoshi/ebiten/internal/packing"
|
"github.com/hajimehoshi/ebiten/internal/packing"
|
||||||
"github.com/hajimehoshi/ebiten/internal/restorable"
|
"github.com/hajimehoshi/ebiten/internal/restorable"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
hooks.AppendHookOnBeforeUpdate(func() error {
|
||||||
|
makeImagesShared()
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaxCountForShare represents the time duration when the image can become shared.
|
||||||
|
//
|
||||||
|
// This value is expoted for testing.
|
||||||
|
const MaxCountForShare = 10
|
||||||
|
|
||||||
|
func makeImagesShared() {
|
||||||
|
backendsM.Lock()
|
||||||
|
defer backendsM.Unlock()
|
||||||
|
|
||||||
|
for i := range imagesToMakeShared {
|
||||||
|
i.nonUpdatedCount++
|
||||||
|
if i.nonUpdatedCount >= MaxCountForShare {
|
||||||
|
i.makeShared()
|
||||||
|
}
|
||||||
|
delete(imagesToMakeShared, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeImagesSharedForTesting() {
|
||||||
|
makeImagesShared()
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
initSize = 1024
|
initSize = 1024
|
||||||
maxSize = 4096
|
maxSize = 4096
|
||||||
@ -84,6 +114,8 @@ var (
|
|||||||
|
|
||||||
// theBackends is a set of actually shared images.
|
// theBackends is a set of actually shared images.
|
||||||
theBackends = []*backend{}
|
theBackends = []*backend{}
|
||||||
|
|
||||||
|
imagesToMakeShared = map[*Image]struct{}{}
|
||||||
)
|
)
|
||||||
|
|
||||||
type Image struct {
|
type Image struct {
|
||||||
@ -93,8 +125,17 @@ type Image struct {
|
|||||||
|
|
||||||
backend *backend
|
backend *backend
|
||||||
|
|
||||||
node *packing.Node
|
node *packing.Node
|
||||||
countForShare int
|
|
||||||
|
// nonUpdatedCount represents how long the image is kept not modified with DrawTriangles.
|
||||||
|
// In the current implementation, if an image is being modified by DrawTriangles, the image is separated from
|
||||||
|
// a shared (restorable) image by ensureNotShared.
|
||||||
|
//
|
||||||
|
// nonUpdatedCount is increased every frame if the image is not modified, or set to 0 if the image id
|
||||||
|
// modified.
|
||||||
|
//
|
||||||
|
// ReplacePixels doesn't affect this value since ReplacePixels can be done on shared images.
|
||||||
|
nonUpdatedCount int
|
||||||
|
|
||||||
neverShared bool
|
neverShared bool
|
||||||
}
|
}
|
||||||
@ -140,7 +181,7 @@ func (i *Image) ensureNotShared() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) forceShared() {
|
func (i *Image) makeShared() {
|
||||||
if i.backend == nil {
|
if i.backend == nil {
|
||||||
i.allocate(true)
|
i.allocate(true)
|
||||||
return
|
return
|
||||||
@ -151,7 +192,7 @@ func (i *Image) forceShared() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !i.shareable() {
|
if !i.shareable() {
|
||||||
panic("shareable: forceShared cannot be called on a non-shareable image")
|
panic("shareable: makeShared cannot be called on a non-shareable image")
|
||||||
}
|
}
|
||||||
|
|
||||||
newI := NewImage(i.width, i.height)
|
newI := NewImage(i.width, i.height)
|
||||||
@ -167,7 +208,7 @@ func (i *Image) forceShared() {
|
|||||||
}
|
}
|
||||||
newI.replacePixels(pixels)
|
newI.replacePixels(pixels)
|
||||||
newI.moveTo(i)
|
newI.moveTo(i)
|
||||||
i.countForShare = 0
|
i.nonUpdatedCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) region() (x, y, width, height int) {
|
func (i *Image) region() (x, y, width, height int) {
|
||||||
@ -207,8 +248,6 @@ func (i *Image) PutVertex(dest []float32, dx, dy, sx, sy float32, bx0, by0, bx1,
|
|||||||
i.backend.restorable.PutVertex(dest, dx, dy, sx+oxf, sy+oyf, bx0+oxf, by0+oyf, bx1+oxf, by1+oyf, cr, cg, cb, ca)
|
i.backend.restorable.PutVertex(dest, dx, dy, sx+oxf, sy+oyf, bx0+oxf, by0+oyf, bx1+oxf, by1+oyf, cr, cg, cb, ca)
|
||||||
}
|
}
|
||||||
|
|
||||||
const MaxCountForShare = 10
|
|
||||||
|
|
||||||
func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) {
|
||||||
backendsM.Lock()
|
backendsM.Lock()
|
||||||
defer backendsM.Unlock()
|
defer backendsM.Unlock()
|
||||||
@ -233,17 +272,12 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16,
|
|||||||
|
|
||||||
i.backend.restorable.DrawTriangles(img.backend.restorable, vertices, indices, colorm, mode, filter, address)
|
i.backend.restorable.DrawTriangles(img.backend.restorable, vertices, indices, colorm, mode, filter, address)
|
||||||
|
|
||||||
i.countForShare = 0
|
i.nonUpdatedCount = 0
|
||||||
|
delete(imagesToMakeShared, i)
|
||||||
|
|
||||||
// TODO: Reusing shared images is temporarily suspended for performance. See #661.
|
if !img.isShared() && img.shareable() {
|
||||||
//
|
imagesToMakeShared[img] = struct{}{}
|
||||||
// if !img.isShared() && img.shareable() {
|
}
|
||||||
// img.countForShare++
|
|
||||||
// if img.countForShare >= MaxCountForShare {
|
|
||||||
// img.forceShared()
|
|
||||||
// img.countForShare = 0
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill fills the image with a color. This affects not only the (0, 0)-(width, height) region but also the whole
|
// Fill fills the image with a color. This affects not only the (0, 0)-(width, height) region but also the whole
|
||||||
|
@ -112,7 +112,7 @@ func TestEnsureNotShared(t *testing.T) {
|
|||||||
img4.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img4.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Disabled_TestReshared(t *testing.T) {
|
func TestReshared(t *testing.T) {
|
||||||
const size = 16
|
const size = 16
|
||||||
|
|
||||||
img0 := NewImage(size, size)
|
img0 := NewImage(size, size)
|
||||||
@ -122,8 +122,7 @@ func Disabled_TestReshared(t *testing.T) {
|
|||||||
img1 := NewImage(size, size)
|
img1 := NewImage(size, size)
|
||||||
defer img1.Dispose()
|
defer img1.Dispose()
|
||||||
img1.ReplacePixels(make([]byte, 4*size*size))
|
img1.ReplacePixels(make([]byte, 4*size*size))
|
||||||
want := true
|
if got, want := img1.IsSharedForTesting(), true; got != want {
|
||||||
if got := img1.IsSharedForTesting(); got != want {
|
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,8 +143,7 @@ func Disabled_TestReshared(t *testing.T) {
|
|||||||
img3.MakeVolatile()
|
img3.MakeVolatile()
|
||||||
defer img3.Dispose()
|
defer img3.Dispose()
|
||||||
img1.ReplacePixels(make([]byte, 4*size*size))
|
img1.ReplacePixels(make([]byte, 4*size*size))
|
||||||
want = false
|
if got, want := img3.IsSharedForTesting(), false; got != want {
|
||||||
if got := img3.IsSharedForTesting(); got != want {
|
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,19 +151,19 @@ func Disabled_TestReshared(t *testing.T) {
|
|||||||
vs := img2.QuadVertices(0, 0, size, size, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
vs := img2.QuadVertices(0, 0, size, size, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
img1.DrawTriangles(img2, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img1.DrawTriangles(img2, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
want = false
|
if got, want := img1.IsSharedForTesting(), false; got != want {
|
||||||
if got := img1.IsSharedForTesting(); got != want {
|
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use img1 as a render source.
|
// Use img1 as a render source.
|
||||||
for i := 0; i < MaxCountForShare-1; i++ {
|
for i := 0; i < MaxCountForShare; i++ {
|
||||||
|
MakeImagesSharedForTesting()
|
||||||
img0.DrawTriangles(img1, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img0.DrawTriangles(img1, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
want := false
|
if got, want := img1.IsSharedForTesting(), false; got != want {
|
||||||
if got := img1.IsSharedForTesting(); got != want {
|
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MakeImagesSharedForTesting()
|
||||||
|
|
||||||
for j := 0; j < size; j++ {
|
for j := 0; j < size; j++ {
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
@ -179,8 +177,7 @@ func Disabled_TestReshared(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
img0.DrawTriangles(img1, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img0.DrawTriangles(img1, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
want = true
|
if got, want := img1.IsSharedForTesting(), true; got != want {
|
||||||
if got := img1.IsSharedForTesting(); got != want {
|
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,9 +194,9 @@ func Disabled_TestReshared(t *testing.T) {
|
|||||||
|
|
||||||
// Use img3 as a render source. img3 never uses a shared texture.
|
// Use img3 as a render source. img3 never uses a shared texture.
|
||||||
for i := 0; i < MaxCountForShare*2; i++ {
|
for i := 0; i < MaxCountForShare*2; i++ {
|
||||||
|
MakeImagesSharedForTesting()
|
||||||
img0.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
img0.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
want := false
|
if got, want := img3.IsSharedForTesting(), false; got != want {
|
||||||
if got := img3.IsSharedForTesting(); got != want {
|
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user