mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
internal/graphicsdriver: replace Pixels with ReadPixels
Now preparing a byte slice is the caller's responsibility.
This commit is contained in:
parent
1cb7633ff6
commit
b22309a0e5
@ -605,11 +605,9 @@ type pixelsCommand struct {
|
|||||||
|
|
||||||
// Exec executes a pixelsCommand.
|
// Exec executes a pixelsCommand.
|
||||||
func (c *pixelsCommand) Exec(indexOffset int) error {
|
func (c *pixelsCommand) Exec(indexOffset int) error {
|
||||||
p, err := c.img.image.Pixels()
|
if err := c.img.image.ReadPixels(c.result); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.result = p
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,18 +165,19 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, offsets [gra
|
|||||||
theCommandQueue.EnqueueDrawTrianglesCommand(i, srcs, offsets, vertices, indices, clr, mode, filter, address, dstRegion, srcRegion, shader, uniforms, evenOdd)
|
theCommandQueue.EnqueueDrawTrianglesCommand(i, srcs, offsets, vertices, indices, clr, mode, filter, address, dstRegion, srcRegion, shader, uniforms, evenOdd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pixels returns the image's pixels.
|
// ReadPixels reads the image's pixels.
|
||||||
// Pixels might return nil when OpenGL error happens.
|
// ReadPixels returns an error when an error happens in the graphics driver.
|
||||||
func (i *Image) Pixels() ([]byte, error) {
|
func (i *Image) ReadPixels(buf []byte) error {
|
||||||
i.resolveBufferedReplacePixels()
|
i.resolveBufferedReplacePixels()
|
||||||
c := &pixelsCommand{
|
c := &pixelsCommand{
|
||||||
img: i,
|
img: i,
|
||||||
|
result: buf,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
if err := theCommandQueue.Flush(); err != nil {
|
if err := theCommandQueue.Flush(); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
return c.result, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
||||||
@ -222,8 +223,9 @@ func (i *Image) Dump(path string, blackbg bool, rect image.Rectangle) error {
|
|||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
pix, err := i.Pixels()
|
w, h := i.InternalSize()
|
||||||
if err != nil {
|
pix := make([]byte, 4*w*h)
|
||||||
|
if err := i.ReadPixels(pix); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ type Image interface {
|
|||||||
ID() ImageID
|
ID() ImageID
|
||||||
Dispose()
|
Dispose()
|
||||||
IsInvalidated() bool
|
IsInvalidated() bool
|
||||||
Pixels() ([]byte, error)
|
ReadPixels(buf []byte) error
|
||||||
ReplacePixels(args []*ReplacePixelsArgs)
|
ReplacePixels(args []*ReplacePixelsArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1186,15 +1186,18 @@ func (i *Image) syncTexture() {
|
|||||||
cb.WaitUntilCompleted()
|
cb.WaitUntilCompleted()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) Pixels() ([]byte, error) {
|
func (i *Image) ReadPixels(buf []byte) error {
|
||||||
|
if got, want := len(buf), 4*i.width*i.height; got != want {
|
||||||
|
return fmt.Errorf("metal: len(buf) must be %d but %d at ReadPixels", want, got)
|
||||||
|
}
|
||||||
|
|
||||||
i.graphics.flushIfNeeded(false)
|
i.graphics.flushIfNeeded(false)
|
||||||
i.syncTexture()
|
i.syncTexture()
|
||||||
|
|
||||||
b := make([]byte, 4*i.width*i.height)
|
i.texture.GetBytes(&buf[0], uintptr(4*i.width), mtl.Region{
|
||||||
i.texture.GetBytes(&b[0], uintptr(4*i.width), mtl.Region{
|
|
||||||
Size: mtl.Size{Width: i.width, Height: i.height, Depth: 1},
|
Size: mtl.Size{Width: i.width, Height: i.height, Depth: 1},
|
||||||
}, 0)
|
}, 0)
|
||||||
return b, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) ReplacePixels(args []*graphicsdriver.ReplacePixelsArgs) {
|
func (i *Image) ReplacePixels(args []*graphicsdriver.ReplacePixelsArgs) {
|
||||||
|
@ -162,12 +162,10 @@ func (c *context) bindFramebufferImpl(f framebufferNative) {
|
|||||||
gl.BindFramebufferEXT(gl.FRAMEBUFFER, uint32(f))
|
gl.BindFramebufferEXT(gl.FRAMEBUFFER, uint32(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) framebufferPixels(f *framebuffer, width, height int) []byte {
|
func (c *context) framebufferPixels(buf []byte, f *framebuffer, width, height int) {
|
||||||
gl.Flush()
|
gl.Flush()
|
||||||
c.bindFramebuffer(f.native)
|
c.bindFramebuffer(f.native)
|
||||||
pixels := make([]byte, 4*width*height)
|
gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(buf))
|
||||||
gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(pixels))
|
|
||||||
return pixels
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) framebufferPixelsToBuffer(f *framebuffer, buffer buffer, width, height int) {
|
func (c *context) framebufferPixelsToBuffer(f *framebuffer, buffer buffer, width, height int) {
|
||||||
|
@ -236,7 +236,7 @@ func (c *context) bindFramebufferImpl(f framebufferNative) {
|
|||||||
gl.bindFramebuffer.Invoke(gles.FRAMEBUFFER, js.Value(f))
|
gl.bindFramebuffer.Invoke(gles.FRAMEBUFFER, js.Value(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) framebufferPixels(f *framebuffer, width, height int) []byte {
|
func (c *context) framebufferPixels(buf []byte, f *framebuffer, width, height int) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
|
|
||||||
c.bindFramebuffer(f.native)
|
c.bindFramebuffer(f.native)
|
||||||
@ -244,8 +244,7 @@ func (c *context) framebufferPixels(f *framebuffer, width, height int) []byte {
|
|||||||
l := 4 * width * height
|
l := 4 * width * height
|
||||||
p := jsutil.TemporaryUint8ArrayFromUint8Slice(l, nil)
|
p := jsutil.TemporaryUint8ArrayFromUint8Slice(l, nil)
|
||||||
gl.readPixels.Invoke(0, 0, width, height, gles.RGBA, gles.UNSIGNED_BYTE, p)
|
gl.readPixels.Invoke(0, 0, width, height, gles.RGBA, gles.UNSIGNED_BYTE, p)
|
||||||
|
copy(buf, uint8ArrayToSlice(p, l))
|
||||||
return uint8ArrayToSlice(p, l)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) framebufferPixelsToBuffer(f *framebuffer, buffer buffer, width, height int) {
|
func (c *context) framebufferPixelsToBuffer(f *framebuffer, buffer buffer, width, height int) {
|
||||||
|
@ -148,14 +148,12 @@ func (c *context) bindFramebufferImpl(f framebufferNative) {
|
|||||||
c.ctx.BindFramebuffer(gles.FRAMEBUFFER, uint32(f))
|
c.ctx.BindFramebuffer(gles.FRAMEBUFFER, uint32(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) framebufferPixels(f *framebuffer, width, height int) []byte {
|
func (c *context) framebufferPixels(buf []byte, f *framebuffer, width, height int) {
|
||||||
c.ctx.Flush()
|
c.ctx.Flush()
|
||||||
|
|
||||||
c.bindFramebuffer(f.native)
|
c.bindFramebuffer(f.native)
|
||||||
|
|
||||||
pixels := make([]byte, 4*width*height)
|
c.ctx.ReadPixels(buf, 0, 0, int32(width), int32(height), gles.RGBA, gles.UNSIGNED_BYTE)
|
||||||
c.ctx.ReadPixels(pixels, 0, 0, int32(width), int32(height), gles.RGBA, gles.UNSIGNED_BYTE)
|
|
||||||
return pixels
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) framebufferPixelsToBuffer(f *framebuffer, buffer buffer, width, height int) {
|
func (c *context) framebufferPixelsToBuffer(f *framebuffer, buffer buffer, width, height int) {
|
||||||
|
@ -60,13 +60,13 @@ func (i *Image) setViewport() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) Pixels() ([]byte, error) {
|
func (i *Image) ReadPixels(buf []byte) error {
|
||||||
if err := i.ensureFramebuffer(); err != nil {
|
if err := i.ensureFramebuffer(); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
p := i.graphics.context.framebufferPixels(i.framebuffer, i.width, i.height)
|
i.graphics.context.framebufferPixels(buf, i.framebuffer, i.width, i.height)
|
||||||
return p, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) framebufferSize() (int, int) {
|
func (i *Image) framebufferSize() (int, int) {
|
||||||
|
@ -497,8 +497,8 @@ 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() error {
|
func (i *Image) readPixelsFromGPU() error {
|
||||||
pix, err := i.image.Pixels()
|
pix := make([]byte, 4*i.width*i.height)
|
||||||
if err != nil {
|
if err := i.image.ReadPixels(pix); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i.basePixels = Pixels{}
|
i.basePixels = Pixels{}
|
||||||
@ -626,8 +626,8 @@ func (i *Image) restore() error {
|
|||||||
|
|
||||||
if len(i.drawTrianglesHistory) > 0 {
|
if len(i.drawTrianglesHistory) > 0 {
|
||||||
i.basePixels = Pixels{}
|
i.basePixels = Pixels{}
|
||||||
pix, err := gimg.Pixels()
|
pix := make([]byte, 4*w*h)
|
||||||
if err != nil {
|
if err := gimg.ReadPixels(pix); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i.basePixels.AddOrReplace(pix, 0, 0, w, h)
|
i.basePixels.AddOrReplace(pix, 0, 0, w, h)
|
||||||
|
Loading…
Reference in New Issue
Block a user