Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
56 user(s) are online (38 user(s) are browsing Forums)

Members: 0
Guests: 56

more...

Support us!

Headlines

 
  Register To Post  

Correct way to work with RGB/ARGB bitmaps?
Home away from home
Home away from home


See User information
@All

I want to write code that will load a bitmap when needed, display it, and then switch to another bitmap as required, and so on.

This should be done in a ReAction window using the bitmap.image class.

Currently, my approach is to create two bitmaps: a user bitmap and a VRAM bitmap. The user bitmap (in RAM) is used for all modifications, and then I blit it to the VRAM bitmap for display.

To achieve this, I created a render() function that takes the number of the bitmap to render.

The entire function looks like this:

void render(num) {


    
// Free old bitmaps
    
if (user_bm) {
        
IGraphics->FreeBitMap(user_bm);
        
user_bm NULL;
        
IDOS->Printf("Freed user_bm\n");
    }
    if (
vram_bm) {
        
IGraphics->FreeBitMap(vram_bm);
        
vram_bm NULL;
        
IDOS->Printf("Freed vram_bm\n");
    }

    
// Allocate new bitmaps
    
vram_bm IGraphics->AllocBitMapTags(widthheight24,
        
BMATags_PixelFormatPIXF_A8R8G8B8,
        
BMATags_DisplayableTRUE,
        
TAG_END);
        
    
user_bm IGraphics->AllocBitMapTags(widthheight24,
        
BMATags_Friendvram_bm,
        
BMATags_UserPrivateTRUE,
        
BMATags_PixelFormatPIXF_A8R8G8B8,
        
TAG_END);
    if (!
vram_bm || !user_bm) {
         
FAIL();
    }

    
// lock bitmap to work with
    
uint8 *buffer;
    
uint32 bpr;
    
APTR lock IGraphics->LockBitMapTags(user_bm,
        
LBM_BaseAddress, &buffer,
        
LBM_BytesPerRow, &bpr,
        
TAG_END);
    if (
lock && buffer) {
        
uint8 *src pix->samples;
        for (
int y 0heighty++) {
            
uint8 *row buffer bpr;
            for (
int x 0widthx++) {
                
row[0] = 255;
                
row[1] = src[pix->0];
                
row[2] = src[pix->1];
                
row[3] = src[pix->2];
            }
            
src += pix->stride;
        }

    
// done, unlock.
    
IGraphics->UnlockBitMap(lock);


    
// Copy to vram_bm
    
int32 blt_result IGraphics->BltBitMapTags(BLITA_Sourceuser_bmBLITA_Destvram_bm,
        
BLITA_WidthwidthBLITA_HeightheightTAG_END);
    
IDOS->Printf("BltBitMapTags result: %ld\n"blt_result);

    
// Update bitmap.image
    
IIntuition->SetAttrs(bitmapObj,
        
BITMAP_BitMapvram_bm,
        
BITMAP_Widthwidth,
        
BITMAP_Heightheight,
        
TAG_END);
    
IDOS->Printf("Updated bitmap.image\n");

    
IIntuition->RefreshWindowFrame(window);
}


Then in the main i do:

int main()
{
   ......
   
LockPubScreen();
   
   
render();
   
    
// Create bitmap gadget
    
bitmapObj IIntuition->NewObject(NULL"bitmap.image",
        
BITMAP_BitMapvram_bm,
        
BITMAP_Widthw,
        
BITMAP_Heighth,
        
BITMAP_Screenpubscreen,
        
TAG_END);
    if (!
bitmapObj) {
        
IDOS->Printf("Failed to create bitmapObj\n");
        goto 
cleanup;
    }

    .... 
winobj creationg ...
    
    
UnLockPubScreen();

    ... + 
main loop in which handle when to call render() again ....
}


So, the first call to render() works perfectly. Everything displays correctly, with no issues. However, on the second call, I often encounter a lockup, either during SetAttrs on the bitmap.image or on RefreshWindowFrame().

When I add more Printf() calls in between, it seems to introduce a delay that allows something to complete, and the lockup sometimes disappears. But when I add more code, the lockups return.

I’m sure I’m missing something critical, like waiting for BltBitMapTags to finish or something similar. It feels like a classic race/timing condition, but I seem to lock/unlock bitmaps when needed, so what’s going wrong? I’m using two bitmaps specifically to avoid unpredictable behavior—doing all the work in the RAM-based bitmap and then blitting to the VRAM bitmap afterward—and yet, it still feels like I’m doing something wrong.

Also, another question: What is the fastest way to display bitmaps on AmigaOS 4 currently? Is BltBitMapTags the best option? Is it accelerated by compositing? If not, should I use compositing instead?

And which approach is better:

Load all data into one large bitmap and navigate through it (but this could be problematic since bitmaps are limited in size, probably 2048x2048 or something like that), or
Load all the data into memory, then create bitmaps each time and blit them as needed? However, constantly creating and freeing bitmaps for every change seems excessive to me.

Thanks for your answers in advance!

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Correct way to work with RGB/ARGB bitmaps?
Home away from home
Home away from home


See User information
You called the first render() before you created the bitmapobjet if that code is right.

But other wise next render you delete the bitmap whilst attached to the bitmapobject, that wont go down well.

Go to top
Re: Correct way to work with RGB/ARGB bitmaps?
Home away from home
Home away from home


See User information
@kas1e
Quote:
Is BltBitMapTags the best option? Is it accelerated by compositing? If not, should I use compositing instead?
The internal BltBitMapTags() implementation should be based on CompositeTags(), at least on supported gfx cards (ATIRadeon.chip, RadeonHD.chip and RadeonRX.chip).
Using CompositeTags() yourself gives your more control, but shouldn't make much difference for the speed.

Go to top
Re: Correct way to work with RGB/ARGB bitmaps?
Home away from home
Home away from home


See User information
@broadblues
Quote:

You called the first render() before you created the bitmapobjet if that code is right.

But other wise next render you delete the bitmap whilst attached to the bitmapobject, that wont go down well


Yeah, were in hope for some reverted logic, but in end turns out it better to go flat one, one after another..

@joerg
Do you know if there restrictions on bitmap size starting from which it's no more hardware accelerated ? I just noticed, that when i have bitmaps bigger that 2048x2048 (or something around that, but no more that 3000x3000 for sure), things start be slower and slower

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Correct way to work with RGB/ARGB bitmaps?
Just can't stay away
Just can't stay away


See User information
@kas1e

Hi, this is how I do it on mgbaGUI and denGUI:
BOOL updateButtonImage(STRPTR fnCONST_STRPTR fb_struint32 OID_btnstruct Window *pw)
{
    
Object *newobj NULL;
    
struct ExamineData *datF;
    
uint32 OID_img OID_btn 1;
DBUG("updateButtonImage() '%s'\n",fn);
    
// Check if filename exists
    
datF IDOS->ExamineObjectTags(EX_StringNameInput,fnTAG_END);
    if(
datF==NULL  &&  fb_str==NULL) { return FALSE; }

    if(
datF) {
DBUG("  ExamineObjectTags(): '%s' %s%lld bytes\n",datF->Name,"",datF->FileSize); // FileSize is int64
        
IDOS->FreeDosObject(DOS_EXAMINEDATAdatF);
        
// Create and set button/image
        
newobj IIntuition->NewObject(BitMapClassNULL//"bitmap.image",
                                       
IA_ScalableTRUE,
                                       
IA_Width,256IA_Height,224,
                                       
//BITMAP_Masking, TRUE,
                                       
BITMAP_Screen,           pw->WScreen,
                                       
BITMAP_SourceFile,       fn,
                                       
BITMAP_SelectSourceFilePREVIEWS"/_launchROM.png",
                                      
TAG_DONE);
    }
DBUG("  new image: 0x%08lx\n",newobj);
    if(
newobj) {
        
IIntuition->SetGadgetAttrs(GAD(OID_btn), pwNULLBUTTON_RenderImage,newobjTAG_DONE);
    }
    else
    {
// No image found -> show fallback string (fb_str)
        
IIntuition->SetGadgetAttrs(GAD(OID_btn), pwNULLGA_Text,fb_strTAG_DONE);
    }

DBUG("  old image: 0x%08lx (disposing)\n",OBJ(OID_img));
    
IIntuition->DisposeObjectOBJ(OID_img) );
    
OBJ(OID_img) = newobj;
    
IIntuition->RefreshGadgets(GAD(OID_btn), pwNULL);

    return 
TRUE;
}


just change/remove code to use "BITMAP_BitMap" instead of "BITMAP_SelectSourceFile"

Go to top
Re: Correct way to work with RGB/ARGB bitmaps?
Home away from home
Home away from home


See User information
@Javier
That just you set ready image, that not problem, and setting bitmap no problem. Just working with bitmaps itself are as i know nothing about their limitations and how they should be handled.

So far i got that you should lock bitmap only for getting pointer to the buffer. Also that you should use BltBitMapTags() which should be compositing accelerated, but i still dunno to what extent: i found that if bitmap are more thatn 2048x2048 all start to be much slower, like, they start to be software rendered instead.

Also, how is better to works with bitmaps to have best as possible speed ? I mean, if i have 10 1920x1080 images, between which i want to flip, should i load up all of them to the RAM at once, or load up them one by one. Just want to understand how to do it all for better speed.

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Correct way to work with RGB/ARGB bitmaps?
Just can't stay away
Just can't stay away


See User information

Go to top

  Register To Post

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2024 The XOOPS Project