mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 02:42:02 +01:00
internal/restorable: use sparate regions instead of a big unified region
This commit is contained in:
parent
09e0320309
commit
aca42e4046
@ -64,11 +64,11 @@ func (p *Pixels) ReadPixels(pixels []byte, x, y, width, height, imageWidth, imag
|
|||||||
p.pixelsRecords.readPixels(pixels, x, y, width, height, imageWidth, imageHeight)
|
p.pixelsRecords.readPixels(pixels, x, y, width, height, imageWidth, imageHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pixels) Region() image.Rectangle {
|
func (p *Pixels) AppendRegion(regions []image.Rectangle) []image.Rectangle {
|
||||||
if p.pixelsRecords == nil {
|
if p.pixelsRecords == nil {
|
||||||
return image.Rectangle{}
|
return regions
|
||||||
}
|
}
|
||||||
return p.pixelsRecords.region()
|
return p.pixelsRecords.appendRegions(regions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// drawTrianglesHistoryItem is an item for history of draw-image commands.
|
// drawTrianglesHistoryItem is an item for history of draw-image commands.
|
||||||
@ -119,9 +119,9 @@ type Image struct {
|
|||||||
// 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.
|
||||||
stale bool
|
stale bool
|
||||||
|
|
||||||
// staleRegion indicates the region to restore.
|
// staleRegions indicates the regions to restore.
|
||||||
// staleRegion is valid only when stale is true.
|
// staleRegions is valid only when stale is true.
|
||||||
staleRegion image.Rectangle
|
staleRegions []image.Rectangle
|
||||||
|
|
||||||
imageType ImageType
|
imageType ImageType
|
||||||
|
|
||||||
@ -208,7 +208,8 @@ func (i *Image) Extend(width, height int) *Image {
|
|||||||
newImg.clearDrawTrianglesHistory()
|
newImg.clearDrawTrianglesHistory()
|
||||||
newImg.basePixels = i.basePixels
|
newImg.basePixels = i.basePixels
|
||||||
newImg.stale = i.stale
|
newImg.stale = i.stale
|
||||||
newImg.staleRegion = i.staleRegion
|
newImg.staleRegions = make([]image.Rectangle, len(i.staleRegions))
|
||||||
|
copy(newImg.staleRegions, i.staleRegions)
|
||||||
|
|
||||||
i.Dispose()
|
i.Dispose()
|
||||||
|
|
||||||
@ -260,13 +261,11 @@ func (i *Image) BasePixelsForTesting() *Pixels {
|
|||||||
func (i *Image) makeStale(rect image.Rectangle) {
|
func (i *Image) makeStale(rect image.Rectangle) {
|
||||||
i.stale = true
|
i.stale = true
|
||||||
|
|
||||||
r := i.staleRegion
|
i.staleRegions = i.basePixels.AppendRegion(i.staleRegions)
|
||||||
r = r.Union(i.basePixels.Region())
|
i.staleRegions = i.appendRegionsForDrawTriangles(i.staleRegions)
|
||||||
for _, d := range i.drawTrianglesHistory {
|
if !rect.Empty() {
|
||||||
r = r.Union(regionToRectangle(d.dstRegion))
|
i.staleRegions = append(i.staleRegions, rect)
|
||||||
}
|
}
|
||||||
r = r.Union(rect)
|
|
||||||
i.staleRegion = r
|
|
||||||
|
|
||||||
i.basePixels = Pixels{}
|
i.basePixels = Pixels{}
|
||||||
i.clearDrawTrianglesHistory()
|
i.clearDrawTrianglesHistory()
|
||||||
@ -329,7 +328,7 @@ func (i *Image) WritePixels(pixels []byte, x, y, width, height int) {
|
|||||||
}
|
}
|
||||||
i.clearDrawTrianglesHistory()
|
i.clearDrawTrianglesHistory()
|
||||||
i.stale = false
|
i.stale = false
|
||||||
i.staleRegion = image.Rectangle{}
|
i.staleRegions = i.staleRegions[:0]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,16 +482,19 @@ func (i *Image) makeStaleIfDependingOnShader(shader *Shader) {
|
|||||||
|
|
||||||
// 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(graphicsDriver graphicsdriver.Graphics) error {
|
func (i *Image) readPixelsFromGPU(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
var r image.Rectangle
|
var rs []image.Rectangle
|
||||||
if i.stale {
|
if i.stale {
|
||||||
i.basePixels = Pixels{}
|
i.basePixels = Pixels{}
|
||||||
r = i.staleRegion
|
rs = append(rs, i.staleRegions...)
|
||||||
} else {
|
} else {
|
||||||
for _, d := range i.drawTrianglesHistory {
|
rs = i.appendRegionsForDrawTriangles(rs)
|
||||||
r = r.Union(regionToRectangle(d.dstRegion))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !r.Empty() {
|
|
||||||
|
for _, r := range rs {
|
||||||
|
if r.Empty() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
pix := make([]byte, 4*r.Dx()*r.Dy())
|
pix := make([]byte, 4*r.Dx()*r.Dy())
|
||||||
if err := i.image.ReadPixels(graphicsDriver, pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil {
|
if err := i.image.ReadPixels(graphicsDriver, pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -501,7 +503,7 @@ func (i *Image) readPixelsFromGPU(graphicsDriver graphicsdriver.Graphics) error
|
|||||||
}
|
}
|
||||||
i.clearDrawTrianglesHistory()
|
i.clearDrawTrianglesHistory()
|
||||||
i.stale = false
|
i.stale = false
|
||||||
i.staleRegion = image.Rectangle{}
|
i.staleRegions = i.staleRegions[:0]
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,7 +581,7 @@ func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
|
|||||||
i.basePixels = Pixels{}
|
i.basePixels = Pixels{}
|
||||||
i.clearDrawTrianglesHistory()
|
i.clearDrawTrianglesHistory()
|
||||||
i.stale = false
|
i.stale = false
|
||||||
i.staleRegion = image.Rectangle{}
|
i.staleRegions = i.staleRegions[:0]
|
||||||
return nil
|
return nil
|
||||||
case ImageTypeVolatile:
|
case ImageTypeVolatile:
|
||||||
i.image = graphicscommand.NewImage(w, h, false)
|
i.image = graphicscommand.NewImage(w, h, false)
|
||||||
@ -617,21 +619,7 @@ func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
|
|||||||
// In order to clear the draw-triangles history, read pixels from GPU.
|
// In order to clear the draw-triangles history, read pixels from GPU.
|
||||||
if len(i.drawTrianglesHistory) > 0 {
|
if len(i.drawTrianglesHistory) > 0 {
|
||||||
var rs []image.Rectangle
|
var rs []image.Rectangle
|
||||||
for _, d := range i.drawTrianglesHistory {
|
rs = i.appendRegionsForDrawTriangles(rs)
|
||||||
r := regionToRectangle(d.dstRegion)
|
|
||||||
if r.Empty() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for i, rr := range rs {
|
|
||||||
if rr.Empty() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if rr.In(r) {
|
|
||||||
rs[i] = image.Rectangle{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rs = append(rs, r)
|
|
||||||
}
|
|
||||||
for _, r := range rs {
|
for _, r := range rs {
|
||||||
if r.Empty() {
|
if r.Empty() {
|
||||||
continue
|
continue
|
||||||
@ -647,7 +635,7 @@ func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
|
|||||||
i.image = gimg
|
i.image = gimg
|
||||||
i.clearDrawTrianglesHistory()
|
i.clearDrawTrianglesHistory()
|
||||||
i.stale = false
|
i.stale = false
|
||||||
i.staleRegion = image.Rectangle{}
|
i.staleRegions = i.staleRegions[:0]
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,7 +649,7 @@ func (i *Image) Dispose() {
|
|||||||
i.basePixels = Pixels{}
|
i.basePixels = Pixels{}
|
||||||
i.clearDrawTrianglesHistory()
|
i.clearDrawTrianglesHistory()
|
||||||
i.stale = false
|
i.stale = false
|
||||||
i.staleRegion = image.Rectangle{}
|
i.staleRegions = i.staleRegions[:0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// isInvalidated returns a boolean value indicating whether the image is invalidated.
|
// isInvalidated returns a boolean value indicating whether the image is invalidated.
|
||||||
@ -688,6 +676,32 @@ func (i *Image) InternalSize() (int, int) {
|
|||||||
return i.image.InternalSize()
|
return i.image.InternalSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *Image) appendRegionsForDrawTriangles(regions []image.Rectangle) []image.Rectangle {
|
||||||
|
var rs []image.Rectangle
|
||||||
|
for _, d := range i.drawTrianglesHistory {
|
||||||
|
r := regionToRectangle(d.dstRegion)
|
||||||
|
if r.Empty() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for i, rr := range rs {
|
||||||
|
if rr.Empty() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if rr.In(r) {
|
||||||
|
rs[i] = image.Rectangle{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rs = append(rs, r)
|
||||||
|
}
|
||||||
|
for _, r := range rs {
|
||||||
|
if r.Empty() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
regions = append(regions, r)
|
||||||
|
}
|
||||||
|
return regions
|
||||||
|
}
|
||||||
|
|
||||||
func regionToRectangle(region graphicsdriver.Region) image.Rectangle {
|
func regionToRectangle(region graphicsdriver.Region) image.Rectangle {
|
||||||
return image.Rect(
|
return image.Rect(
|
||||||
int(math.Floor(float64(region.X))),
|
int(math.Floor(float64(region.X))),
|
||||||
|
@ -129,10 +129,12 @@ func (pr *pixelsRecords) apply(img *graphicscommand.Image) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *pixelsRecords) region() image.Rectangle {
|
func (pr *pixelsRecords) appendRegions(regions []image.Rectangle) []image.Rectangle {
|
||||||
var rect image.Rectangle
|
|
||||||
for _, r := range pr.records {
|
for _, r := range pr.records {
|
||||||
rect = rect.Union(r.rect)
|
if r.rect.Empty() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
regions = append(regions, r.rect)
|
||||||
}
|
}
|
||||||
return rect
|
return regions
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user