mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
restorable: Refactoring
This commit is contained in:
parent
0f611b49ac
commit
3c0cd47b1f
@ -301,7 +301,7 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
||||
}
|
||||
i.image.ReplacePixels(pixels, x, y, width, height)
|
||||
|
||||
if !NeedsRestoring() {
|
||||
if !needsRestoring() {
|
||||
i.makeStale()
|
||||
return
|
||||
}
|
||||
@ -362,7 +362,7 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16,
|
||||
}
|
||||
theImages.makeStaleIfDependingOn(i)
|
||||
|
||||
if img.stale || img.volatile || i.screen || !NeedsRestoring() || i.volatile {
|
||||
if img.stale || img.volatile || i.screen || !needsRestoring() || i.volatile {
|
||||
i.makeStale()
|
||||
} else {
|
||||
i.appendDrawTrianglesHistory(img, vertices, indices, colorm, mode, filter, address)
|
||||
@ -447,7 +447,7 @@ func (i *Image) readPixelsFromGPU() {
|
||||
|
||||
// resolveStale resolves the image's 'stale' state.
|
||||
func (i *Image) resolveStale() {
|
||||
if !NeedsRestoring() {
|
||||
if !needsRestoring() {
|
||||
return
|
||||
}
|
||||
|
||||
@ -551,15 +551,11 @@ func (i *Image) Dispose() {
|
||||
i.stale = false
|
||||
}
|
||||
|
||||
// IsInvalidated returns a boolean value indicating whether the image is invalidated.
|
||||
// isInvalidated returns a boolean value indicating whether the image is invalidated.
|
||||
//
|
||||
// If an image is invalidated, GL context is lost and all the images should be restored asap.
|
||||
func (i *Image) IsInvalidated() (bool, error) {
|
||||
func (i *Image) isInvalidated() bool {
|
||||
// FlushCommands is required because c.offscreen.impl might not have an actual texture.
|
||||
graphicscommand.FlushCommands()
|
||||
if !NeedsRestoring() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return i.image.IsInvalidated(), nil
|
||||
return i.image.IsInvalidated()
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ import (
|
||||
// forceRestoring reports whether restoring forcely happens or not.
|
||||
var forceRestoring = true
|
||||
|
||||
// NeedsRestoring reports whether restoring process works or not.
|
||||
func NeedsRestoring() bool {
|
||||
// needsRestoring reports whether restoring process works or not.
|
||||
func needsRestoring() bool {
|
||||
if forceRestoring {
|
||||
return true
|
||||
}
|
||||
@ -53,16 +53,33 @@ var theImages = &images{
|
||||
// ResolveStaleImages is intended to be called at the end of a frame.
|
||||
func ResolveStaleImages() {
|
||||
graphicscommand.FlushCommands()
|
||||
if !NeedsRestoring() {
|
||||
if !needsRestoring() {
|
||||
return
|
||||
}
|
||||
theImages.resolveStaleImages()
|
||||
}
|
||||
|
||||
// Restore restores the images.
|
||||
// RestoreIfNeeded restores the images.
|
||||
//
|
||||
// Restoring means to make all *graphicscommand.Image objects have their textures and framebuffers.
|
||||
func Restore() error {
|
||||
func RestoreIfNeeded() error {
|
||||
if !needsRestoring() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !forceRestoring {
|
||||
r := false
|
||||
// As isInvalidated() is expensive, call this only for one image.
|
||||
// This assumes that if there is one image that is invalidated, all images are invalidated.
|
||||
for img := range theImages.images {
|
||||
r = img.isInvalidated()
|
||||
break
|
||||
}
|
||||
if !r {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if err := graphicscommand.ResetGraphicsDriverState(); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -144,7 +161,7 @@ func (i *images) makeStaleIfDependingOnImpl(target *Image) {
|
||||
//
|
||||
// Restoring means to make all *graphicscommand.Image objects have their textures and framebuffers.
|
||||
func (i *images) restore() error {
|
||||
if !NeedsRestoring() {
|
||||
if !needsRestoring() {
|
||||
panic("restorable: restore cannot be called when restoring is disabled")
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ func TestRestore(t *testing.T) {
|
||||
clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff}
|
||||
img0.Fill(clr0.R, clr0.G, clr0.B, clr0.A)
|
||||
ResolveStaleImages()
|
||||
if err := Restore(); err != nil {
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := clr0
|
||||
@ -92,7 +92,7 @@ func TestRestoreWithoutDraw(t *testing.T) {
|
||||
// If there is no drawing command on img0, img0 is cleared when restored.
|
||||
|
||||
ResolveStaleImages()
|
||||
if err := Restore(); err != nil {
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ func TestRestoreChain(t *testing.T) {
|
||||
imgs[i+1].DrawTriangles(imgs[i], vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||
}
|
||||
ResolveStaleImages()
|
||||
if err := Restore(); err != nil {
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := clr
|
||||
@ -175,7 +175,7 @@ func TestRestoreChain2(t *testing.T) {
|
||||
}
|
||||
|
||||
ResolveStaleImages()
|
||||
if err := Restore(); err != nil {
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, img := range imgs {
|
||||
@ -214,7 +214,7 @@ func TestRestoreOverrideSource(t *testing.T) {
|
||||
img0.Fill(clr1.R, clr1.G, clr1.B, clr1.A)
|
||||
img1.DrawTriangles(img0, quadVertices(img0, w, h, 0, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||
ResolveStaleImages()
|
||||
if err := Restore(); err != nil {
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testCases := []struct {
|
||||
@ -307,7 +307,7 @@ func TestRestoreComplexGraph(t *testing.T) {
|
||||
vs = quadVertices(img3, w, h, 2, 0)
|
||||
img7.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||
ResolveStaleImages()
|
||||
if err := Restore(); err != nil {
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testCases := []struct {
|
||||
@ -398,7 +398,7 @@ func TestRestoreRecursive(t *testing.T) {
|
||||
img1.DrawTriangles(img0, quadVertices(img0, w, h, 1, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||
img0.DrawTriangles(img1, quadVertices(img1, w, h, 1, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||
ResolveStaleImages()
|
||||
if err := Restore(); err != nil {
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testCases := []struct {
|
||||
@ -452,7 +452,7 @@ func TestReplacePixels(t *testing.T) {
|
||||
}
|
||||
}
|
||||
ResolveStaleImages()
|
||||
if err := Restore(); err != nil {
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 7; j < 11; j++ {
|
||||
@ -484,7 +484,7 @@ func TestDrawTrianglesAndReplacePixels(t *testing.T) {
|
||||
img1.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, 0, 2, 1)
|
||||
|
||||
ResolveStaleImages()
|
||||
if err := Restore(); err != nil {
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, g, b, a := img1.At(0, 0)
|
||||
@ -517,7 +517,7 @@ func TestDispose(t *testing.T) {
|
||||
img1.Dispose()
|
||||
|
||||
ResolveStaleImages()
|
||||
if err := Restore(); err != nil {
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, g, b, a := img0.At(0, 0)
|
||||
@ -625,7 +625,7 @@ func TestReplacePixelsOnly(t *testing.T) {
|
||||
}
|
||||
|
||||
ResolveStaleImages()
|
||||
if err := Restore(); err != nil {
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := color.RGBA{1, 2, 3, 4}
|
||||
|
@ -404,13 +404,6 @@ func (i *Image) IsVolatile() bool {
|
||||
return i.backend.restorable.IsVolatile()
|
||||
}
|
||||
|
||||
func (i *Image) IsInvalidated() (bool, error) {
|
||||
backendsM.Lock()
|
||||
defer backendsM.Unlock()
|
||||
v, err := i.backend.restorable.IsInvalidated()
|
||||
return v, err
|
||||
}
|
||||
|
||||
func NewImage(width, height int) *Image {
|
||||
// Actual allocation is done lazily.
|
||||
return &Image{
|
||||
@ -508,15 +501,10 @@ func ResolveStaleImages() {
|
||||
restorable.ResolveStaleImages()
|
||||
}
|
||||
|
||||
func NeedsRestoring() bool {
|
||||
// As NeedsRestoring is an immutable state, no need to lock here.
|
||||
return restorable.NeedsRestoring()
|
||||
}
|
||||
|
||||
func Restore() error {
|
||||
func RestoreIfNeeded() error {
|
||||
backendsM.Lock()
|
||||
defer backendsM.Unlock()
|
||||
return restorable.Restore()
|
||||
return restorable.RestoreIfNeeded()
|
||||
}
|
||||
|
||||
func Images() []image.Image {
|
||||
|
16
uicontext.go
16
uicontext.go
@ -146,22 +146,8 @@ func (c *uiContext) Update(afterFrameUpdate func()) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *uiContext) needsRestoring() (bool, error) {
|
||||
return c.offscreen.mipmap.original().IsInvalidated()
|
||||
}
|
||||
|
||||
func (c *uiContext) restoreIfNeeded() error {
|
||||
if !shareable.NeedsRestoring() {
|
||||
return nil
|
||||
}
|
||||
r, err := c.needsRestoring()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !r {
|
||||
return nil
|
||||
}
|
||||
if err := shareable.Restore(); err != nil {
|
||||
if err := shareable.RestoreIfNeeded(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
Loading…
Reference in New Issue
Block a user