×

Discussion Board

Results 1 to 9 of 9
  1. #1
    Registered User
    Join Date
    Aug 2003
    Posts
    34

    direct screen access use with bitmap and pointer addresses URGENT !!!

    Hi there,

    I have some questions concerning the direct screen access topic.

    I think they are very important for some programmers who have ask similar questions and it would be great If anyone of the Nokia experts could give us more information about it since new phones support now 16bit (or even 24bit) color (a new example would be great):

    I´m getting confused about the size of the pointers and the addresses they use.

    The pixel address is 32bit long and looks like this (right ?)

    32.................................................................1

    0000 0000 0000 0000 0000 0000 0000 0000

    not used blue(5) green(6) red(5bits) palette



    First we skip the palette data

    // fetch screen buffer address
    ….
    iScreenAddr = screenInfo.iScreenAddressValid ? (TUint16*)screenInfo.iScreenAddress : 0;
    User::LeaveIfNull(iScreenAddr);
    // skip the palette data in the beginning of frame buffer (16 entries in 12/16 bit mode)
    iScreenAddr += 16; // Important:16*2 für TUint8 Address


    Then we get the data address of the pixel, why are you using TUint8 (SDK:Address is 32bit) in the example?

    // calculate the (used) frame buffer size in bytes
    iFrameBufLen = iFlagRect.Width() * iFlagRect.Height() * 2;

    iRenderer->ShowNextImageL((TUint8*)iOffScreenBmp->DataAddress());

    Mem::Copy(iScreenAddr, iOffScreenBmp->DataAddress(), iFrameBufLen);


    I use a simple copy of the image to the framebuffer pixel by pixel

    TFileName imageLocation(KBitmapFilename);

    // load image
    iBild->Load(imageLocation,iTest);
    iFlagDataAddr = (TUint8*)iBild->DataAddress();

    Mem::FillZ(aBitmapAddr, iLength << 1);

    TInt b= (iHeight-1)*(iWidth-1)*2;

    for(TInt s = 0; s < b; s++)
    {
    Mem::Copy(aBitmapAddr +s, iFlagDataAddr +s , 1);

    //12 bit mode but what about 16bit ???
    TUint16* orgLocation = (TUint16*)aBitmapAddr + j*iWidth + i;
    TUint16* movLocation = orgLocation + (sinTable[angle % 256] * iWidth);

    // read values, hex addresses for 16bit ???
    TInt8 r = static_cast<TInt8>((*orgLocation & 0x00f) - someValue);
    //RED should be 0x001f
    TInt8 g = static_cast<TInt8>(((*orgLocation & 0x0f0) >> 4) - someValue);
    //GREEN should be 0x07ff >>5
    TInt8 b = static_cast<TInt8>(((*orgLocation & 0xf00) >> 8) - someValue);
    //BLUE should be 0xf800 >>11

    // copy the pixel data to a new location ???
    (r < 0) ? *movLocation = 0 : *movLocation = r;
    (g < 0) ? *movLocation &= 0xf0f : *movLocation |= g << 4; // <<5
    (b < 0) ? *movLocation &= 0x0ff : *movLocation |= b << 8; // <<11
    }


    The example works but when I manipulate the r,g,b values I get some strange results.
    I hope someone can help me as soon as possible. I need this information urgently !

    Thank you.

    Greetings

    h.sieber

  2. #2
    Registered User
    Join Date
    Aug 2003
    Posts
    34
    is there a chance to get a fast answer ?

  3. #3
    Registered User
    Join Date
    Aug 2003
    Posts
    34
    Hi,

    I also used this method but it is very slow and it´s not working properly (missmatch with length TUint8 and TUint32)!

    TBitmapUtil changebmp (iBild);
    changebmp.Begin(TPoint(0,0));
    TInt xPos, yPos, cWert;
    cWert=1;
    for (yPos=0; yPos<207;yPos++)
    {
    for (xPos=0; xPos<175;xPos++)
    {
    changebmp.SetPos(TPoint(xPos,yPos));
    TUint32 cpixel = changebmp.GetPixel();
    changebmp.SetPixel(40000+cWert);
    cWert++;

    changebmp.IncXPos();
    }
    }
    changebmp.End();

    I just want to get the pixel color , manipulate it and write it to the buffer using 16bit mode !

    Please help me.

    Greetings

    H.Sieber

  4. #4
    Registered User
    Join Date
    Feb 2004
    Posts
    24

    some info

    hi

    1) yes, you're right: series 60 devices have 32 bit palette at the beginning. bug be careful: UIQ devices havent;

    2) on 12bpp and 16bpp size of the pixel 2 bytes;

    3) when you copy bitmap data directly to video memory, it is essential to ensure your screen mode is same as bitmap mode;

    4) a little advise: use TUint8* everywere, just for simplicity.

    hope it helps.

  5. #5
    Registered User
    Join Date
    Aug 2003
    Posts
    34
    Thanks for the reply (but I found the answer by myself),

    by the way how should I use a TUnit8 Pointer for 16bit color ???
    I think I have to use TUnit16 !

    I found also a mistake in the dsa paper from nokia. It took me 4 DAYS (After a lot of tests, what a waste of time...)

    The rgb bits are not red -> green -> blue in 16bit mode

    The order is blue -> green -> red (bit 0 to 15) ! Please correct this. Or inform me if I´m wrong (I just tested it on a 6600 ).


    Greetings

    H. Sieber

  6. #6
    Registered User
    Join Date
    Jul 2004
    Posts
    21
    hi sieber,
    what's the dsa paper from Nokia with that mistake!? If you refeer to the "DirScrAcc" flag example, i think there is something really wrong with it and a Nokia 6600 because i tried it too and it's all greeny and bad (i think the View3, with the flag in DSA/DMA mode). Anyway, this can be fixed by changing the color depth of the screen, if i remeber it correctly..

    Anyway, i'm coding my own framework for our development team, and i really know how bad is to have to figure out this stuff by yourself and how it's stressfull trying and hanging the phone.
    I'm posting some snippet from my framework, and these are surely working because we are using it for a game.

    I'll try to explain as best as i can, sorry for some grammar-mistakes, i'm not an english guy ;-)


    Here i'm setting up the DirectScreenAccess, depending on the target platform because, you know, the emulator is different from the real device: anyway, the preprocessor can help you a lot without loosing readability.
    Code:
    	// Direct screen access
    	iDirectScreenAccess = CDirectScreenAccess::NewL(iClient, iScreenDevice, iWindow, *this);
    
    #ifdef __WINS__
        iScreenBufferBitmap = new (ELeave) CWsBitmap( iClient );
        TSize size = iScreenDevice.SizeInPixels();
        User::LeaveIfError(iScreenBufferBitmap->Create(size, KDisplayMode));
        iScreenAddrBase = (TUint16*)iScreenBufferBitmap->DataAddress();
    #else
    
    	// DSA and DMA
    
    	// fetch screen buffer address
    	TScreenInfoV01 screenInfo;
    	TPckg<TScreenInfoV01> sInfo(screenInfo);
    	UserSvr::ScreenInfo(sInfo);
    	TUint8* frameBufAddr = NULL;
    	 
    	frameBufAddr = screenInfo.iScreenAddressValid ? (TUint8*)screenInfo.iScreenAddress : 0;
    	User::LeaveIfNull(frameBufAddr);
    
    	// skip the palette data
    	frameBufAddr += 32;
    	iScreenAddrBase = (TUint16*)frameBufAddr;
    
    	// initialise the raw redraw event (used when drawing directly to frame buffer)
    	iRedraw.Set(TRawEvent::ERedraw);
    
    #endif	// __WINS__
    
    	iScreenAddr = iScreenAddrBase;
    
    	iSurface = new CSurface(iScreenAddr, iScreenDevice.SizeInPixels().iWidth, iScreenDevice.SizeInPixels().iHeight);
    
    	SetupDirectScreenAccessL();
    
    	iCanDraw = true;

    Notice we are skipping the 16 2bytes palette entries with a TUint8* pointer, so we must add 32 bytes in order to skip correctly. If it was a TUint16* pointer, we would add 16 bytes instead of 32.


    The next snippet came from my macros in order to compose a color for the 16bit color mode (EColor64K), given the RGB-triplet as a input:

    Code:
    #define MAKE_PIXEL16(R, G, B) (((R >> 3) << 11) | ((G >> 2) << 5) | (B >> 3))
    this way you can draw a single pixel by doing something like this:

    Code:
    TUint16* pixel = iScreenAddr + yourX + yourY * iScreenPitch;
    *pixel = MAKE_PIXEL16(126, 35, 89);
    It's pretty self-explanatory

    Now, if you want to get your original RGB-triplet from your 16bit encoded one, you can use those macros, but read the note then:

    Code:
    // return color components using the byte notation
    #define GETR(color) (((color >> 11) & 0x1F) << 3)
    #define GETG(color) (((color >> 5) & 0x3F) << 2)
    #define GETB(color) ((color & 0x1F) << 3)
    
    // return color components using the 565 notation
    #define GETR565(color) ( color >> 11 ) & 0x001f
    #define GETG565(color) ( color >> 6 ) & 0x001f
    #define GETB565(color) ( color & 0x001f )
    This isn't completely true, the process cannot be reversed completely because when you encode an RGB-triplet to the corresponding 16bit encoding you are loosing informations: for example, u'll try to encode an R value of 255, you'll not be able to return to the original 255 value!
    Why two version of GetR/G/B ?! Because you can extrapolate color informations in two ways, mapping the 5-bit (or 6-bit for green) to the corresponding 8-bit, or by retaining only the 5/6 bit information. So, for the previous R value of 255, you'll get "31" as the result from the GETR565, or something like 252 from the GETR one.


    As last hint, i re-propose a snippet from the dsa one:

    Code:
    	iSurface = new CSurface(iScreenAddr, iScreenDevice.SizeInPixels().iWidth, iScreenDevice.SizeInPixels().iHeight);
    This code came from my framework, so u'll do better to remove it if you wanna compile, but take it as an advise: wrap screen addresses into "Symbian-TClasses" (i don't like this naming convention so the mine is called CSurface), your coding will be seriously more comfortable


    Hope to helped some people in trouble!

  7. #7
    Registered User
    Join Date
    Aug 2003
    Posts
    34
    hi bmanuel79,

    thanks a lot for your clear response. Your solution is quite simple and better than mine ;-)

    I think this will help also others concerning RGB with DSA.

    Since I´m not very familiar with Symbian I don´t get it with the T-Classes. You change it to a C-Class ? Anyway this is not important to me.

    Greetings

    Sieber

    P.S. Hablas espanol ? Si es asi de donde vienes ?

  8. #8
    Regular Contributor
    Join Date
    Mar 2003
    Posts
    55
    hi,

    the pixel conversion same too slow >_<
    here is my code:

    Mem::Copy( iScreenAddr, 12bppBitmap->DataAddress(), 176*208*2 );
    for (TInt i=0; i<176*208; i++)
    {
    iScreenAddr[i] = ((iScreenAddr[i]&0xf00)<<4) | ((iScreenAddr[i]&0x0f0)<<3) | ((iScreenAddr[i]&0x00f)<<1);
    }

    by this way, the FPS is 41 on 7610, if replaced with:

    SystemGc().BitBlt(TPoint(0,0), 12bppBitmap);

    the FPS is 51. so maybe we should find the better way for converting pixel from 12bpp to 16bpp(565)

  9. #9
    Registered User
    Join Date
    Sep 2005
    Posts
    31

    Re: direct screen access use with bitmap and pointer addresses URGENT !!!

    Guys,

    Please help.

    I got a screen address by

    CWsBitmap *bm = new(ELeave) CWsBitmap(ws);
    TUint16 *pbScreen=(TUint16 *)bm->DataAddress();

    I am getting the raw 16bpp bitmap data.
    As mentioned in the forum, i tried the GETR565 macro and put the data into the screen address. My code looks like this


    TUint16 *s=(TUint16 *)pbScreen;
    bm->SetDisplayMode(EColor64K);
    TUint16 j=0,i=0;
    TUint16 *buf=(TUint16 *)parm->write.bitmap;
    TUint16 buf1;
    TUint16 R=0,G=0,B=0;
    for (;j<((parm->write.wRegion) *(parm->write.hRegion));j++)//176*208
    {
    buf1=buf[j];
    R=GETR565(buf1);
    G=GETG565(buf1);
    B=GETB565(buf1);
    *(s++)=MAKE_PIXEL16(R,G,B);
    }
    context->BitBlt(TPoint(0,0),bm);
    device->Update();
    }


    But i am getting the blank screen. I am trying to display one button.
    Please help

    Thanks
    Gilly

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×