internal/atlas: refactoring

This commit is contained in:
Hajime Hoshi 2024-04-29 23:34:37 +09:00
parent 12876343ff
commit 0af5b41d48
3 changed files with 21 additions and 32 deletions

View File

@ -14,16 +14,12 @@
package atlas
import (
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
)
const (
BaseCountToPutOnSourceBackend = baseCountToPutOnSourceBackend
)
func PutImagesOnSourceBackendForTesting(graphicsDriver graphicsdriver.Graphics) {
putImagesOnSourceBackend(graphicsDriver)
func PutImagesOnSourceBackendForTesting() {
putImagesOnSourceBackend()
}
var (

View File

@ -36,13 +36,6 @@ var (
maxSize = 0
)
func max(a, b int) int {
if a > b {
return a
}
return b
}
func min(a, b int) int {
if a < b {
return a
@ -81,7 +74,7 @@ func flushDeferred() {
// Actual time duration is increased in an exponential way for each usage as a rendering target.
const baseCountToPutOnSourceBackend = 10
func putImagesOnSourceBackend(graphicsDriver graphicsdriver.Graphics) {
func putImagesOnSourceBackend() {
// The counter usedAsDestinationCount is updated at most once per frame (#2676).
imagesUsedAsDestination.forEach(func(i *Image) {
// This counter is not updated when the backend is created in this frame.
@ -97,7 +90,7 @@ func putImagesOnSourceBackend(graphicsDriver graphicsdriver.Graphics) {
i.usedAsSourceCount++
}
if int64(i.usedAsSourceCount) >= int64(baseCountToPutOnSourceBackend*(1<<uint(min(i.usedAsDestinationCount, 31)))) {
i.putOnSourceBackend(graphicsDriver)
i.putOnSourceBackend()
i.usedAsSourceCount = 0
}
})
@ -359,7 +352,7 @@ func (i *Image) ensureIsolatedFromSource(backends []*backend) {
newI.moveTo(i)
}
func (i *Image) putOnSourceBackend(graphicsDriver graphicsdriver.Graphics) {
func (i *Image) putOnSourceBackend() {
if i.backend == nil {
i.allocate(nil, true)
return
@ -942,7 +935,7 @@ func BeginFrame(graphicsDriver graphicsdriver.Graphics) error {
}
flushDeferred()
putImagesOnSourceBackend(graphicsDriver)
putImagesOnSourceBackend()
return nil
}

View File

@ -201,7 +201,7 @@ func TestReputOnSourceBackend(t *testing.T) {
// Use the doubled count since img1 was on a texture atlas and became an isolated image once.
// Then, img1 requires longer time to recover to be on a texture atlas again.
for i := 0; i < atlas.BaseCountToPutOnSourceBackend*2; i++ {
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
vs := quadVertices(size, size, 0, 0, 1)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img1.IsOnSourceBackendForTesting(), false; got != want {
@ -209,13 +209,13 @@ func TestReputOnSourceBackend(t *testing.T) {
}
}
// Finally, img1 is on a source backend.
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
vs := quadVertices(size, size, 0, 0, 1)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img1.IsOnSourceBackendForTesting(), true; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
pix = make([]byte, 4*size*size)
ok, err := img1.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, size, size))
@ -279,7 +279,7 @@ func TestReputOnSourceBackend(t *testing.T) {
// Use img1 as a render source, but call WritePixels.
// Now use 4x count as img1 became an isolated image again.
for i := 0; i < atlas.BaseCountToPutOnSourceBackend*4; i++ {
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
img1.WritePixels(make([]byte, 4*size*size), image.Rect(0, 0, size, size))
vs := quadVertices(size, size, 0, 0, 1)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
@ -287,7 +287,7 @@ func TestReputOnSourceBackend(t *testing.T) {
t.Errorf("got: %v, want: %v", got, want)
}
}
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
// img1 is not on an atlas due to WritePixels.
vs = quadVertices(size, size, 0, 0, 1)
@ -298,7 +298,7 @@ func TestReputOnSourceBackend(t *testing.T) {
// Use img3 as a render source. As img3 is volatile, img3 is never on an atlas.
for i := 0; i < atlas.BaseCountToPutOnSourceBackend*2; i++ {
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
vs := quadVertices(size, size, 0, 0, 1)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img3}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img3.IsOnSourceBackendForTesting(), false; got != want {
@ -620,7 +620,7 @@ func TestDeallocatedAndReputOnSourceBackend(t *testing.T) {
// Use src as a render source.
for i := 0; i < atlas.BaseCountToPutOnSourceBackend/2; i++ {
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
vs := quadVertices(size, size, 0, 0, 1)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := src.IsOnSourceBackendForTesting(), false; got != want {
@ -632,7 +632,7 @@ func TestDeallocatedAndReputOnSourceBackend(t *testing.T) {
src.Deallocate()
// Confirm that PutImagesOnSourceBackendForTesting doesn't panic.
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
}
// Issue #1456
@ -665,7 +665,7 @@ func TestImageIsNotReputOnSourceBackendWithoutUsingAsSource(t *testing.T) {
// Update the count without using src2 as a rendering source.
// This should not affect whether src2 is on an atlas or not.
for i := 0; i < atlas.BaseCountToPutOnSourceBackend; i++ {
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
if got, want := src2.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -673,7 +673,7 @@ func TestImageIsNotReputOnSourceBackendWithoutUsingAsSource(t *testing.T) {
// Update the count with using src2 as a rendering source.
for i := 0; i < atlas.BaseCountToPutOnSourceBackend; i++ {
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
vs := quadVertices(size, size, 0, 0, 1)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src2}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := src2.IsOnSourceBackendForTesting(), false; got != want {
@ -681,7 +681,7 @@ func TestImageIsNotReputOnSourceBackendWithoutUsingAsSource(t *testing.T) {
}
}
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
if got, want := src2.IsOnSourceBackendForTesting(), true; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -802,14 +802,14 @@ func TestDestinationCountOverflow(t *testing.T) {
// Use dst0 as a destination for a while.
for i := 0; i < 31; i++ {
dst0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
}
// Use dst0 as a source for a while.
// As dst0 is used as a destination too many times (31 is a maximum), dst0's backend should never be a source backend.
for i := 0; i < 100; i++ {
dst1.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{dst0}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
if dst0.IsOnSourceBackendForTesting() {
t.Errorf("dst0 cannot be on a source backend: %d", i)
}
@ -836,7 +836,7 @@ func TestIteratingImagesToPutOnSourceBackend(t *testing.T) {
for _, img := range srcs {
img.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
}
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
// Use srcs as sources. This will register an image to imagesToPutOnSourceBackend.
// Check iterating the registered image works correctly.
@ -844,7 +844,7 @@ func TestIteratingImagesToPutOnSourceBackend(t *testing.T) {
for _, src := range srcs {
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
}
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
}
}