Skip to content
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

Drawing to screen #4

Open
ricosolana opened this issue Sep 4, 2022 · 1 comment
Open

Drawing to screen #4

ricosolana opened this issue Sep 4, 2022 · 1 comment
Labels

Comments

@ricosolana
Copy link

I was wondering about the usage of lcd_blit(void*) versus using the raw LCD screen memory address.

Looking through lcd_blit.cpp, the lcd_blit(void*) calls a hardware-specific function in the array lcd_blit_320x240_320x240_565 or 2 others. This then performs a memcpy from the passed buffer into the LCD screen address.

Why not just write each pixel as needed into the LCD screen address? Since 2 writes I see are done, one from triangles into the nGL screen buffer (looking at triangles.inc.h), then the last one in lcd_blit() when that same buffer is now copied to the screen address. Is this not done because of safety/ease of use, or does it makes little difference in speed?

Is there a way to draw to the screen faster or is this best we have?

@Vogtinator
Copy link
Owner

screen can't be used directly as LCD framebuffer because it's constantly being changed between frames. Depending on timing, an incomplete render (or more likely, just garbage) will appear on screen. On top of that, there's also the issue that the pixel data needs to be flushed from the data cache onto RAM so that the LCDC gets the right data. I did some benchmarks on real HW and at least the simple memcpy case is fast enough to not be a major concern compared to the time it takes for actual rendering.

Is there a way to draw to the screen faster or is this best we have?

The pretty much ideal way is to do double buffering by using two framebuffers, one that's being displayed and the other rendered to. Displaying is then just a matter of switching them, which the LCD controller has native support for, which also allows Vsync (see also ndless-nspire/Ndless#159).

The main drawback is that the framebuffer format must be the one expected by the display hardware, so currently either 320x240 8bpp, 320x240 16bpp or 240x320 16bpp rotated (90° and 270°...). nGL always renders 320x240 16bpp, so some conversion is necessary. That's currently handled by lcd_blit, which writes the converted data directly into the active framebuffer.

As long as format conversion is necessary, some kind of copy is unavoidable. That leaves just the original CX (pre W) which would benefit from a simple double buffering implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants