mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-27 03:02:49 +01:00
graphics: Refactoring: Reduce imageImpl's functions
This commit is contained in:
parent
76ad9cf42b
commit
16b0c9186e
37
image.go
37
image.go
@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/restorable"
|
||||||
)
|
)
|
||||||
|
|
||||||
func glContext() *opengl.Context {
|
func glContext() *opengl.Context {
|
||||||
@ -38,19 +39,19 @@ func glContext() *opengl.Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type images struct {
|
type images struct {
|
||||||
images map[*imageImpl]struct{}
|
images map[*restorable.Image]struct{}
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
lastChecked *imageImpl
|
lastChecked *imageImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
var theImagesForRestoring = images{
|
var theImagesForRestoring = images{
|
||||||
images: map[*imageImpl]struct{}{},
|
images: map[*restorable.Image]struct{}{},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *images) add(img *imageImpl) *Image {
|
func (i *images) add(img *imageImpl) *Image {
|
||||||
i.m.Lock()
|
i.m.Lock()
|
||||||
defer i.m.Unlock()
|
defer i.m.Unlock()
|
||||||
i.images[img] = struct{}{}
|
i.images[img.restorable] = struct{}{}
|
||||||
eimg := &Image{img}
|
eimg := &Image{img}
|
||||||
runtime.SetFinalizer(eimg, theImagesForRestoring.remove)
|
runtime.SetFinalizer(eimg, theImagesForRestoring.remove)
|
||||||
return eimg
|
return eimg
|
||||||
@ -62,7 +63,7 @@ func (i *images) remove(img *Image) {
|
|||||||
}
|
}
|
||||||
i.m.Lock()
|
i.m.Lock()
|
||||||
defer i.m.Unlock()
|
defer i.m.Unlock()
|
||||||
delete(i.images, img.impl)
|
delete(i.images, img.impl.restorable)
|
||||||
runtime.SetFinalizer(img, nil)
|
runtime.SetFinalizer(img, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,14 +72,14 @@ func (i *images) resolveStalePixels(context *opengl.Context) error {
|
|||||||
defer i.m.Unlock()
|
defer i.m.Unlock()
|
||||||
i.lastChecked = nil
|
i.lastChecked = nil
|
||||||
for img := range i.images {
|
for img := range i.images {
|
||||||
if err := img.resolveStalePixels(context); err != nil {
|
if err := img.ReadPixelsFromVRAMIfStale(context); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *images) resetPixelsIfDependingOn(target *Image, context *opengl.Context) {
|
func (i *images) resetPixelsIfDependingOn(target *Image) {
|
||||||
i.m.Lock()
|
i.m.Lock()
|
||||||
defer i.m.Unlock()
|
defer i.m.Unlock()
|
||||||
if i.lastChecked == target.impl {
|
if i.lastChecked == target.impl {
|
||||||
@ -89,7 +90,7 @@ func (i *images) resetPixelsIfDependingOn(target *Image, context *opengl.Context
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for img := range i.images {
|
for img := range i.images {
|
||||||
img.resetPixelsIfDependingOn(target.impl, context)
|
img.MakeStaleIfDependingOn(target.impl.restorable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,10 +99,10 @@ func (i *images) restore(context *opengl.Context) error {
|
|||||||
defer i.m.Unlock()
|
defer i.m.Unlock()
|
||||||
// Framebuffers/textures cannot be disposed since framebuffers/textures that
|
// Framebuffers/textures cannot be disposed since framebuffers/textures that
|
||||||
// don't belong to the current context.
|
// don't belong to the current context.
|
||||||
imagesWithoutDependency := []*imageImpl{}
|
imagesWithoutDependency := []*restorable.Image{}
|
||||||
imagesWithDependency := []*imageImpl{}
|
imagesWithDependency := []*restorable.Image{}
|
||||||
for img := range i.images {
|
for img := range i.images {
|
||||||
if img.hasDependency() {
|
if img.HasDependency() {
|
||||||
imagesWithDependency = append(imagesWithDependency, img)
|
imagesWithDependency = append(imagesWithDependency, img)
|
||||||
} else {
|
} else {
|
||||||
imagesWithoutDependency = append(imagesWithoutDependency, img)
|
imagesWithoutDependency = append(imagesWithoutDependency, img)
|
||||||
@ -109,12 +110,12 @@ func (i *images) restore(context *opengl.Context) error {
|
|||||||
}
|
}
|
||||||
// Images depending on other images should be processed first.
|
// Images depending on other images should be processed first.
|
||||||
for _, img := range imagesWithoutDependency {
|
for _, img := range imagesWithoutDependency {
|
||||||
if err := img.restore(context); err != nil {
|
if err := img.Restore(context); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, img := range imagesWithDependency {
|
for _, img := range imagesWithDependency {
|
||||||
if err := img.restore(context); err != nil {
|
if err := img.Restore(context); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,7 +126,7 @@ func (i *images) clearVolatileImages() {
|
|||||||
i.m.Lock()
|
i.m.Lock()
|
||||||
defer i.m.Unlock()
|
defer i.m.Unlock()
|
||||||
for img := range i.images {
|
for img := range i.images {
|
||||||
img.clearIfVolatile()
|
img.ClearIfVolatile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +150,7 @@ func (i *Image) Size() (width, height int) {
|
|||||||
//
|
//
|
||||||
// Clear always returns nil as of 1.5.0-alpha.
|
// Clear always returns nil as of 1.5.0-alpha.
|
||||||
func (i *Image) Clear() error {
|
func (i *Image) Clear() error {
|
||||||
theImagesForRestoring.resetPixelsIfDependingOn(i, glContext())
|
theImagesForRestoring.resetPixelsIfDependingOn(i)
|
||||||
i.impl.Fill(color.Transparent)
|
i.impl.Fill(color.Transparent)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -160,7 +161,7 @@ func (i *Image) Clear() error {
|
|||||||
//
|
//
|
||||||
// Fill always returns nil as of 1.5.0-alpha.
|
// Fill always returns nil as of 1.5.0-alpha.
|
||||||
func (i *Image) Fill(clr color.Color) error {
|
func (i *Image) Fill(clr color.Color) error {
|
||||||
theImagesForRestoring.resetPixelsIfDependingOn(i, glContext())
|
theImagesForRestoring.resetPixelsIfDependingOn(i)
|
||||||
i.impl.Fill(clr)
|
i.impl.Fill(clr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -188,7 +189,7 @@ func (i *Image) Fill(clr color.Color) error {
|
|||||||
//
|
//
|
||||||
// DrawImage always returns nil as of 1.5.0-alpha.
|
// DrawImage always returns nil as of 1.5.0-alpha.
|
||||||
func (i *Image) DrawImage(image *Image, options *DrawImageOptions) error {
|
func (i *Image) DrawImage(image *Image, options *DrawImageOptions) error {
|
||||||
theImagesForRestoring.resetPixelsIfDependingOn(i, glContext())
|
theImagesForRestoring.resetPixelsIfDependingOn(i)
|
||||||
i.impl.DrawImage(image, options)
|
i.impl.DrawImage(image, options)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -225,7 +226,7 @@ func (i *Image) Dispose() error {
|
|||||||
if i.impl.isDisposed() {
|
if i.impl.isDisposed() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
theImagesForRestoring.resetPixelsIfDependingOn(i, glContext())
|
theImagesForRestoring.resetPixelsIfDependingOn(i)
|
||||||
i.impl.Dispose()
|
i.impl.Dispose()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -242,7 +243,7 @@ func (i *Image) Dispose() error {
|
|||||||
//
|
//
|
||||||
// ReplacePixels always returns nil as of 1.5.0-alpha.
|
// ReplacePixels always returns nil as of 1.5.0-alpha.
|
||||||
func (i *Image) ReplacePixels(p []uint8) error {
|
func (i *Image) ReplacePixels(p []uint8) error {
|
||||||
theImagesForRestoring.resetPixelsIfDependingOn(i, glContext())
|
theImagesForRestoring.resetPixelsIfDependingOn(i)
|
||||||
i.impl.ReplacePixels(p)
|
i.impl.ReplacePixels(p)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
59
imageimpl.go
59
imageimpl.go
@ -74,15 +74,6 @@ func (i *imageImpl) Fill(clr color.Color) {
|
|||||||
i.restorable.Fill(rgba)
|
i.restorable.Fill(rgba)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageImpl) clearIfVolatile() {
|
|
||||||
i.m.Lock()
|
|
||||||
defer i.m.Unlock()
|
|
||||||
if i.restorable == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
i.restorable.ClearIfVolatile()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) {
|
func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) {
|
||||||
// Calculate vertices before locking because the user can do anything in
|
// Calculate vertices before locking because the user can do anything in
|
||||||
// options.ImageParts interface without deadlock (e.g. Call Image functions).
|
// options.ImageParts interface without deadlock (e.g. Call Image functions).
|
||||||
@ -134,56 +125,6 @@ func (i *imageImpl) At(x, y int, context *opengl.Context) color.Color {
|
|||||||
return clr
|
return clr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageImpl) resolveStalePixels(context *opengl.Context) error {
|
|
||||||
i.m.Lock()
|
|
||||||
defer i.m.Unlock()
|
|
||||||
if i.restorable == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if err := i.restorable.ReadPixelsFromVRAMIfStale(context); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *imageImpl) resetPixelsIfDependingOn(target *imageImpl, context *opengl.Context) {
|
|
||||||
i.m.Lock()
|
|
||||||
defer i.m.Unlock()
|
|
||||||
if i == target {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if i.restorable == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if target.isDisposed() {
|
|
||||||
panic("ebiten: target must not be disposed")
|
|
||||||
}
|
|
||||||
// target is an image that is about to be tried mutating.
|
|
||||||
// If pixels object is related to that image, the pixels must be reset.
|
|
||||||
i.restorable.MakeStaleIfDependingOn(target.restorable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *imageImpl) hasDependency() bool {
|
|
||||||
i.m.Lock()
|
|
||||||
defer i.m.Unlock()
|
|
||||||
if i.restorable == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return i.restorable.HasDependency()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *imageImpl) restore(context *opengl.Context) error {
|
|
||||||
i.m.Lock()
|
|
||||||
defer i.m.Unlock()
|
|
||||||
if i.restorable == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if err := i.restorable.Restore(context); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *imageImpl) Dispose() {
|
func (i *imageImpl) Dispose() {
|
||||||
i.m.Lock()
|
i.m.Lock()
|
||||||
defer i.m.Unlock()
|
defer i.m.Unlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user