mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-27 03:02:49 +01:00
internal/atlas: change when to count up usedAsDestinationCount
An image has a counter to count how many times an image is used. Before this change, the counter was updated only when an image was moved from a source backend to a destination backend. This seemed not enough, and an image was likely moved to a source backend more often than necessary (#2676). However, there was also an issue that the counter was updated too aggressively and the image was unlikely moved from a destination to a source image (#2586). In order to resolve this dilemma, let's adopt an intermediate way: count up the counter at most once per frame. Updates #2586 Updates #2676
This commit is contained in:
parent
3bc970e898
commit
1ae5e022b6
@ -64,9 +64,15 @@ func flushDeferred() {
|
|||||||
const baseCountToPutOnSourceBackend = 10
|
const baseCountToPutOnSourceBackend = 10
|
||||||
|
|
||||||
func putImagesOnSourceBackend(graphicsDriver graphicsdriver.Graphics) error {
|
func putImagesOnSourceBackend(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
|
// The counter usedAsDestinationCount is updated at most once per frame (#2676).
|
||||||
|
for i := range imagesUsedAsDestination {
|
||||||
|
i.usedAsDestinationCount++
|
||||||
|
delete(imagesUsedAsDestination, i)
|
||||||
|
}
|
||||||
|
|
||||||
for i := range imagesToPutOnSourceBackend {
|
for i := range imagesToPutOnSourceBackend {
|
||||||
i.usedAsSourceCount++
|
i.usedAsSourceCount++
|
||||||
if i.usedAsSourceCount >= baseCountToPutOnSourceBackend*(1<<uint(min(i.destinationCount, 31))) {
|
if i.usedAsSourceCount >= baseCountToPutOnSourceBackend*(1<<uint(min(i.usedAsDestinationCount, 31))) {
|
||||||
if err := i.putOnSourceBackend(graphicsDriver); err != nil {
|
if err := i.putOnSourceBackend(graphicsDriver); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -123,6 +129,8 @@ var (
|
|||||||
|
|
||||||
imagesToPutOnSourceBackend = map[*Image]struct{}{}
|
imagesToPutOnSourceBackend = map[*Image]struct{}{}
|
||||||
|
|
||||||
|
imagesUsedAsDestination = map[*Image]struct{}{}
|
||||||
|
|
||||||
deferred []func()
|
deferred []func()
|
||||||
|
|
||||||
// deferredM is a mutex for the slice operations. This must not be used for other usages.
|
// deferredM is a mutex for the slice operations. This must not be used for other usages.
|
||||||
@ -172,10 +180,11 @@ type Image struct {
|
|||||||
// WritePixels doesn't affect this value since WritePixels can be done on images on an atlas.
|
// WritePixels doesn't affect this value since WritePixels can be done on images on an atlas.
|
||||||
usedAsSourceCount int
|
usedAsSourceCount int
|
||||||
|
|
||||||
// destinationCount represents how many times an image switches its backend when the image is used
|
// usedAsDestinationCount represents how many times an image is used as a rendering destination at DrawTriangles.
|
||||||
// as a rendering destination at DrawTriangles.
|
// usedAsDestinationCount affects the calculation when to put the image onto a texture atlas again.
|
||||||
// destinationCount affects the calculation when to put the image onto a texture atlas again.
|
//
|
||||||
destinationCount int
|
// usedAsDestinationCount is never reset.
|
||||||
|
usedAsDestinationCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
// moveTo moves its content to the given image dst.
|
// moveTo moves its content to the given image dst.
|
||||||
@ -231,6 +240,8 @@ func (i *Image) ensureIsolatedFromSource(backends []*backend) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imagesUsedAsDestination[i] = struct{}{}
|
||||||
|
|
||||||
// Check if i has the same backend as the given backends.
|
// Check if i has the same backend as the given backends.
|
||||||
var needsIsolation bool
|
var needsIsolation bool
|
||||||
for _, b := range backends {
|
for _, b := range backends {
|
||||||
@ -270,10 +281,6 @@ func (i *Image) ensureIsolatedFromSource(backends []*backend) {
|
|||||||
delete(theSourceBackendsForOneFrame, origBackend)
|
delete(theSourceBackendsForOneFrame, origBackend)
|
||||||
|
|
||||||
newI.moveTo(i)
|
newI.moveTo(i)
|
||||||
|
|
||||||
// Count up only when the backend is switched. (#2586).
|
|
||||||
// This counting up must be done after moveTo.
|
|
||||||
i.destinationCount++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) putOnSourceBackend(graphicsDriver graphicsdriver.Graphics) error {
|
func (i *Image) putOnSourceBackend(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user