BRT Community

Please login or register.

Login with username, password and session length
Advanced search  

News:

Welcome to the Bridgetek Community!

Please read our Welcome Note

Technical Support enquires
please contact the team
@ Bridgetek Support

Please refer to our website for detailed information on all our products - Bridgetek - Bridging Technology

Author Topic: Load image  (Read 2751 times)

koyocik88

  • Newbie
  • *
  • Posts: 6
    • View Profile
Load image
« on: June 24, 2024, 07:42:31 AM »

Hello,

I want load different icons to the screen. I uploaded PNG into the flash memory. When I try display two different icons are displayed two the same icons (see attachment).
Additional are displayed artifacts on both icons.

I use also append feature for display this part of screen as static part. I tried display icons without append feature. The icons have no artifact that way, but also
are displayed same icons instead two different.

Has any one idea where is the problem?

Below part of my code:

Code: [Select]
#define SETTINGS_ADDRESS_MEM         22976
#define NEXT_ADDRESS_MEM24576

// Clear the first 10K of RAM_G where we will store the static part of the DL #######
Gpu_CoCmd_Dlstart (phost); // Start co-pro list
Gpu_CoCmd_MemSet (phost, 0, 0, 10 * 1024); // Set a block of memory to zeros between address 0 and address 10*1024
App_Flush_Co_Buffer (phost); // Send the above co-pro commands off to the FT800 ...
Gpu_Hal_WaitCmdfifo_empty (phost); // ... and wait for them to be processed

// Create the static part of the display and store it within the FT800's RAM_G
// Create a co-processor list which displays the Static (non-changing) part of the final screen #######

Gpu_CoCmd_Dlstart (phost); //Start the display list

App_WrCoCmd_Buffer (phost, CLEAR(1, 1, 1)); //Command CLEAR is recommended to be used before any other drawing operation,
//in order to put the graphics engine in a known state.
//The end of the display list is always flagged with the command DISPLAY
// Draw background
App_WrCoCmd_Buffer (phost, SCISSOR_XY(0, 0));
App_WrCoCmd_Buffer (phost, SCISSOR_SIZE(240, 320));
Gpu_CoCmd_Gradient (phost, 0, 0, 0x323232, 0, 320, 0x666666);

// Return the stencil and scissor to normal
App_WrCoCmd_Buffer (phost, STENCIL_FUNC(ALWAYS, 1, 255));
App_WrCoCmd_Buffer (phost, SCISSOR_SIZE(240, 320));
App_WrCoCmd_Buffer (phost, SCISSOR_XY(0, 0));

// Draw parameters button menu
Gpu_CoCmd_FlashHelper_SwitchFullMode(&host);
Gpu_CoCmd_FlashSource(phost, PARAMETERS_ADDRESS_MEM);
Gpu_CoCmd_LoadImage(phost, 0, OPT_FLASH );

//Start drawing bitmap
App_WrCoCmd_Buffer(phost, BEGIN(BITMAPS));
App_WrCoCmd_Buffer(phost, VERTEX2II(15, 15, 0, 0));
App_WrCoCmd_Buffer(phost, END());


// Draw parameters button menu
Gpu_CoCmd_FlashHelper_SwitchFullMode(&host);
Gpu_CoCmd_FlashSource(phost, NEXT_ADDRESS_MEM);
Gpu_CoCmd_LoadImage(phost, 0, OPT_FLASH );

//Start drawing bitmap
App_WrCoCmd_Buffer(phost, BEGIN(BITMAPS));
App_WrCoCmd_Buffer(phost, VERTEX2II(130, 15, 0, 0));
App_WrCoCmd_Buffer(phost, END());

dloffset = Gpu_Hal_Rd16 (phost, REG_CMD_DL); // Reading the REG_CMD_DL tells us where the end of the new DL is in
// RAM_DL and therefore the size of our new 'static' display list
Gpu_Hal_WrCmd32 (phost, CMD_MEMCPY); // Command to copy a block of memory within the FT800
Gpu_Hal_WrCmd32 (phost, 1000L); // First parameter is destination, copy to address 1,000 decimal
Gpu_Hal_WrCmd32 (phost, RAM_DL); // Second parameter is the source, here we copy from start of RAM_DL
Gpu_Hal_WrCmd32 (phost, dloffset); // Third parameter is length of data to copy, as determined above

App_WrCoCmd_Buffer(phost, DISPLAY()); // Display command finished the Display List
Gpu_CoCmd_Swap(phost); // Swap to make the new DL active
App_Flush_Co_Buffer(phost); // Send the above co-pro commands off to the FT800 ...
Gpu_Hal_WaitCmdfifo_empty(phost); // ... and wait for them to be processed


Thank you in advance!
Logged

Rudolph

  • Sr. Member
  • ****
  • Posts: 418
    • View Profile
Re: Load image
« Reply #1 on: June 24, 2024, 05:17:01 PM »

Not my library, so I am not actually sure what potential side-effects are.  ;)

However, I see that you are mixing utility commands with display list commands.
Try to make things a bit cleaner first, do not throw everything between one pair of Gpu_CoCmd_Dlstart (phost); / Gpu_Hal_WaitCmdfifo_empty(phost); calls.

Setup things first, like you already did with the Gpu_CoCmd_MemSet().

I mean this stuff:
Gpu_CoCmd_FlashHelper_SwitchFullMode(&host);
Gpu_CoCmd_FlashSource(phost, PARAMETERS_ADDRESS_MEM);
Gpu_CoCmd_LoadImage(phost, 0, OPT_FLASH );

Move it out of the display-list building.
Especially so as using .png has the tendency to take quite some time and it wrangles the uppper 42k of memory.

I provide separate functions in my library.
One group that is meant to be called outside of display list building and that already includes execution
and waiting for the operation to be done.
And one group that is meant to be called when building a display list.

As you do have an external flash I would also advise to use ASTC 8x8 format, not to display directly from flash necessarily,
but mostly ASTC 8x8 is a 32 bit format with 8 bit alpha that only needs 2 bits per pixel.
And PNG is decoded to well, some format, that needs 8 or 16 bits per pixel.

Gpu_CoCmd_FlashSource(phost, PARAMETERS_ADDRESS_MEM);
Gpu_CoCmd_LoadImage(phost, 0, OPT_FLASH );
Gpu_CoCmd_FlashSource(phost, NEXT_ADDRESS_MEM);
Gpu_CoCmd_LoadImage(phost, 0, OPT_FLASH );

This loads two images from different flash addresse but decodes them both to address 0 of RAM_G.

This is missing CMD_SETBITMAP:
//Start drawing bitmap
App_WrCoCmd_Buffer(phost, BEGIN(BITMAPS));
App_WrCoCmd_Buffer(phost, VERTEX2II(130, 15, 0, 0));
App_WrCoCmd_Buffer(phost, END());

I wonder why the images are even displayed.

And the artefacts are likely the result of
Gpu_Hal_WrCmd32 (phost, CMD_MEMCPY)
As this also goes to address 0 of RAM_G.
Logged

koyocik88

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Load image
« Reply #2 on: June 25, 2024, 09:58:22 AM »

Hi Rudolph,

Thank you for your answer.

I'm sorry but I'm beginner in this field. Could you show example how should looks right code?
I mean this:
Quote
However, I see that you are mixing utility commands with display list commands.
Try to make things a bit cleaner first, do not throw everything between one pair of Gpu_CoCmd_Dlstart (phost); / Gpu_Hal_WaitCmdfifo_empty(phost); calls.

I use Riverdi library and their example doesn't consist CMD_SETBITMAP. Below is example from them for loading image:
Code: [Select]
static void Load_Jpeg(Gpu_Hal_Context_t *phost, uint32_t adr)
{
Gpu_CoCmd_Dlstart(phost);

App_WrCoCmd_Buffer(phost, CLEAR(1, 1, 1));

App_WrCoCmd_Buffer(phost, COLOR_RGB(255, 255, 255));

//Gpu_CoCmd_FlashHelper_SwitchFullMode(&host);

Gpu_CoCmd_FlashSource(phost, adr);

Gpu_CoCmd_LoadImage(phost, 0, OPT_FLASH );

//Start drawing bitmap

App_WrCoCmd_Buffer(phost, BEGIN(BITMAPS));

App_WrCoCmd_Buffer(phost, VERTEX2II(0, 0, 0, 0));

App_WrCoCmd_Buffer(phost, END());

App_WrCoCmd_Buffer(phost, RESTORE_CONTEXT());

App_WrCoCmd_Buffer(phost, DISPLAY());

Gpu_CoCmd_Swap(phost);

App_Flush_Co_Buffer(phost);

Gpu_Hal_WaitCmdfifo_empty(phost);

//platform_sleep_ms(3000);

}

Thank you for advice for using ASTC format. I will do like that.
Logged

BRT Community

  • Administrator
  • Hero Member
  • *****
  • Posts: 770
    • View Profile
Re: Load image
« Reply #3 on: June 25, 2024, 11:09:15 AM »

Hi,

Could you please post (or email to support.emea@brtchip.com) the actual icon image .png that you are displaying?

Good point Rudolph about using ASTC 8x8, this should give good quality with relatively small data size,

Best Regards, BRT Community
Logged

Rudolph

  • Sr. Member
  • ****
  • Posts: 418
    • View Profile
Re: Load image
« Reply #4 on: June 25, 2024, 07:05:52 PM »

Ok, first, I have my own library and I have a basic example: https://github.com/RudolphRiedel/FT800-FT813/tree/5.x/examples
All the examples use the same code, one of these is: https://github.com/RudolphRiedel/FT800-FT813/blob/5.x/examples/EVE_Test_Arduino_PlatformIO/src/tft.c
Just as something extra to check out.

Now, how EVE fundamentally works is that a display list gets executed internally, typically 60 times per second.
There is no screen buffer, the whole display is composed on the fly over and over again.
The display list can be written directly to with basic commands but usually is generated with the command co-processor as this allows mixing basic commands with more high-level commands like CMD_BUTTON.
And then there are assets like images and fonts (ok, technically also images).
The FT81x / BT81x EVE chips do have 1Mib of integrated memory for anything we want to put there.

So in order to display an image we first need to put it in RAM_G - but we only need to do this once.
This is something for the initialization phase of the software as a whole lot of data needs to be transferred thru SPI.
Unless you run out of RAM_G when your UI gets complex with several screens perhaps, you transfer the images once and be done.

So first do the setup:
Code: [Select]
...
Gpu_CoCmd_FlashHelper_SwitchFullMode(&host);
...
Gpu_CoCmd_FlashSource(phost, PARAMETERS_ADDRESS_MEM);
Gpu_CoCmd_LoadImage(phost, ADDRESS_IMAGE1, OPT_FLASH );
App_Flush_Co_Buffer(phost);
Gpu_Hal_WaitCmdfifo_empty(phost);
Gpu_CoCmd_FlashSource(phost, NEXT_ADDRESS_MEM);
Gpu_CoCmd_LoadImage(phost, ADDRESS_IMAGE2, OPT_FLASH );
App_Flush_Co_Buffer(phost);
Gpu_Hal_WaitCmdfifo_empty(phost);
...

And when everything is setup, write your display-list.
I am kind of gussing my way thru this library here.

Code: [Select]
Gpu_CoCmd_Dlstart(phost);
App_WrCoCmd_Buffer(phost, CLEAR(1, 1, 1));
App_WrCoCmd_Buffer(phost, VERTEX_FORMAT(0)); /* set the pixel precision for VERTEX2F to 1 */

App_WrCoCmd_Buffer(phost, BEGIN(BITMAPS));

App_WrCoCmd_Buffer(phost, COLOR_RGB(255, 255, 255));
Gpu_CoCmd_SetBitmap(phost, ADDRESS_IMAGE1, FORMAT_IMAGE1, WIDTH_IMAGE1, HEIGHT_IMAGE1);
App_WrCoCmd_Buffer(phost, VERTEX2F(15, 15);

App_WrCoCmd_Buffer(phost, COLOR_RGB(255, 255, 255));
Gpu_CoCmd_SetBitmap(phost, ADDRESS_IMAGE2, FORMAT_IMAGE2, WIDTH_IMAGE2, HEIGHT_IMAGE2);
App_WrCoCmd_Buffer(phost, VERTEX2F(130, 15);

App_WrCoCmd_Buffer(phost, END());

App_WrCoCmd_Buffer(phost, DISPLAY());
Gpu_CoCmd_Swap(phost);
App_Flush_Co_Buffer(phost);
Gpu_Hal_WaitCmdfifo_empty(phost);

So this display list should display your two images when you fill in the missing information about the images.

I added
App_WrCoCmd_Buffer(phost, COLOR_RGB(255, 255, 255));
for each image and this is where things are getting more interesting.

If you send the display list either cyclically (my preferred method) or when there is a change (needs to have a minimum delay between updates),
you can modify the colors each time,
For example to visually indicate that a touch was detected for an icon.

And again, for this it is not necessary to setup the images again in RAM_G.

Well, and there is a couple more things. :-)
Logged

koyocik88

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Load image
« Reply #5 on: June 26, 2024, 10:23:20 AM »

Thank you Rudolph for your comprehensive answer on this topic. I will follow your guidance.

As you advised before I will use ASTC format, but I can't display picture.
1. I used EAB v2.11.1 and I converted my PNG file into ASTC_8x8 format.
2. I uploaded .astc file into screen external flash.
3. I used example generated code for displaying image on the screen.
4 The image is not displayed right way.

What is strange that's my original PNG file has dimension 75x75 pixel and generated by EAB is 80x80 pixel.   

My .map file:

Code: [Select]
bt817.blob                                           : 0    : 4096
EDF Block                                            : 4096 : 128
info_80x80_COMPRESSED_RGBA_ASTC_8x8_KHR.astc         : 4224 : 1616
info_80x80_COMPRESSED_RGBA_ASTC_8x8_KHR.astc.padding : 5840 : 48 

Below is code from sample app generated by EAB:
Code: [Select]
#define USE_BT81X_FLASH

void Load_Image_info_80x80_COMPRESSED_RGBA_ASTC_8x8_KHR(EVE_HalContext * phost)
{
    Gpu_Hal_WaitCmdfifo_empty(phost);

    Gpu_CoCmd_Dlstart(phost);
    App_WrCoCmd_Buffer(phost, CLEAR(1, 1, 1));
    App_WrCoCmd_Buffer(phost, COLOR_RGB(255, 255, 255));

    uint16_t iw = 80;
    uint16_t ih = 80;
    uint16_t format = COMPRESSED_RGBA_ASTC_8x8_KHR;

#ifdef USE_BT81X_FLASH
#define BITMAP_ADDRESS_ON_FLASH 4224  // address of bitmap file from Flash Map
#define BITMAP_SIZE_ON_FLASH    1616    // size of bitmap file from Flash Map
    /* Switch Flash to FULL Mode */
    Gpu_CoCmd_FlashHelper_SwitchFullMode(phost);

    if (format >= COMPRESSED_RGBA_ASTC_4x4_KHR && format <= COMPRESSED_RGBA_ASTC_12x12_KHR) {
        Gpu_CoCmd_SetBitmap(phost, (0x800000 | BITMAP_ADDRESS_ON_FLASH / 32), format, iw, ih);
    } else {
        Gpu_CoCmd_FlashRead(phost, RAM_G, BITMAP_ADDRESS_ON_FLASH, BITMAP_SIZE_ON_FLASH);
        Gpu_CoCmd_SetBitmap(phost, RAM_G, format, iw, ih);
    }
#else
    //load bitmap file into graphics RAM
    //RAM_G is starting address in graphics RAM, for example 00 0000h
    Gpu_Hal_LoadImageToMemory(phost, "../../../info_80x80_COMPRESSED_RGBA_ASTC_8x8_KHR.raw", RAM_G, LOAD);
    Gpu_CoCmd_SetBitmap(phost, RAM_G, format, iw, ih);
#endif
    //Start drawing bitmap
    App_WrCoCmd_Buffer(phost, BEGIN(BITMAPS));
    App_WrCoCmd_Buffer(phost, VERTEX2II(0, 0, 0, 0));
    App_WrCoCmd_Buffer(phost, END());
    App_WrCoCmd_Buffer(phost, DISPLAY());
    Gpu_CoCmd_Swap(phost);
    App_Flush_Co_Buffer(phost);
    Gpu_Hal_WaitCmdfifo_empty(phost);

}
« Last Edit: June 26, 2024, 03:05:25 PM by koyocik88 »
Logged

Rudolph

  • Sr. Member
  • ****
  • Posts: 418
    • View Profile
Re: Load image
« Reply #6 on: June 27, 2024, 08:32:08 PM »

Looks like you used the .astc file, you need to use the .raw file.
The .astc file has an extra 16 bytes of file header.

I am not using the example, I only wish it would be optional to write that to disk.
Same goes for the .astc the .json, the .rawh and the _converted.png.
When converting a bunch of files the cleanup takes longer than the conversion.

Some for fonts, all I need is the .glyph and the .xfont file, not the three extra files, not the example and
certainly not that a folder is created with a sub-folder for every font size.


>What is strange that's my original PNG file has dimension 75x75 pixel and generated by EAB is 80x80 pixel.

Yes, that is a limitation of the format, you need sizes that can be divided by 8.

>Now, how EVE fundamentally works is that a display list gets executed internally...

One thing that I forgot to mention when I tried to be both brief and informative,
the display-list is double-buffered, you can not change the active one, you update the inactive one and CMD_SWAP then
exchanges it with the active list and so on.
The only bad idea there is trying to SWAP the list faster than the screen is refreshed.


Logged

koyocik88

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Load image
« Reply #7 on: July 01, 2024, 08:45:20 AM »

Thank you Rudolph.

File with extension .raw work fine.

I refresh my screen each 50 ms.

Logged