Click here to Skip to main content
15,887,083 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a graphics library for IoT devices here

GFX Forever: The Complete Guide to GFX for IoT[^]

It is decoupled from its drivers, and you can write one any sort of display.

These displays usually only have one "mode" they can be in - at their native resolution and color depth.

However, some displays can present multiple "modes" of operation, wherein they utilize a different resolution or a different color depth or otherwise have other features (like partial updates on e-paper displays)

The trouble is a bit difficult to explain without some background, so let me start by saying a different color depth requires a different concrete type such that

bitmap<rgb_pixel<16>> is a different type than bitmap<rgb_pixel<24>> or bitmap<gsc_pixel<1>> (last one is monochrome) - the example uses bitmaps for clarity but the same applies to screen modes as well.

That means I can't have one traditional screen_mode() function. It must be a template function that takes the screen mode as a template argument, like screen_mode<0>() because the type it returns will be different for each screen mode.

The other thing is, all of my draw surfaces, be they bitmaps or display drivers or screen modes (for drivers that expose more than one) are initialized on first use (but can be initialized earlier). They have to work that way.

With all of that in mind:

When I first draw to an uninitialized screen mode it will clear the display. it has to.

When I change screen modes I have to deinitialize the previous screen mode in the case that it holds a frame buffer in local RAM instead of on the display hardware (common for epaper and monochrome LCD)

This is before the new screen mode is initialized.

The screen will be blanked.

so if i go

C++
auto mode0 = driver.template screen_mode<0>();

// draw a small rectangle in the center of 
// the screen (clears the screen first)
draw::filled_rectangle(mode0,
    srect16(0,0,15,15).center((srect16)mode0.bounds()),
    color<decltype(mode0)::pixel_type>::blue);

auto mode1 = driver.template screen_mode<1>();

// draw a small rectangle in the center of
// the screen (changes mode and clears the 
// screen first)
draw::filled_rectangle(mode1,
    srect16(0,0,15,15).center((srect16)mode1.bounds()),
    color<decltype(mode1)::pixel_type>::purple);


// draw a small rectangle in the center of 
// the screen (changes mode and clears the 
// screen first)
draw::filled_rectangle(mode0,
    srect16(0,0,15,15).center((srect16)mode0.bounds()),
    color<decltype(mode0)::pixel_type>::red);


Note the comments. The first draw clears the screen due to initializing the driver (first use)

The second one clears the screen as the mode changes from 0 to 1

The third draw clears the screen as the mode changes from 1 to 0

My question to you is, how counterintuitive is this to you as a C++ developer, and can you think of a better way given the limitations I outlined?

What I have tried:

That kind of doesn't apply here, but I've tried exactly the code I presented, and it's currently the way I am doing things moving forward. I'm just not sure I like it.
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900