graphics: Keep pendingPixels not to read pixels from GPU unnecessarily

Fixes #947
This commit is contained in:
Hajime Hoshi 2019-10-05 00:02:52 +09:00
parent 7e7751bd43
commit 4c90674e17

View File

@ -92,7 +92,7 @@ func (i *Image) Fill(clr color.Color) error {
panic("ebiten: render to a subimage is not implemented (Fill)") panic("ebiten: render to a subimage is not implemented (Fill)")
} }
i.resolvePendingPixels(false) i.invalidatePendingPixels()
i.mipmap.fill(color.RGBAModel.Convert(clr).(color.RGBA)) i.mipmap.fill(color.RGBAModel.Convert(clr).(color.RGBA))
return nil return nil
@ -151,7 +151,7 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error {
} }
img.resolvePendingPixels(true) img.resolvePendingPixels(true)
i.resolvePendingPixels(true) i.resolvePendingPixels(false)
// 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).
@ -294,7 +294,7 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o
} }
img.resolvePendingPixels(true) img.resolvePendingPixels(true)
i.resolvePendingPixels(true) i.resolvePendingPixels(false)
if len(indices)%3 != 0 { if len(indices)%3 != 0 {
panic("ebiten: len(indices) % 3 must be 0") panic("ebiten: len(indices) % 3 must be 0")
@ -390,7 +390,8 @@ func (i *Image) At(x, y int) color.Color {
if i.isSubImage() && !image.Pt(x, y).In(i.bounds) { if i.isSubImage() && !image.Pt(x, y).In(i.bounds) {
return color.RGBA{} return color.RGBA{}
} }
i.resolvePendingPixels(true) // TODO: Use pending pixels
i.resolvePendingPixels(false)
r, g, b, a := i.mipmap.at(x, y) r, g, b, a := i.mipmap.at(x, y)
return color.RGBA{r, g, b, a} return color.RGBA{r, g, b, a}
} }
@ -437,9 +438,17 @@ func (img *Image) Set(x, y int, clr color.Color) {
img.pendingPixels[4*(x+y*w)+3] = byte(a >> 8) img.pendingPixels[4*(x+y*w)+3] = byte(a >> 8)
} }
func (i *Image) resolvePendingPixels(draw bool) { func (i *Image) invalidatePendingPixels() {
if i.isSubImage() { if i.isSubImage() {
i.original.resolvePendingPixels(draw) i.original.invalidatePendingPixels()
return
}
i.pendingPixels = nil
}
func (i *Image) resolvePendingPixels(keepPendingPixels bool) {
if i.isSubImage() {
i.original.resolvePendingPixels(keepPendingPixels)
return return
} }
@ -447,13 +456,10 @@ func (i *Image) resolvePendingPixels(draw bool) {
return return
} }
if !draw { i.mipmap.replacePixels(i.pendingPixels)
if !keepPendingPixels {
i.pendingPixels = nil i.pendingPixels = nil
return
} }
i.ReplacePixels(i.pendingPixels)
i.pendingPixels = nil
} }
// Dispose disposes the image data. After disposing, most of image functions do nothing and returns meaningless values. // Dispose disposes the image data. After disposing, most of image functions do nothing and returns meaningless values.
@ -474,7 +480,7 @@ func (i *Image) Dispose() error {
return nil return nil
} }
i.mipmap.dispose() i.mipmap.dispose()
i.resolvePendingPixels(false) i.invalidatePendingPixels()
return nil return nil
} }
@ -499,7 +505,7 @@ func (i *Image) ReplacePixels(p []byte) error {
if i.isSubImage() { if i.isSubImage() {
panic("ebiten: render to a subimage is not implemented (ReplacePixels)") panic("ebiten: render to a subimage is not implemented (ReplacePixels)")
} }
i.resolvePendingPixels(false) i.invalidatePendingPixels()
s := i.Bounds().Size() s := i.Bounds().Size()
if l := 4 * s.X * s.Y; len(p) != l { if l := 4 * s.X * s.Y; len(p) != l {
panic(fmt.Sprintf("ebiten: len(p) was %d but must be %d", len(p), l)) panic(fmt.Sprintf("ebiten: len(p) was %d but must be %d", len(p), l))