Skip to content

Commit

Permalink
internal/atlas: refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
hajimehoshi committed Apr 29, 2024
1 parent 1287634 commit 0af5b41
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 32 deletions.
8 changes: 2 additions & 6 deletions internal/atlas/export_test.go
Expand Up @@ -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 (
Expand Down
15 changes: 4 additions & 11 deletions internal/atlas/image.go
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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
}
})
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -942,7 +935,7 @@ func BeginFrame(graphicsDriver graphicsdriver.Graphics) error {
}

flushDeferred()
putImagesOnSourceBackend(graphicsDriver)
putImagesOnSourceBackend()

return nil
}
Expand Down
30 changes: 15 additions & 15 deletions internal/atlas/image_test.go
Expand Up @@ -201,21 +201,21 @@ 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 {
t.Errorf("got: %v, want: %v", got, want)
}
}
// 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))
Expand Down Expand Up @@ -279,15 +279,15 @@ 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)
if got, want := img1.IsOnSourceBackendForTesting(), false; got != want {
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)
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -665,23 +665,23 @@ 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)
}
}

// 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 {
t.Errorf("got: %v, want: %v", got, want)
}
}

atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
atlas.PutImagesOnSourceBackendForTesting()
if got, want := src2.IsOnSourceBackendForTesting(), true; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
Expand Down Expand Up @@ -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)
}
Expand All @@ -836,15 +836,15 @@ 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.
for i := 0; i < 100; i++ {
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()
}
}

Expand Down

0 comments on commit 0af5b41

Please sign in to comment.