cancel
Showing results for 
Search instead for 
Did you mean: 

Using a PainterRGB888 in custom container causes TouchGFX thread to halt

JHarding
Senior

Hello,

TouchGFX version: 4.15.0

STMCubeIDE: 1.4.2

I need some help, I am seeing some strange behavior from a custom module I am creating. Basically, when I am forced to use a PainterRGB888 to color a circle, TouchGFX will halt when calling showBaseModal()

Here is my class:

#include <gui/containers/modal/modalBase.hpp>
#include <touchgfx/Color.hpp>
 
modalBase* modalBase::getInstance()
{
    static modalBase gModalBase;
    return &gModalBase;
}
 
modalBase::modalBase()
{
    mInternalWidth  = 212;
    mInternalHeight = 159;
    mCornerRadius   = 10;
    mEdgeBuffer     = 30;
 
    mMainContainer.setX(0);
    mMainContainer.setY(0);
    mMainContainer.setWidth(272);
    mMainContainer.setHeight(480);
 
    circleTopLeft.setPosition(mEdgeBuffer, 161, mCornerRadius*2, mCornerRadius*2);
    circleTopLeft.setCenter(mCornerRadius, mCornerRadius);
    circleTopLeft.setRadius(mCornerRadius);
    circleTopLeft.setLineWidth(0);
    circleTopLeft.setArc(0, 360);
    circleTopLeftPainter.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 255, 255));
    circleTopLeft.setPainter(circleTopLeftPainter);
 
    mMainContainer.add(circleTopLeft);
}
 
void modalBase::initialize()
{
 
}
 
void modalBase::showBaseModal()
{
    if(!application().getCurrentScreen()->getRootContainer().contains(mMainContainer))
        application().getCurrentScreen()->getRootContainer().add(mMainContainer);
 
    mMainContainer.invalidate();
}
 
#ifndef GUI_INCLUDE_GUI_CONTAINERS_MODALBASE_HPP_
#define GUI_INCLUDE_GUI_CONTAINERS_MODALBASE_HPP_
 
#include <gui/common/FrontendApplication.hpp>
#include <touchgfx/containers/Container.hpp>
#include <touchgfx/widgets/Box.hpp>
#include <touchgfx/widgets/canvas/Circle.hpp>
#include <touchgfx/widgets/canvas/PainterRGB888.hpp>
#include <touchgfx/widgets/canvas/Line.hpp>
#include <gui/containers/HomeBar.hpp>
#include <touchgfx/mixins/MoveAnimator.hpp>
 
class modalBase
{
public:
    static modalBase* getInstance();
 
    virtual void initialize();
 
    void showBaseModal();
 
protected:
    FrontendApplication& application()
    {
        return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
    }
 
    touchgfx::Circle circleTopLeft;
    touchgfx::PainterRGB888 circleTopLeftPainter;
 
    MoveAnimator< touchgfx::Container > mMainContainer;
private:
    modalBase();//Private so no one else can make one of me.
 
    int mInternalWidth;
    int mInternalHeight;
    int mCornerRadius;
    int mEdgeBuffer;
};
 
#endif /* GUI_INCLUDE_GUI_CONTAINERS_MODALBASE_HPP_ */

If I change the circle to something like a Box that doesn't require a painter, then the code works just fine. If I change it to a line (which requires a painter) then TouchGFX halts when calling showBaseModal();

If I use a circle from within TouchGFX generator, that circle will be drawn on the screen without issue.

Any idea what I am doing wrong here?

1 ACCEPTED SOLUTION

Accepted Solutions
JHarding
Senior

Thanks for the nudges in the right direction. It got me to a solution.

To answer a few questions...

I am using a custom board based off the STM32F746. It is setup mostly the same as the STM32F746 Discovery board with a few pins changed here or there.

The simulator for my project has never worked :(

I created the project with CubeMX.

What I ended up doing was using a template project for the STM32F746 Disco board. From there I imported my custom container, added my own button to the template, added an interaction to call a virtual function, and then added the necessary code to call showBaseModal(). I was then able to use the simulator, which froze exactly like my board!

When I added my custom container, the line:

mMainContainer.invalidate();

was commented out of my showBaseModal() function. When I uncommented that line, the simulator crashed with the following message.

Assertion failed: No buffer allocated for CanvasWidgetRender

A quick google search led me to Martin's existing post located here:

Martin's post about Canvas Widget Renderers

I quickly added his example code and now my circles draw on the screen without issue.

I am attaching the example project that I made for anyone that is wondering how to show a modal on any screen at any time. I hope this adds some value to my post and to the community.

Thanks for your help!

View solution in original post

11 REPLIES 11
JHarding
Senior

So when I use a circle on a screen that is entirely controlled by touchGFX designer, circles work. I tried creating a base class within TouchGFX designer, and then extending it via code and the new extended version of the container doesn't work when using a function like showBaseModal(). But the base class does work as a container when just manually added to a screen from within touchGFX.

I have used the code:

application().getCurrentScreen()->getRootContainer().add(mycontainer);

for a custom keyboard that I want to display on the active screen and it works flawlessly. Clearly there is some weird thing about this methodology that doesn't work well with painters. Please, some guidance here would be really nice. Little hick-ups like these are really delaying the progress of this project and its stacking up against me. Thank you.

JHarding
Senior

Hello? @Alexandre RENOUX​ @Martin KJELDSEN​ @Mon2​ 

Alexandre RENOUX
Principal

Hello,

Here are a few questions to help moving forward with your request :

What board are you using ?

Is it working on the Simulator ?

When you say you use a circle from TouchGFX Designer what is different from your non working code ?

Can you enclose your project ?

/Alexandre

Martin KJELDSEN
Chief III

​If your application is not 24bpp then PainterRGB888 will cause a fault in the LCD class.

Generally it will be very helpful if you always supply

  1. how you created the project. CubeMX? Toughgfx designer? which Application Template? Bit depth?
  2. versions of tools (which you did)
  3. Board you're trying to run on

/Martin

JHarding
Senior

Thanks for the nudges in the right direction. It got me to a solution.

To answer a few questions...

I am using a custom board based off the STM32F746. It is setup mostly the same as the STM32F746 Discovery board with a few pins changed here or there.

The simulator for my project has never worked :(

I created the project with CubeMX.

What I ended up doing was using a template project for the STM32F746 Disco board. From there I imported my custom container, added my own button to the template, added an interaction to call a virtual function, and then added the necessary code to call showBaseModal(). I was then able to use the simulator, which froze exactly like my board!

When I added my custom container, the line:

mMainContainer.invalidate();

was commented out of my showBaseModal() function. When I uncommented that line, the simulator crashed with the following message.

Assertion failed: No buffer allocated for CanvasWidgetRender

A quick google search led me to Martin's existing post located here:

Martin's post about Canvas Widget Renderers

I quickly added his example code and now my circles draw on the screen without issue.

I am attaching the example project that I made for anyone that is wondering how to show a modal on any screen at any time. I hope this adds some value to my post and to the community.

Thanks for your help!

Alexandre RENOUX
Principal

For your information, you don't need to do it manually now.

In the Designer there's an option to select it easily. When you click on the screen having the circle, on the right side bar you will notice something like below.

0693W000005ArrcQAC.pngSimply tick the box and choose the size in byte you want. Usually we put 3600.

/Alexandre

Thanks for that. I did notice it was there. Can you please confirm something for me?

if I do it from the designer, it applies to that screen specifically?

Whereas if I do it from code, externally from a specific screen it will apply to all screens?

If you do it from a specific screen it's going to be applied for this specific screen.

In any case, you need to add it to each screen if you plan on using a circle on several screens.

If you create two screens in the Designer with one circle per screen and generate code, you can see for yourself the code generated.

Maybe it is something that can be optimized. We will think about it.

/Alexandre

I created several screens in TouchGFX. I then created one separate class that creates a buffer for the canvas widget renderer prior to starting the TouchGFX task. This seems to work for all screens and then I don’t have to modify each screen. Is this expected behavior?