Open hajimehoshi opened 5 months ago
https://github.com/hajimehoshi/ebiten/issues/2902 might be related
For an indexed bitmap editor for pixel art it is handy that ebiten.Image is an image.Image. If this is removed we will need to add conversion functions in both ways.
Yeah, this additional function call is an intentional change to make the execution cost more explicit.
As long as indexed bitmaps are properly supported both ways, this is fine by me
I have no idea about the bitmap editor, so I cannot say anything about this.
As ReadPixels
is very special as it flushes the internal command queue, I might want to move this method to somewhere where we can call it in a limited situation (under Update or Draw). Actually, reading pixels was a blocker to implement handling events (https://github.com/hajimehoshi/ebiten/issues/1704#issuecomment-1751803675).
Another possible idea is to make ReadPixels
asynchronous:
type ReadPixelsResult struct {
Bytes []byte
Err error
}
func (*Image) ReadPixels(buf []byte) (<-chan ReadPixelsResult)
Another possible idea is to make ReadPixels asynchronous:
I have a few questions:
buf
argument in this case?What is the role of the buf argument in this case?
To avoid or reduce internal allocations.
What is the case where ReadPixels returns an error, for example?
The graphics driver might fail for some reasons. In most cases there is nothing a user can do.
If we just add a return value, compatibility is certainly preserved, but if the signature is going to change, it would be more straightforward to change the function name.
No, adding a returning value breaks the compatibility. There can be an interface that defines ReadPixels.
To avoid or reduce internal allocations.
Will the allocated buf
be written from another goroutine?
Will the allocated buf be written from another goroutine?
Yes and no. We can treat this like append
: if the buf is not enough, ReadPixels can extend the buffer.
OK, thanks for responding. To be honest I am not sure about the design of the asynchronous API, but my opinion is in favor of this proposal.
Another example of Go's non-blocking API is a Start/Wait pair like exec.Command, I'm not sure if it's appropriate for Ebitengine, but just FYI.
Operating System
What feature would you like to be added?
*ebiten.Image
now implementsimage.Image
which includesAt
andColorModel
. EspeciallyAt
is problematic asAt
seems handy though it is very expensive to sync pixel data from GPU to CPU. So, we don't want encourage users to useAt
.*ebiten.Image
implementingimage.Image
was not a good API in terms of execution costs.Thus, we propose these API changes.
(*ebiten.Image).At
(*ebiten.Image).RGBA64At
(*ebiten.Image).ColorModel
(*ebiten.Image).Set
draw.Image
, but as*ebiten.Image
is no longerimage.Image
, I don't think we have to have this.(*ebiten.Image).SubImage
return an*ebiten.Image
instead ofimage.Image
*ebiten.Image
is no longerimage.Image
, we no longer need to follow this.(*ebiten.Image).ReadPixels
return an errorAt
couldn't return an error and Ebitengine accumulated an error in the internal. AsAt
is removed, we no longer need to have such a hack.func Image(*ebiten.Image) image.Image
toebitenutil
(orScreenshot
orDump
?)(*ebiten.Image).ReadPixels
, we can put a utility function to create animage.Image
in a utility package, rather than the core package.As these are breaking changes, we will do in v3.
/CC @Zyko0 @superloach @tinne26
Why is this needed?
An expensive API should not be handy since people often misuse such APIs.