pixels: Add 'stale' member

This commit is contained in:
Hajime Hoshi 2016-07-27 02:16:31 +09:00
parent c18756352d
commit 56732d9a23
2 changed files with 30 additions and 22 deletions

View File

@ -113,9 +113,6 @@ func (i *imageImpl) Fill(clr color.Color) error {
if i.disposed { if i.disposed {
return errors.New("ebiten: image is already disposed") return errors.New("ebiten: image is already disposed")
} }
if i.pixels == nil {
i.pixels = pixels.NewPixels(i.image)
}
i.pixels.Fill(clr) i.pixels.Fill(clr)
return i.image.Fill(clr) return i.image.Fill(clr)
} }
@ -129,9 +126,6 @@ func (i *imageImpl) clearIfVolatile() error {
if !i.volatile { if !i.volatile {
return nil return nil
} }
if i.pixels == nil {
i.pixels = pixels.NewPixels(i.image)
}
i.pixels.Clear() i.pixels.Clear()
return i.image.Fill(color.Transparent) return i.image.Fill(color.Transparent)
} }
@ -170,9 +164,7 @@ func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error {
geom := options.GeoM geom := options.GeoM
colorm := options.ColorM colorm := options.ColorM
mode := opengl.CompositeMode(options.CompositeMode) mode := opengl.CompositeMode(options.CompositeMode)
if i.pixels != nil {
i.pixels.AppendDrawImageHistory(image.impl.image, vertices, &geom, &colorm, mode) i.pixels.AppendDrawImageHistory(image.impl.image, vertices, &geom, &colorm, mode)
}
if err := i.image.DrawImage(image.impl.image, vertices, &geom, &colorm, mode); err != nil { if err := i.image.DrawImage(image.impl.image, vertices, &geom, &colorm, mode); err != nil {
return err return err
} }
@ -202,10 +194,9 @@ func (i *imageImpl) ensurePixels(context *opengl.Context) error {
if i.disposed { if i.disposed {
return nil return nil
} }
if i.pixels != nil { if !i.pixels.IsStale() {
return nil return nil
} }
i.pixels = pixels.NewPixels(i.image)
if err := i.pixels.Reset(context); err != nil { if err := i.pixels.Reset(context); err != nil {
return err return err
} }
@ -224,9 +215,6 @@ func (i *imageImpl) resetPixelsIfDependingOn(target *imageImpl, context *opengl.
if target.isDisposed() { if target.isDisposed() {
return errors.New("ebiten: target is already disposed") return errors.New("ebiten: target is already disposed")
} }
if i.pixels == nil {
return nil
}
// target is an image begin tried to mutate. // target is an image begin tried to mutate.
// If pixels object is related to that image, the pixels must be reset. // If pixels object is related to that image, the pixels must be reset.
if !i.pixels.DependsOn(target.image) { if !i.pixels.DependsOn(target.image) {
@ -234,7 +222,7 @@ func (i *imageImpl) resetPixelsIfDependingOn(target *imageImpl, context *opengl.
} }
if context == nil { if context == nil {
// context is nil when this is not initialized yet. // context is nil when this is not initialized yet.
i.pixels = nil i.pixels.MakeStale()
return nil return nil
} }
if err := i.pixels.Reset(context); err != nil { if err := i.pixels.Reset(context); err != nil {
@ -246,9 +234,6 @@ func (i *imageImpl) resetPixelsIfDependingOn(target *imageImpl, context *opengl.
func (i *imageImpl) hasDependency() bool { func (i *imageImpl) hasDependency() bool {
i.m.Lock() i.m.Lock()
defer i.m.Unlock() defer i.m.Unlock()
if i.pixels == nil {
return false
}
return i.pixels.HasDependency() return i.pixels.HasDependency()
} }
@ -308,9 +293,6 @@ func (i *imageImpl) ReplacePixels(p []uint8) error {
} }
i.m.Lock() i.m.Lock()
defer i.m.Unlock() defer i.m.Unlock()
if i.pixels == nil {
i.pixels = pixels.NewPixels(i.image)
}
i.pixels.ReplacePixels(p) i.pixels.ReplacePixels(p)
if i.disposed { if i.disposed {
return errors.New("ebiten: image is already disposed") return errors.New("ebiten: image is already disposed")

View File

@ -38,6 +38,7 @@ type Pixels struct {
basePixels []uint8 basePixels []uint8
baseColor color.Color baseColor color.Color
drawImageHistory []*drawImageHistoryItem drawImageHistory []*drawImageHistoryItem
stale bool
} }
func NewPixels(image *graphics.Image) *Pixels { func NewPixels(image *graphics.Image) *Pixels {
@ -46,16 +47,29 @@ func NewPixels(image *graphics.Image) *Pixels {
} }
} }
func (p *Pixels) IsStale() bool {
return p.stale
}
func (p *Pixels) MakeStale() {
p.basePixels = nil
p.baseColor = nil
p.drawImageHistory = nil
p.stale = true
}
func (p *Pixels) Clear() { func (p *Pixels) Clear() {
p.basePixels = nil p.basePixels = nil
p.baseColor = nil p.baseColor = nil
p.drawImageHistory = nil p.drawImageHistory = nil
p.stale = false
} }
func (p *Pixels) Fill(clr color.Color) { func (p *Pixels) Fill(clr color.Color) {
p.basePixels = nil p.basePixels = nil
p.baseColor = clr p.baseColor = clr
p.drawImageHistory = nil p.drawImageHistory = nil
p.stale = false
} }
func (p *Pixels) ReplacePixels(pixels []uint8) { func (p *Pixels) ReplacePixels(pixels []uint8) {
@ -65,9 +79,13 @@ func (p *Pixels) ReplacePixels(pixels []uint8) {
copy(p.basePixels, pixels) copy(p.basePixels, pixels)
p.baseColor = nil p.baseColor = nil
p.drawImageHistory = nil p.drawImageHistory = nil
p.stale = false
} }
func (p *Pixels) AppendDrawImageHistory(image *graphics.Image, vertices []int16, geom graphics.Matrix, colorm graphics.Matrix, mode opengl.CompositeMode) { func (p *Pixels) AppendDrawImageHistory(image *graphics.Image, vertices []int16, geom graphics.Matrix, colorm graphics.Matrix, mode opengl.CompositeMode) {
if p.stale {
return
}
item := &drawImageHistoryItem{ item := &drawImageHistoryItem{
image: image, image: image,
vertices: vertices, vertices: vertices,
@ -83,7 +101,7 @@ func (p *Pixels) AppendDrawImageHistory(image *graphics.Image, vertices []int16,
// Note that this must not be called until context is available. // Note that this must not be called until context is available.
// This means Pixels members must match with acutal state in GPU. // This means Pixels members must match with acutal state in GPU.
func (p *Pixels) At(idx int, context *opengl.Context) (color.Color, error) { func (p *Pixels) At(idx int, context *opengl.Context) (color.Color, error) {
if p.basePixels == nil || p.drawImageHistory != nil { if p.basePixels == nil || p.drawImageHistory != nil || p.stale {
if err := p.Reset(context); err != nil { if err := p.Reset(context); err != nil {
return nil, err return nil, err
} }
@ -93,6 +111,9 @@ func (p *Pixels) At(idx int, context *opengl.Context) (color.Color, error) {
} }
func (p *Pixels) DependsOn(target *graphics.Image) bool { func (p *Pixels) DependsOn(target *graphics.Image) bool {
if p.stale {
return false
}
for _, c := range p.drawImageHistory { for _, c := range p.drawImageHistory {
if c.image == target { if c.image == target {
return true return true
@ -109,10 +130,14 @@ func (p *Pixels) Reset(context *opengl.Context) error {
} }
p.baseColor = nil p.baseColor = nil
p.drawImageHistory = nil p.drawImageHistory = nil
p.stale = false
return nil return nil
} }
func (p *Pixels) HasDependency() bool { func (p *Pixels) HasDependency() bool {
if p.stale {
return false
}
return p.drawImageHistory != nil return p.drawImageHistory != nil
} }
@ -153,5 +178,6 @@ func (p *Pixels) Restore(context *opengl.Context, width, height int, filter open
} }
p.baseColor = nil p.baseColor = nil
p.drawImageHistory = nil p.drawImageHistory = nil
p.stale = false
return gimg, nil return gimg, nil
} }