mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-02-03 14:34:26 +01:00
internal/atlas: refactoring
This commit is contained in:
parent
12876343ff
commit
0af5b41d48
@ -14,16 +14,12 @@
|
|||||||
|
|
||||||
package atlas
|
package atlas
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BaseCountToPutOnSourceBackend = baseCountToPutOnSourceBackend
|
BaseCountToPutOnSourceBackend = baseCountToPutOnSourceBackend
|
||||||
)
|
)
|
||||||
|
|
||||||
func PutImagesOnSourceBackendForTesting(graphicsDriver graphicsdriver.Graphics) {
|
func PutImagesOnSourceBackendForTesting() {
|
||||||
putImagesOnSourceBackend(graphicsDriver)
|
putImagesOnSourceBackend()
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -36,13 +36,6 @@ var (
|
|||||||
maxSize = 0
|
maxSize = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
func max(a, b int) int {
|
|
||||||
if a > b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func min(a, b int) int {
|
func min(a, b int) int {
|
||||||
if a < b {
|
if a < b {
|
||||||
return a
|
return a
|
||||||
@ -81,7 +74,7 @@ func flushDeferred() {
|
|||||||
// Actual time duration is increased in an exponential way for each usage as a rendering target.
|
// Actual time duration is increased in an exponential way for each usage as a rendering target.
|
||||||
const baseCountToPutOnSourceBackend = 10
|
const baseCountToPutOnSourceBackend = 10
|
||||||
|
|
||||||
func putImagesOnSourceBackend(graphicsDriver graphicsdriver.Graphics) {
|
func putImagesOnSourceBackend() {
|
||||||
// The counter usedAsDestinationCount is updated at most once per frame (#2676).
|
// The counter usedAsDestinationCount is updated at most once per frame (#2676).
|
||||||
imagesUsedAsDestination.forEach(func(i *Image) {
|
imagesUsedAsDestination.forEach(func(i *Image) {
|
||||||
// This counter is not updated when the backend is created in this frame.
|
// This counter is not updated when the backend is created in this frame.
|
||||||
@ -97,7 +90,7 @@ func putImagesOnSourceBackend(graphicsDriver graphicsdriver.Graphics) {
|
|||||||
i.usedAsSourceCount++
|
i.usedAsSourceCount++
|
||||||
}
|
}
|
||||||
if int64(i.usedAsSourceCount) >= int64(baseCountToPutOnSourceBackend*(1<<uint(min(i.usedAsDestinationCount, 31)))) {
|
if int64(i.usedAsSourceCount) >= int64(baseCountToPutOnSourceBackend*(1<<uint(min(i.usedAsDestinationCount, 31)))) {
|
||||||
i.putOnSourceBackend(graphicsDriver)
|
i.putOnSourceBackend()
|
||||||
i.usedAsSourceCount = 0
|
i.usedAsSourceCount = 0
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -359,7 +352,7 @@ func (i *Image) ensureIsolatedFromSource(backends []*backend) {
|
|||||||
newI.moveTo(i)
|
newI.moveTo(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) putOnSourceBackend(graphicsDriver graphicsdriver.Graphics) {
|
func (i *Image) putOnSourceBackend() {
|
||||||
if i.backend == nil {
|
if i.backend == nil {
|
||||||
i.allocate(nil, true)
|
i.allocate(nil, true)
|
||||||
return
|
return
|
||||||
@ -942,7 +935,7 @@ func BeginFrame(graphicsDriver graphicsdriver.Graphics) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
flushDeferred()
|
flushDeferred()
|
||||||
putImagesOnSourceBackend(graphicsDriver)
|
putImagesOnSourceBackend()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -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.
|
// 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.
|
// Then, img1 requires longer time to recover to be on a texture atlas again.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnSourceBackend*2; i++ {
|
for i := 0; i < atlas.BaseCountToPutOnSourceBackend*2; i++ {
|
||||||
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
|
atlas.PutImagesOnSourceBackendForTesting()
|
||||||
vs := quadVertices(size, size, 0, 0, 1)
|
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)
|
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 {
|
if got, want := img1.IsOnSourceBackendForTesting(), false; got != want {
|
||||||
@ -209,13 +209,13 @@ func TestReputOnSourceBackend(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Finally, img1 is on a source backend.
|
// Finally, img1 is on a source backend.
|
||||||
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
|
atlas.PutImagesOnSourceBackendForTesting()
|
||||||
vs := quadVertices(size, size, 0, 0, 1)
|
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)
|
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 {
|
if got, want := img1.IsOnSourceBackendForTesting(), true; got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
|
atlas.PutImagesOnSourceBackendForTesting()
|
||||||
|
|
||||||
pix = make([]byte, 4*size*size)
|
pix = make([]byte, 4*size*size)
|
||||||
ok, err := img1.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, 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.
|
// Use img1 as a render source, but call WritePixels.
|
||||||
// Now use 4x count as img1 became an isolated image again.
|
// Now use 4x count as img1 became an isolated image again.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnSourceBackend*4; i++ {
|
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))
|
img1.WritePixels(make([]byte, 4*size*size), image.Rect(0, 0, size, size))
|
||||||
vs := quadVertices(size, size, 0, 0, 1)
|
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)
|
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)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
|
atlas.PutImagesOnSourceBackendForTesting()
|
||||||
|
|
||||||
// img1 is not on an atlas due to WritePixels.
|
// img1 is not on an atlas due to WritePixels.
|
||||||
vs = quadVertices(size, size, 0, 0, 1)
|
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.
|
// Use img3 as a render source. As img3 is volatile, img3 is never on an atlas.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnSourceBackend*2; i++ {
|
for i := 0; i < atlas.BaseCountToPutOnSourceBackend*2; i++ {
|
||||||
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
|
atlas.PutImagesOnSourceBackendForTesting()
|
||||||
vs := quadVertices(size, size, 0, 0, 1)
|
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)
|
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 {
|
if got, want := img3.IsOnSourceBackendForTesting(), false; got != want {
|
||||||
@ -620,7 +620,7 @@ func TestDeallocatedAndReputOnSourceBackend(t *testing.T) {
|
|||||||
|
|
||||||
// Use src as a render source.
|
// Use src as a render source.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnSourceBackend/2; i++ {
|
for i := 0; i < atlas.BaseCountToPutOnSourceBackend/2; i++ {
|
||||||
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
|
atlas.PutImagesOnSourceBackendForTesting()
|
||||||
vs := quadVertices(size, size, 0, 0, 1)
|
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)
|
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 {
|
if got, want := src.IsOnSourceBackendForTesting(), false; got != want {
|
||||||
@ -632,7 +632,7 @@ func TestDeallocatedAndReputOnSourceBackend(t *testing.T) {
|
|||||||
src.Deallocate()
|
src.Deallocate()
|
||||||
|
|
||||||
// Confirm that PutImagesOnSourceBackendForTesting doesn't panic.
|
// Confirm that PutImagesOnSourceBackendForTesting doesn't panic.
|
||||||
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
|
atlas.PutImagesOnSourceBackendForTesting()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue #1456
|
// Issue #1456
|
||||||
@ -665,7 +665,7 @@ func TestImageIsNotReputOnSourceBackendWithoutUsingAsSource(t *testing.T) {
|
|||||||
// Update the count without using src2 as a rendering source.
|
// Update the count without using src2 as a rendering source.
|
||||||
// This should not affect whether src2 is on an atlas or not.
|
// This should not affect whether src2 is on an atlas or not.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnSourceBackend; i++ {
|
for i := 0; i < atlas.BaseCountToPutOnSourceBackend; i++ {
|
||||||
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
|
atlas.PutImagesOnSourceBackendForTesting()
|
||||||
if got, want := src2.IsOnSourceBackendForTesting(), false; got != want {
|
if got, want := src2.IsOnSourceBackendForTesting(), false; got != want {
|
||||||
t.Errorf("got: %v, want: %v", 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.
|
// Update the count with using src2 as a rendering source.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnSourceBackend; i++ {
|
for i := 0; i < atlas.BaseCountToPutOnSourceBackend; i++ {
|
||||||
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
|
atlas.PutImagesOnSourceBackendForTesting()
|
||||||
vs := quadVertices(size, size, 0, 0, 1)
|
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)
|
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 {
|
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 {
|
if got, want := src2.IsOnSourceBackendForTesting(), true; got != want {
|
||||||
t.Errorf("got: %v, want: %v", 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.
|
// Use dst0 as a destination for a while.
|
||||||
for i := 0; i < 31; i++ {
|
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)
|
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.
|
// 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.
|
// 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++ {
|
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)
|
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() {
|
if dst0.IsOnSourceBackendForTesting() {
|
||||||
t.Errorf("dst0 cannot be on a source backend: %d", i)
|
t.Errorf("dst0 cannot be on a source backend: %d", i)
|
||||||
}
|
}
|
||||||
@ -836,7 +836,7 @@ func TestIteratingImagesToPutOnSourceBackend(t *testing.T) {
|
|||||||
for _, img := range srcs {
|
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)
|
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.
|
// Use srcs as sources. This will register an image to imagesToPutOnSourceBackend.
|
||||||
// Check iterating the registered image works correctly.
|
// Check iterating the registered image works correctly.
|
||||||
@ -844,7 +844,7 @@ func TestIteratingImagesToPutOnSourceBackend(t *testing.T) {
|
|||||||
for _, src := range srcs {
|
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)
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user