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
}
// 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) {
// TODO: Clearing is not needed when the image is for only ReplacePixels.
clearImage(img)
if p.rectToPixels == nil {
clearImage(img)
return
}
@ -77,14 +81,13 @@ type drawTrianglesHistoryItem struct {
type Image struct {
image *graphicscommand.Image
basePixels *Pixels
basePixels Pixels
// drawTrianglesHistory is a set of draw-image commands.
// TODO: This should be merged with the similar command queue in package graphics (#433).
drawTrianglesHistory []*drawTrianglesHistoryItem
// 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
// volatile indicates whether the image is cleared whenever a frame starts.
@ -125,7 +128,7 @@ func NewImage(width, height int) *Image {
i := &Image{
image: graphicscommand.NewImage(width, height),
}
i.clearForInitialization()
i.clear()
theImages.add(i)
return i
}
@ -178,7 +181,7 @@ func NewScreenFramebufferImage(width, height int) *Image {
image: graphicscommand.NewScreenFramebufferImage(width, height),
screen: true,
}
i.clearForInitialization()
i.clear()
theImages.add(i)
return i
}
@ -188,12 +191,6 @@ func (i *Image) 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.
// This does nothing to do with a restorable.Image's rendering state.
func clearImage(img *graphicscommand.Image) {
@ -232,7 +229,7 @@ func (i *Image) clear() {
//
// After ResetRestoringState, the image is assumed to be cleared.
func (i *Image) ResetRestoringState() {
i.basePixels = &Pixels{}
i.basePixels = Pixels{}
i.drawTrianglesHistory = nil
i.stale = false
}
@ -243,7 +240,7 @@ func (i *Image) IsVolatile() bool {
// BasePixelsForTesting returns the image's basePixels for testing.
func (i *Image) BasePixelsForTesting() *Pixels {
return i.basePixels
return &i.basePixels
}
// 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.
func (i *Image) makeStale() {
i.basePixels = nil
i.basePixels = Pixels{}
i.drawTrianglesHistory = nil
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 i.basePixels == nil {
i.basePixels = &Pixels{}
}
if pixels != nil {
i.basePixels.AddOrReplace(pixels, 0, 0, w, h)
} else {
@ -347,9 +341,6 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
return
}
if i.basePixels == nil {
i.basePixels = &Pixels{}
}
if pixels != nil {
i.basePixels.AddOrReplace(pixels, x, y, width, height)
} else {
@ -401,7 +392,7 @@ func (i *Image) appendDrawTrianglesHistory(image *Image, vertices []float32, ind
}
func (i *Image) readPixelsFromGPUIfNeeded() {
if i.basePixels == nil || len(i.drawTrianglesHistory) > 0 || i.stale {
if len(i.drawTrianglesHistory) > 0 || i.stale {
graphicscommand.FlushCommands()
i.readPixelsFromGPU()
i.drawTrianglesHistory = nil
@ -420,11 +411,6 @@ func (i *Image) At(x, y int) (byte, byte, byte, byte) {
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)
}
@ -441,7 +427,7 @@ func (i *Image) makeStaleIfDependingOn(target *Image) {
// readPixelsFromGPU reads the pixels from GPU and resolves the image's 'stale' state.
func (i *Image) readPixelsFromGPU() {
w, h := i.Size()
i.basePixels = &Pixels{}
i.basePixels = Pixels{}
i.basePixels.AddOrReplace(i.image.Pixels(), 0, 0, w, h)
i.drawTrianglesHistory = nil
i.stale = false
@ -499,14 +485,14 @@ func (i *Image) restore() error {
// The screen image should also be recreated because framebuffer might
// be changed.
i.image = graphicscommand.NewScreenFramebufferImage(w, h)
i.basePixels = nil
i.basePixels = Pixels{}
i.drawTrianglesHistory = nil
i.stale = false
return nil
}
if i.volatile {
i.image = graphicscommand.NewImage(w, h)
i.clearForInitialization()
i.clear()
return nil
}
if i.stale {
@ -515,11 +501,8 @@ func (i *Image) restore() error {
}
gimg := graphicscommand.NewImage(w, h)
// Clear the image explicitly.
clearImage(gimg)
if i.basePixels != nil {
i.basePixels.Apply(gimg)
}
// gimg is not initialized (by clearing), but Apply should work.
i.basePixels.Apply(gimg)
for _, c := range i.drawTrianglesHistory {
if c.image.hasDependency() {
@ -529,7 +512,7 @@ func (i *Image) restore() error {
}
if len(i.drawTrianglesHistory) > 0 {
i.basePixels = &Pixels{}
i.basePixels = Pixels{}
i.basePixels.AddOrReplace(gimg.Pixels(), 0, 0, w, h)
}
@ -547,7 +530,7 @@ func (i *Image) Dispose() {
i.image.Dispose()
i.image = nil
i.basePixels = nil
i.basePixels = Pixels{}
i.drawTrianglesHistory = nil
i.stale = false
}