Jump to content

Recommended Posts

Posted (edited)

Hi folks!

I use High Performance TFT-LCD Graphics Controller LT7381 with Geometric Drawing Engine and I want to use hardware functions of drawing Circles, Ellipses, Boxes, Rounded Boxes and etc. I found how to draw lines and fill a rectangle using GDISP_HARDWARE_LINES and GDISP_HARDWARE_FILLS. For example, for GDISP_HARDWARE_CIRCLE I did not find the corresponding code. How to do it right without interfering with the uGFX library?

Thanks!

Edited by Sergey Kushnir
Posted

Hey!

If the library does currently not support a particular hardware accelerated feature (such as GDISP_HARDWARE_CIRCLE), you'll have to modify/extend the library in two places:

Have a look at src/gdisp/gdisp_driver.h. You can see that there are function pointers to LLD functions for hardware accelerated drawing.
For anything not in there yet, you'd create another one of those entries in the driver VMT (i.e. guarded by GDISP_HARDWARE_CIRCLE).

Then set that GDISP_HARDWARE_XXX to GFXON in your GDISP driver configuration file (gdisp_lld_config.h) and implement that function.

From there, the only thing left to do is to actually call that new LLD function instead of doing the rendering in software inside of src/gdisp/gdisp.c.

We once added support for hardware accelerated circles, ellipses, text and so on but the customer did not want the code to be merged back into the library. Hence it's currently absent from the publicly available version :(

 

Hope that helps!

Posted

I also thought in this direction. Your answer confirms that this is the correct way. I was looking to see if maybe there is some *.h file included as an extension in the main code. Sometimes they do this.

Posted

Unfortunately, there is no way around modifying both src/gdisp/gdisp_driver.h and src/gdisp/gdisp.c :(

You can either maintain a patch yourself for subsequent updates of the µGFX library or consider contributing changes to back so they'll be incorporated :)

  • 1 month later...
Posted

I have successfully implemented drawing of graphic primitives using the built-in Geometric Drawing Engine. But I have the following question. Preamble. My project uses a display with a screen size of 1024x600 pixels. The exchange rate between the control controller and the display is not enough and leads to flickering of the screen elements. This is annoying for the user. The memory size of the LT7381 display controller is 32 Mbit and can accommodate two images. If one image is displayed on the display, the second image - the shadow screen - can be prepared. The cycle of drawing and displaying can be represented as follows (real code of another project):

void CDisplay::RedrawStaticScreen(void)
{
	// Filling the shadow screen area
	// Displaying the menu
	m_pMenu->Draw(m_pGui);
	// Drawing the screen
	m_pCurrentScreen->DrawStatic();
	m_pCurrentScreen->DrawRefresh(m_iFrameIndex, true);

	// Switching the active frame
	m_pHal->FrameActivate(m_iFrameIndex);
	if (1 < (++m_iFrameIndex))
		m_iFrameIndex = 0;

	// Filling the second screen area
	// Displaying the menu
	m_pMenu->Draw(m_pGui);
	// Drawing the screen
	m_pCurrentScreen->DrawStatic();
	m_pCurrentScreen->DrawRefresh(m_iFrameIndex, true);
}

 

The question is: where in the library uGFX can you switch screens?

Posted

Yes, this is generally possible.

The basic concept consists of:

  • Using gdispGetDisplay() to get the two buffers
  • Using gdispControl() / gdispGControl() to tell the driver which buffer to show (i.e. when to swap buffers)
  • Using the various 'G' prefixed versions of the GDISP rendering API (or setting the currently active GDISP globally whenever you swap)

Note that this requires implementing this capability in your corresponding GDISP driver.

Look at the STM32LTDC driver in the current master branch. It supports double buffering the same way (i.e. the display controller provides more than one buffer and µGFX simply switches from one to the other): https://git.ugfx.io/uGFX/ugfx/src/branch/master/drivers/gdisp/STM32LTDC
The readme in there might be useful too.

Actually using it would look like this:

#include "gfx.h"

static GDisplay* _display1;
static GDisplay* _display2;

// Requests a buffer swap on the driver level
static void _setActiveBuffer(GDisplay* g)
{
	gdispGControl(g, STM32LTDC_CONTROL_SHOW_BUFFER, NULL);
}

int main(void)
{
	// Initialize uGFX library
	gfxInit();
	
	// Get the two buffers
	_display1 = gdispGetDisplay(0);
	if (!_display1)
		gfxHalt("could not get display 1");
	_display2 = gdispGetDisplay(1);
	if (!_display2)
		gfxHalt("could not get display 2");

	// Render to each buffer
	gdispGClear(_display1, GFX_BLUE);
	gdispGClear(_display2, GFX_RED);

	// Switch between buffers
	while (gTrue) {
		gfxSleepMilliseconds(800);
		_setActiveBuffer(_display1);
		gfxSleepMilliseconds(800);
		_setActiveBuffer(_display2);
	}

	return 0;
}

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...