2020-06-11 01:38 PM
I'm following this guide to creating a custom widget. Instead of any qr code logic, all I'm starting with is just drawing a solid color to the invalidated widget.
void MyWidget::draw(const touchgfx::Rect& invalidatedArea) const {
touchgfx::Rect absolute = getAbsoluteRect();
uint16_t* framebuffer = touchgfx::HAL::getInstance()->lockFrameBuffer();
for (int y = invalidatedArea.y; y < invalidatedArea.bottom(); y++)
{
for (int x = invalidatedArea.x; x < invalidatedArea.right(); x++)
{
framebuffer[absolute.x + x + (absolute.y + y) * touchgfx::HAL::DISPLAY_WIDTH] = 0xFFFF;
}
}
touchgfx::HAL::getInstance()->unlockFrameBuffer();
}
When I download and run the program, the area in which the widget is supposed to reside does not update when I enter the screen, instead it holds the image of the last screen. I also see three white boxes of interleaving white in a different part of the screen altogether.
As an experiment, I attempted to draw a white 800px line at the top of the screen, and discovered the white line only went 2/3 of the way across. I reason this is because the framebuffer is a 16 bit pointer, and my pixel format is 24 bits.
Thanks.
2020-06-11 02:14 PM
If anyone stumbles on this in the future, here is a possible solution that worked for me. Reinterpret_cast the framebuffer pointer to an 8-bit pointer, find the base address by multiplying the offset by 3 (8 bits x 3 = 24 bits), and write to it and the two adjacent cells.
uint8_t* framebuffer = reinterpret_cast<uint8_t*>(touchgfx::HAL::getInstance()->lockFrameBuffer());
for (int y = invalidatedArea.y; y < invalidatedArea.bottom(); y++)
{
for (int x = invalidatedArea.x; x < invalidatedArea.right(); x++)
{
framebuffer[(absolute.x + x + (absolute.y + y) * touchgfx::HAL::DISPLAY_WIDTH) * 3] = 0xFF;
framebuffer[(absolute.x + x + (absolute.y + y) * touchgfx::HAL::DISPLAY_WIDTH) * 3 + 1] = 0xFF;
framebuffer[(absolute.x + x + (absolute.y + y) * touchgfx::HAL::DISPLAY_WIDTH) * 3 + 2] = 0xFF;
}
}
2020-06-12 04:57 AM
If you're moving to a new screen and you're seeing some old elements, it's typically because you don't have a background that covers the entire framebuffer. You're peeking at the left-over state of the framebuffer that hasn't been overwritten by your new screen.
uint8_t* RESTRICT buf = reinterpret_cast<uint8_t*>(HAL::getInstance()->lockFrameBuffer());
/Martin
2020-06-15 06:38 AM
For what it's worth, although my solution above worked, I didn't end up drawing to the framebuffer directly as my implementation was slow and didn't suit my personal application; instead I used fillrect for most of my drawing.
2020-06-15 11:36 PM
Usually, you'll only draw directly to the framebuffer if there's something that TouchGFX cannot handle for you. In some cases, it'll even help you to optimize by using the ChromART chip. For instance, if you don't want to pay the price in memory for widgets, or if you need to do some calculations around a certain pixel, etc.
/Martin