restorable: Refactoring

This commit is contained in:
Hajime Hoshi 2019-07-21 10:52:29 +09:00
parent 0cf11d9af8
commit 777cab5cc3

View File

@ -28,9 +28,13 @@ type Pixels struct {
rectToPixels *rectToPixels rectToPixels *rectToPixels
} }
// Apply applies the Pixels state to the given image especially for restoring.
//
// Apply must work even with an image not initialized.
func (p *Pixels) Apply(img *graphicscommand.Image) { func (p *Pixels) Apply(img *graphicscommand.Image) {
// TODO: Clearing is not needed when the image is for only ReplacePixels.
clearImage(img)
if p.rectToPixels == nil { if p.rectToPixels == nil {
clearImage(img)
return return
} }
@ -77,14 +81,13 @@ type drawTrianglesHistoryItem struct {
type Image struct { type Image struct {
image *graphicscommand.Image image *graphicscommand.Image
basePixels *Pixels basePixels Pixels
// drawTrianglesHistory is a set of draw-image commands. // drawTrianglesHistory is a set of draw-image commands.
// TODO: This should be merged with the similar command queue in package graphics (#433). // TODO: This should be merged with the similar command queue in package graphics (#433).
drawTrianglesHistory []*drawTrianglesHistoryItem drawTrianglesHistory []*drawTrianglesHistoryItem
// stale indicates whether the image needs to be synced with GPU as soon as possible. // stale indicates whether the image needs to be synced with GPU as soon as possible.
// TODO: Instead of this boolean value, can we represent the stale state with basePixels's state?
stale bool stale bool
// volatile indicates whether the image is cleared whenever a frame starts. // volatile indicates whether the image is cleared whenever a frame starts.
@ -125,7 +128,7 @@ func NewImage(width, height int) *Image {
i := &Image{ i := &Image{
image: graphicscommand.NewImage(width, height), image: graphicscommand.NewImage(width, height),
} }
i.clearForInitialization() i.clear()
theImages.add(i) theImages.add(i)
return i return i
} }
@ -178,7 +181,7 @@ func NewScreenFramebufferImage(width, height int) *Image {
image: graphicscommand.NewScreenFramebufferImage(width, height), image: graphicscommand.NewScreenFramebufferImage(width, height),
screen: true, screen: true,
} }
i.clearForInitialization() i.clear()
theImages.add(i) theImages.add(i)
return i return i
} }
@ -188,12 +191,6 @@ func (i *Image) Clear() {
i.clear() i.clear()
} }
// clearForInitialization clears the underlying image for initialization.
func (i *Image) clearForInitialization() {
// As this is for initialization, drawing history doesn't have to be adjusted.
i.clear()
}
// clearImage clears a graphicscommand.Image. // clearImage clears a graphicscommand.Image.
// This does nothing to do with a restorable.Image's rendering state. // This does nothing to do with a restorable.Image's rendering state.
func clearImage(img *graphicscommand.Image) { func clearImage(img *graphicscommand.Image) {
@ -232,7 +229,7 @@ func (i *Image) clear() {
// //
// After ResetRestoringState, the image is assumed to be cleared. // After ResetRestoringState, the image is assumed to be cleared.
func (i *Image) ResetRestoringState() { func (i *Image) ResetRestoringState() {
i.basePixels = &Pixels{} i.basePixels = Pixels{}
i.drawTrianglesHistory = nil i.drawTrianglesHistory = nil
i.stale = false i.stale = false
} }
@ -243,7 +240,7 @@ func (i *Image) IsVolatile() bool {
// BasePixelsForTesting returns the image's basePixels for testing. // BasePixelsForTesting returns the image's basePixels for testing.
func (i *Image) BasePixelsForTesting() *Pixels { func (i *Image) BasePixelsForTesting() *Pixels {
return i.basePixels return &i.basePixels
} }
// Size returns the image's size. // Size returns the image's size.
@ -281,7 +278,7 @@ func (i *Image) PutVertex(vs []float32, dx, dy, sx, sy float32, bx0, by0, bx1, b
// makeStale makes the image stale. // makeStale makes the image stale.
func (i *Image) makeStale() { func (i *Image) makeStale() {
i.basePixels = nil i.basePixels = Pixels{}
i.drawTrianglesHistory = nil i.drawTrianglesHistory = nil
i.stale = true i.stale = true
@ -322,9 +319,6 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
} }
if x == 0 && y == 0 && width == w && height == h { if x == 0 && y == 0 && width == w && height == h {
if i.basePixels == nil {
i.basePixels = &Pixels{}
}
if pixels != nil { if pixels != nil {
i.basePixels.AddOrReplace(pixels, 0, 0, w, h) i.basePixels.AddOrReplace(pixels, 0, 0, w, h)
} else { } else {
@ -347,9 +341,6 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
return return
} }
if i.basePixels == nil {
i.basePixels = &Pixels{}
}
if pixels != nil { if pixels != nil {
i.basePixels.AddOrReplace(pixels, x, y, width, height) i.basePixels.AddOrReplace(pixels, x, y, width, height)
} else { } else {
@ -401,7 +392,7 @@ func (i *Image) appendDrawTrianglesHistory(image *Image, vertices []float32, ind
} }
func (i *Image) readPixelsFromGPUIfNeeded() { func (i *Image) readPixelsFromGPUIfNeeded() {
if i.basePixels == nil || len(i.drawTrianglesHistory) > 0 || i.stale { if len(i.drawTrianglesHistory) > 0 || i.stale {
graphicscommand.FlushCommands() graphicscommand.FlushCommands()
i.readPixelsFromGPU() i.readPixelsFromGPU()
i.drawTrianglesHistory = nil i.drawTrianglesHistory = nil
@ -420,11 +411,6 @@ func (i *Image) At(x, y int) (byte, byte, byte, byte) {
i.readPixelsFromGPUIfNeeded() i.readPixelsFromGPUIfNeeded()
// Even after readPixelsFromGPU, basePixels might be nil when OpenGL error happens.
if i.basePixels == nil {
return 0, 0, 0, 0
}
return i.basePixels.At(x, y) return i.basePixels.At(x, y)
} }
@ -441,7 +427,7 @@ func (i *Image) makeStaleIfDependingOn(target *Image) {
// readPixelsFromGPU reads the pixels from GPU and resolves the image's 'stale' state. // readPixelsFromGPU reads the pixels from GPU and resolves the image's 'stale' state.
func (i *Image) readPixelsFromGPU() { func (i *Image) readPixelsFromGPU() {
w, h := i.Size() w, h := i.Size()
i.basePixels = &Pixels{} i.basePixels = Pixels{}
i.basePixels.AddOrReplace(i.image.Pixels(), 0, 0, w, h) i.basePixels.AddOrReplace(i.image.Pixels(), 0, 0, w, h)
i.drawTrianglesHistory = nil i.drawTrianglesHistory = nil
i.stale = false i.stale = false
@ -499,14 +485,14 @@ func (i *Image) restore() error {
// The screen image should also be recreated because framebuffer might // The screen image should also be recreated because framebuffer might
// be changed. // be changed.
i.image = graphicscommand.NewScreenFramebufferImage(w, h) i.image = graphicscommand.NewScreenFramebufferImage(w, h)
i.basePixels = nil i.basePixels = Pixels{}
i.drawTrianglesHistory = nil i.drawTrianglesHistory = nil
i.stale = false i.stale = false
return nil return nil
} }
if i.volatile { if i.volatile {
i.image = graphicscommand.NewImage(w, h) i.image = graphicscommand.NewImage(w, h)
i.clearForInitialization() i.clear()
return nil return nil
} }
if i.stale { if i.stale {
@ -515,11 +501,8 @@ func (i *Image) restore() error {
} }
gimg := graphicscommand.NewImage(w, h) gimg := graphicscommand.NewImage(w, h)
// Clear the image explicitly. // gimg is not initialized (by clearing), but Apply should work.
clearImage(gimg) i.basePixels.Apply(gimg)
if i.basePixels != nil {
i.basePixels.Apply(gimg)
}
for _, c := range i.drawTrianglesHistory { for _, c := range i.drawTrianglesHistory {
if c.image.hasDependency() { if c.image.hasDependency() {
@ -529,7 +512,7 @@ func (i *Image) restore() error {
} }
if len(i.drawTrianglesHistory) > 0 { if len(i.drawTrianglesHistory) > 0 {
i.basePixels = &Pixels{} i.basePixels = Pixels{}
i.basePixels.AddOrReplace(gimg.Pixels(), 0, 0, w, h) i.basePixels.AddOrReplace(gimg.Pixels(), 0, 0, w, h)
} }
@ -547,7 +530,7 @@ func (i *Image) Dispose() {
i.image.Dispose() i.image.Dispose()
i.image = nil i.image = nil
i.basePixels = nil i.basePixels = Pixels{}
i.drawTrianglesHistory = nil i.drawTrianglesHistory = nil
i.stale = false i.stale = false
} }