mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-11 19:48:54 +01:00
internal/buffer: remove the graphics-driver argument from ReplacePartialRegionPixels
This is necessary to remove the graphics driver usage from (*ebiten.Image).At. And this is necessary to determine the graphics driver after the window becomes transparent or not. Unfortunately, it is not obvious to make a transparent window with DirectX. Then, the determination of a graphics driver should be delayed. Updates #1007
This commit is contained in:
parent
4f070915b2
commit
29f7a45ccc
@ -30,6 +30,7 @@ type Image struct {
|
|||||||
height int
|
height int
|
||||||
|
|
||||||
pixels []byte
|
pixels []byte
|
||||||
|
mask []byte
|
||||||
needsToResolvePixels bool
|
needsToResolvePixels bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,6 +113,7 @@ func (i *Image) initializeAsScreenFramebuffer(width, height int) {
|
|||||||
|
|
||||||
func (i *Image) invalidatePendingPixels() {
|
func (i *Image) invalidatePendingPixels() {
|
||||||
i.pixels = nil
|
i.pixels = nil
|
||||||
|
i.mask = nil
|
||||||
i.needsToResolvePixels = false
|
i.needsToResolvePixels = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,9 +122,10 @@ func (i *Image) resolvePendingPixels(keepPendingPixels bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
i.img.ReplacePixels(i.pixels, nil)
|
i.img.ReplacePixels(i.pixels, i.mask)
|
||||||
if !keepPendingPixels {
|
if !keepPendingPixels || i.mask != nil {
|
||||||
i.pixels = nil
|
i.pixels = nil
|
||||||
|
i.mask = nil
|
||||||
}
|
}
|
||||||
i.needsToResolvePixels = false
|
i.needsToResolvePixels = false
|
||||||
}
|
}
|
||||||
@ -140,28 +143,29 @@ func (i *Image) MarkDisposed() {
|
|||||||
i.img.MarkDisposed()
|
i.img.MarkDisposed()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) ensurePixels(graphicsDriver graphicsdriver.Graphics) error {
|
|
||||||
if i.pixels != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
pix, err := i.img.Pixels(graphicsDriver)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
i.pixels = pix
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (img *Image) At(graphicsDriver graphicsdriver.Graphics, x, y int) (r, g, b, a byte, err error) {
|
func (img *Image) At(graphicsDriver graphicsdriver.Graphics, x, y int) (r, g, b, a byte, err error) {
|
||||||
checkDelayedCommandsFlushed("At")
|
checkDelayedCommandsFlushed("At")
|
||||||
|
|
||||||
if err := img.ensurePixels(graphicsDriver); err != nil {
|
idx := (y*img.width + x)
|
||||||
return 0, 0, 0, 0, err
|
if img.pixels != nil {
|
||||||
|
if img.mask == nil {
|
||||||
|
return img.pixels[4*idx], img.pixels[4*idx+1], img.pixels[4*idx+2], img.pixels[4*idx+3], nil
|
||||||
|
}
|
||||||
|
if img.mask[idx/8]<<(idx%8)&1 != 0 {
|
||||||
|
return img.pixels[4*idx], img.pixels[4*idx+1], img.pixels[4*idx+2], img.pixels[4*idx+3], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
idx := 4 * (y*img.width + x)
|
img.resolvePendingPixels(false)
|
||||||
return img.pixels[idx], img.pixels[idx+1], img.pixels[idx+2], img.pixels[idx+3], nil
|
}
|
||||||
|
|
||||||
|
pix, err := img.img.Pixels(graphicsDriver)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, 0, 0, err
|
||||||
|
}
|
||||||
|
img.pixels = pix
|
||||||
|
// When pixels represents the whole pixels, the mask is not needed.
|
||||||
|
img.mask = nil
|
||||||
|
return img.pixels[4*idx], img.pixels[4*idx+1], img.pixels[4*idx+2], img.pixels[4*idx+3], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) DumpScreenshot(graphicsDriver graphicsdriver.Graphics, name string, blackbg bool) error {
|
func (i *Image) DumpScreenshot(graphicsDriver graphicsdriver.Graphics, name string, blackbg bool) error {
|
||||||
@ -194,7 +198,7 @@ func (i *Image) ReplacePixels(pix []byte) {
|
|||||||
|
|
||||||
// ReplacePartial replaces the pixel at the specified partial region.
|
// ReplacePartial replaces the pixel at the specified partial region.
|
||||||
// This call might be accumulated and send one draw call to replace pixels for the accumulated calls.
|
// This call might be accumulated and send one draw call to replace pixels for the accumulated calls.
|
||||||
func (i *Image) ReplacePartialPixels(graphicsDriver graphicsdriver.Graphics, pix []byte, x, y, width, height int) error {
|
func (i *Image) ReplacePartialPixels(pix []byte, x, y, width, height int) {
|
||||||
if l := 4 * width * height; len(pix) != l {
|
if l := 4 * width * height; len(pix) != l {
|
||||||
panic(fmt.Sprintf("buffered: len(pix) was %d but must be %d", len(pix), l))
|
panic(fmt.Sprintf("buffered: len(pix) was %d but must be %d", len(pix), l))
|
||||||
}
|
}
|
||||||
@ -203,26 +207,38 @@ func (i *Image) ReplacePartialPixels(graphicsDriver graphicsdriver.Graphics, pix
|
|||||||
if tryAddDelayedCommand(func() error {
|
if tryAddDelayedCommand(func() error {
|
||||||
copied := make([]byte, len(pix))
|
copied := make([]byte, len(pix))
|
||||||
copy(copied, pix)
|
copy(copied, pix)
|
||||||
i.ReplacePartialPixels(graphicsDriver, copied, x, y, width, height)
|
i.ReplacePartialPixels(copied, x, y, width, height)
|
||||||
return nil
|
return nil
|
||||||
}) {
|
}) {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := i.ensurePixels(graphicsDriver); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
i.replacePendingPixels(pix, x, y, width, height)
|
i.replacePendingPixels(pix, x, y, width, height)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) replacePendingPixels(pix []byte, x, y, width, height int) {
|
func (img *Image) replacePendingPixels(pix []byte, x, y, width, height int) {
|
||||||
for j := 0; j < height; j++ {
|
if img.pixels == nil {
|
||||||
copy(i.pixels[4*((j+y)*i.width+x):], pix[4*j*width:4*(j+1)*width])
|
img.pixels = make([]byte, 4*img.width*img.height)
|
||||||
|
if img.mask == nil {
|
||||||
|
img.mask = make([]byte, (img.width*img.height-1)/8+1)
|
||||||
}
|
}
|
||||||
i.needsToResolvePixels = true
|
}
|
||||||
|
for j := 0; j < height; j++ {
|
||||||
|
copy(img.pixels[4*((j+y)*img.width+x):], pix[4*j*width:4*(j+1)*width])
|
||||||
|
}
|
||||||
|
|
||||||
|
// A mask is created only when a partial regions are replaced by replacePendingPixels.
|
||||||
|
if img.mask != nil {
|
||||||
|
for j := 0; j < height; j++ {
|
||||||
|
for i := 0; i < width; i++ {
|
||||||
|
idx := (y+j)*img.width + x + i
|
||||||
|
img.mask[idx/8] |= 1 << (idx % 8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img.needsToResolvePixels = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// DrawTriangles draws the src image with the given vertices.
|
// DrawTriangles draws the src image with the given vertices.
|
||||||
|
@ -76,12 +76,9 @@ func (m *Mipmap) ReplacePixels(pix []byte) {
|
|||||||
m.disposeMipmaps()
|
m.disposeMipmaps()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mipmap) ReplacePartialPixels(graphicsDriver graphicsdriver.Graphics, pix []byte, x, y, width, height int) error {
|
func (m *Mipmap) ReplacePartialPixels(pix []byte, x, y, width, height int) {
|
||||||
if err := m.orig.ReplacePartialPixels(graphicsDriver, pix, x, y, width, height); err != nil {
|
m.orig.ReplacePartialPixels(pix, x, y, width, height)
|
||||||
return err
|
|
||||||
}
|
|
||||||
m.disposeMipmaps()
|
m.disposeMipmaps()
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mipmap) At(graphicsDriver graphicsdriver.Graphics, x, y int) (r, g, b, a byte, err error) {
|
func (m *Mipmap) At(graphicsDriver graphicsdriver.Graphics, x, y int) (r, g, b, a byte, err error) {
|
||||||
|
@ -73,12 +73,7 @@ func (i *Image) ReplacePixels(pix []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) ReplacePartialPixels(pix []byte, x, y, width, height int) {
|
func (i *Image) ReplacePartialPixels(pix []byte, x, y, width, height int) {
|
||||||
if theGlobalState.error() != nil {
|
i.mipmap.ReplacePartialPixels(pix, x, y, width, height)
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := i.mipmap.ReplacePartialPixels(graphicsDriver(), pix, x, y, width, height); err != nil {
|
|
||||||
theGlobalState.setError(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) At(x, y int) (r, g, b, a byte) {
|
func (i *Image) At(x, y int) (r, g, b, a byte) {
|
||||||
|
Loading…
Reference in New Issue
Block a user