-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pixel drawing is slow #36
Comments
I've tested this so far by adding a new data type named sg_pixbuf_be and have compared it's speed to the current method of drawing pixels directly to a window of size 800x600 pixels. Drawing directly to the window yields a speed of 134ms per frame on my laptop, whilst drawing to a pixbuf which is then drawn to the screen is approximately 42ms per frame. Whilst creating a new datatype called pixbuf proves that it would be advantageous to draw in this way, I'm thinking modifying bitmap such that it can act similar to a pixbuf would be a better approach. Bitmap already has both a surface and a texture, bitmap can already have shapes drawn to it, and modifying bitmap would be less intrusive and would continue to work with already existing games/programs. @macite, any additional comments or thoughts before I go ahead? |
Yeah, this is interesting. If you changed the bitmap then all drawing operations would need to be changed to use that approach -- draw changes to the surface then render to each texture on its draw. There was a reason we didn't do it this way... I remember. Drawing rotated and scaled bitmaps onto other bitmaps. It may be better to have the pixel buffer and only support something like put pixel.... what else did you want to support for this? |
I was thinking about having an enum in the bitmap which determines if the last drawing operation was to a SDL_Surface or to a SDL_Texture and syncs one with the other periodically if the next operation was to the opposite data type. For example, if the last drawing operation was a Texture operation and the next one was a Surface operation, then the surface would be synced with the texture. This would allow multiple pixels to be drawn to a surface relatively quickly, then for the surface to only be transferred to textures once a texture based operation occurs. You'll still get slow cases, like when you draw a pixel, then a shape, then another pixel and another shape. But this seems like a rather odd thing to do anyway and should end up being the same speed as what we've already got. |
May I suggest a DrawPixelBatch() function that takes an array of pixels and does the surface/texture handling internally? That would mean that the feature is entirely insulated from the rest of the codebase, and it will be clearer that you have to draw all your pixels at once for efficiency. From: Aloz1 [email protected] I was thinking about having an enum in the bitmap which determines if the last drawing operation was to a SDL_Surface or to a SDL_Texture and syncs one with the other periodically if the next operation was to the opposite data type. For example, if the last drawing operation was a Texture operation and the next one was a Surface operation, then the surface would be synced with the texture. This would allow multiple pixels to be drawn to a surface relatively quickly, then for the surface to only be transferred to textures once a texture based operation occurs. You'll still get slow cases, like when you draw a pixel, then a shape, then another pixel and another shape. But this seems like a rather odd thing to do anyway and should end up being the same speed as what we've already got. You are receiving this because you are subscribed to this thread. |
Draw Pixel Batch sounds like a good idea in this case. Parameters? May need a PixelBatch type, to avoid issues mapping this between languages. |
I envisioned it as multiple sets of whatever DrawPixel takes. Then it would be akin to calling DrawPixel in a loop but with efficiency gains. I've not looked at it too closely to be honest, so there may be details to work out -- a PixelBatch type sounds like one of them. From: Andrew Cain [email protected] Draw Pixel Batch sounds like a good idea in this case. Parameters? May need a PixelBatch type, to avoid issues mapping this between languages. You are receiving this because you commented. |
That's essentially what I've done by creating sg_pixbuf_be. But after thinking about it, I figured it would be quicker to only update pixels in the texture when they're needed, and only those that have changed...not once every frame (what I've implemented), or by individually transferring pixels across (which is what is currently in swingame). The way you'd do this is by introducing a SDL_Texture into each pixbuf, then calling either SDL_UpdateTexture or SDL_LockTexture once you've finished drawing pixels to transfer the changes across to the GPU. Once you've done this however, there is very little difference between sg_pixbuf_bg and sg_bitmap_be...just that one is way faster with pixels...and the other has shape drawing functionality. Hence why my train of thought led to merging sg_pixbuf_be and sg_bitmap_be. We could keep the two separate, but I felt it would be more convenient and more beneficial to merge the functionality together. I'll experiment some more and let you know what the numbers are like for speed regarding SDL_UpdateTexture and SDL_LockTexture. I'm currently creating a new texture each frame from the surface data, so there is definitely room for improvement. |
Also make sure you are on the |
Branches are tidied up now... work off |
Finally finished both versions. Sorry it took so long, I've been busy with work and had to rebase everything (as well as fix up some small bugs) as I'd unfortunately been developing under the old v4_backend branch. I'll create pull requests for both methods so you can comment on them and see what you think. As an aside, the way I've implemented this under the bitmap_be version means that bitmap_be always has a surface as well as textures, and remembers where it last drew to so it can keep things in sync. This also ties in quite nicely with how swingame currently keeps bitmaps open without a window. |
Currently pixel drawing is very slow in Swingame, to the point where drawing each pixel once on a 800x600 window results in a desperate of approximately 1-10 frames per second (dependant on the computer).
Having explored ideas, it seems that drawing all pixel changes to an SDL_Surface then moving those changes to a texture once per frame will dramatically increase the speed.
The text was updated successfully, but these errors were encountered: