Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Contributor
graysont
Posts: 35
Registered: ‎11-22-2011
My Device: Playbook
Accepted Solution

Issue with png and img_lib on some devices

I am getting reports from some users that the png images are distorted on some but not all devices when using img_load_file. I suspect that it has something to do with the Qualcomm devices, but can't seem to replicate the issue either on the simulator or the Dev Alpha device. Has anyone else experienced this or is is possibly something with just a very small subset of devices. Currently I have had only 3 reports, but there are possibly more. Any help would be appreciated or even if someone can replicate the issue. I am using the png to blit into a native window. Again it works on the simulator and Dev Alpha so likely it has something to do with the Qualcomm devices, but I don't have one to test with.
Developer
BGmot
Posts: 1,068
Registered: ‎11-24-2011
My Device: PlayBook

Re: Issue with png and img_lib on some devices

I get randomly image distortion on my DevAlpha B.

Contributor
graysont
Posts: 35
Registered: ‎11-22-2011
My Device: Playbook

Re: Issue with png and img_lib on some devices

[ Edited ]

Unfortunately this isn't random. I have experienced that as well, but usually in the browser on the Dev Alpha device. The issue I have is consistent and only does it with devices that have the Snapdragon S4 processor. Seems the other devices are fine.

Here are the gneeral steps to reproduce:
On application initialization:
screen_create_context(&ctx, SCREEN_APPLICATION_CONTEXT);
screen_create_window_type(&window, ctx, SCREEN_CHILD_WINDOW);
screen_join_window_group(window, groupArr.constData());
screen_set_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, idArr.length(), idArr.constData());
winsize[0] = deviceWidth;
winsize[1] = deviceHeight;
usage = SCREEN_USAGE_NATIVE;
screen_set_window_property_iv(window, SCREEN_PROPERTY_USAGE, &usage);
// Create the window buffers, in this application we will use two buffers.
screen_create_window_buffers(window, 2);
screen_set_window_property_iv(window, SCREEN_PROPERTY_FORMAT, &format);
screen_set_window_property_iv(window, SCREEN_PROPERTY_BUFFER_SIZE, winsize) ;
screen_set_window_property_iv(window, SCREEN_PROPERTY_SOURCE_SIZE, winsize);
screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &z);
screen_set_window_property_iv(window, SCREEN_PROPERTY_TRANSPARENCY, &screenTransparency);
// Set the window position on screen.
int pos[2] = { winrect[0], winrect[1] };
screen_set_window_property_iv(window, SCREEN_PROPERTY_POSITION, pos);
// Create Background pixmap
screen_create_pixmap(&pixmap, ctx);
usage = SCREEN_USAGE_WRITE | SCREEN_USAGE_NATIVE;
screen_set_pixmap_property_iv(pixmap, SCREEN_PROPERTY_USAGE, &usage);
screen_set_pixmap_property_iv(pixmap, SCREEN_PROPERTY_BUFFER_SIZE, pixsize);
screen_create_pixmap_buffer(pixmap);
screen_get_pixmap_property_pv(pixmap, SCREEN_PROPERTY_RENDER_BUFFERS,(void **) &pixbuf);
unsigned char *ptr = NULL;
screen_get_buffer_property_pv(pixbuf, SCREEN_PROPERTY_POINTER, (void **) &ptr);
// Code to fill pixmap pixel data goes here

// Load overlay images and create associated pixmaps and buffers
int rc;
if ((rc = img_lib_attach(&ilib)) != IMG_ERR_OK)
{
// Output errors is any
}else{
overlayimg.flags = 0;
overlayimg.format = IMG_FMT_PKLE_ARGB8888;
overlayimg.flags |= IMG_FORMAT;
if ( (rc = img_load_file(ilib, "path to image", NULL, &overlayimg)) != IMG_ERR_OK)
{
// Output error info if load fails
}
overlaysize[0] = overlayimg.w;
overlaysize[1] = overlayimg.h;
screen_create_pixmap(&overlay, ctx);
screen_set_pixmap_property_iv(overlay, SCREEN_PROPERTY_FORMAT, &format);
usage = SCREEN_USAGE_WRITE | SCREEN_USAGE_NATIVE;
screen_set_pixmap_property_iv(pointer, SCREEN_PROPERTY_BUFFER_SIZE, overlaysize);
screen_create_pixmap_buffer(overlay);
screen_get_pixmap_property_pv(overlay, SCREEN_PROPERTY_RENDER_BUFFERS,(void **) &overlaybuf);.
unsigned char *overlayptr = NULL;
screen_get_buffer_property_pv(overlaybuf, SCREEN_PROPERTY_POINTER, (void **) &overlayptr );
memcpy (overlayptr , overlayimg.access.direct.data,overlayimg.w * overlayimg.h * 4);
}

In the screen event loop:
screen_get_window_property_pv(window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **) mScreenBuf);

int blits[] = { SCREEN_BLIT_SOURCE_X, 0,
SCREEN_BLIT_SOURCE_Y, 0,
SCREEN_BLIT_SOURCE_WIDTH, bkgwidth,
SCREEN_BLIT_SOURCE_HEIGHT, bkgheight,
SCREEN_BLIT_DESTINATION_X, 0,
SCREEN_BLIT_DESTINATION_Y, 0,
SCREEN_BLIT_DESTINATION_WIDTH, deviceWidth,
SCREEN_BLIT_DESTINATION_HEIGHT, deviceHeight,
SCREEN_BLIT_END };

screen_blit(ctx, mScreenBuf[0], pixbuf, blits);
// pointer
int blitsoverlay[] = { SCREEN_BLIT_SOURCE_X, 0,
SCREEN_BLIT_SOURCE_Y, 0,
SCREEN_BLIT_SOURCE_WIDTH, overlayimg.w,
SCREEN_BLIT_SOURCE_HEIGHT, overlayimg.h,
SCREEN_BLIT_DESTINATION_X, 10,
SCREEN_BLIT_DESTINATION_Y, 10,
SCREEN_BLIT_DESTINATION_WIDTH, overlayimg.w,
SCREEN_BLIT_DESTINATION_HEIGHT, overlayimg.w,
SCREEN_BLIT_TRANSPARENCY, SCREEN_TRANSPARENCY_SOURCE_OVER,
SCREEN_BLIT_END };
screen_blit(ctx, mScreenBuf[0], overlaybuf, blitsoverlay);
screen_post_window(window, mScreenBuf[0], 1, winrect, 0);


Not too sure if anyone is doing something similar. I currently have a bug open in Developer Issues:

https://www.blackberry.com/jira/browse/BBTEN-973

It would be nice if someone who has a development device with the Snapdragon S4 processor could confirm as the only feedback I have is from those who are having issues with my app and I have been unable to replicate it with either the Dev Alpha A or the simulator.

Contributor
graysont
Posts: 35
Registered: ‎11-22-2011
My Device: Playbook

Re: Issue with png and img_lib on some devices

Added an example to the following bug report that shows the issue and is based off of the foreign window app in case anyone wants to look or see if they are doing something similar and may also have the same issue.

 

https://www.blackberry.com/jira/browse/BBTEN-973

 

 

BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Issue with png and img_lib on some devices

I'll ping the resident libimg expert :smileyhappy:

I ran into stride problems recently on a related app.  Since you are doing a memcy() from a flat buffer into a pixmap (which may be strided), I suspect you are having the same problem.  Check the stride of the buffer.. I imagine it is not equal to width * 4.

 

screen_get_buffer_property_iv(overlaybuf, SCREEN_PROPERTY_STRIDE, &stride);

 

(also, next time you post code, please insert a "code" block using the "C" icon up top there... it preserves indentation, etc.  feel free to edit your post)

 

Cheers,

Sean

Contributor
graysont
Posts: 35
Registered: ‎11-22-2011
My Device: Playbook

Re: Issue with png and img_lib on some devices

[ Edited ]
Thank-you for the advice. Would an incorrect stride only show up on Z10s with Snapdragon processors? The above code and that of the example in Developer Issues works fine on a Dev Alpha A and in the simulator with no change to the assets. I also tried uncompressed tga images and got the same issue, but again only on devices with Snapdragon processor. Could it possibly be a driver issue or maybe a Cascades problem? I saw another post talking about gel swap buffer settings where they had a similar issue, but that shouldn't affect the screen library. Lastly, I tried using QImage instead of libimg and have the same problem, so it is either something in my code or something specific to the Snapdragon processor.
BlackBerry Development Advisor
ChrisCameron
Posts: 7
Registered: ‎01-21-2013
My Device: Z10

Re: Issue with png and img_lib on some devices

[ Edited ]

Sean is probably right. Maybe on that processor the screen/overlay stride is different. Just looking at the kind of distortion you're getting looks like a stride off-by-pixels problem. Most likely the overlay stride is bigger than the libimg stride (or smaller if you have the incorrect format set up for your overlay - unlikely since it works in simulator)


Try changing this line

 

memcpy (overlayptr , overlayimg.access.direct.data,overlayimg.w * overlayimg.h * 4);

To copy the image in scanline-by-scanline, e.g. something like this (crossing my fingers for no typos):

 

for (i = 0; i < overlayimg.h; i++) {
  memcpy(overlayptr + (i * overlay_stride), overlayimg.access.direct.data + (i * overlayimg.access.direct.stride), IMG_FMT_BPL(overlayimg.format, overlayimg.w));
}

Note that I am making the distinction between overlay_stride, which was the stride Sean was referring to, and the libimg stride, stored in overlayimg.access.direct.stride. It may very well be that for ARGB8888 libimg will give you a stride of overlayimg.w*4, but you shouldn't make that assumption.

 

Edit: Darn, even crossing my fingers didn't help. Re-wrote the memcpy to make use of the IMG_FMT_BPL macro found in img.h. BPL stands for bytes-per-line, which is the word-aligned number of bytes that the pixel data takes up per scanline *not* including the stride. Also originally I forgot to update the source data pointer. In any case, Sean's new post makes the issue clearer with regards to getting the stride from screen properties, so give his code a shot.

BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Issue with png and img_lib on some devices

[ Edited ]

graysont wrote:
Thank-you for the advice. Would an incorrect stride only show up on Z10s with Snapdragon processors?

The hardware buffer striding is a function of the hardware being used, and is independent of the software.  As soon as you try to copy pixels out of a libimg (or screen) structure, you're going to have to be aware of this fact.  When I ported a similar piece of code from OMAP to Snapdragon, I ran into this problem.  If I had written my code smarter to start with (eg. not made assumptions about hardware buffer striding), then I would not have had this problem.  Please try as suggested by Chris, and copy the png buffer one scanline at a time...  Something like the following:

 

screen_get_buffer_property_iv(overlaybuf, SCREEN_PROPERTY_STRIDE, &stride);

uint8_t* src=overlayimg.access.direct.data;
uint8_t* dest = overlayptr;

for (i = 0; i < overlayimg.h; i++) {
  memcpy(dest, src, IMG_FMT_BPL(overlayimg.format, overlayimg.w));  // better than overlayimg.w*4
  src += overlayimg.access.direct.stride;
  dest += stride;
}

You'll note that in the img_t struct definitions, the access.direct struct has 2 members:  data, and stride.  This should be a hint that if you want to access to pixel data directly, you should be making use of those 2 things :smileyhappy:

 

Cheers,

Sean

Contributor
graysont
Posts: 35
Registered: ‎11-22-2011
My Device: Playbook

Re: Issue with png and img_lib on some devices

Thank-you so much!! That resolved the issue. I guess Ijust assumed that the buffer would be in the screen format specified in screen_set_pixmap_property_iv(overlay, SCREEN_PROPERTY_FORMAT, &format) and as such each pixel being 32 bits. Looks like my assumption got in the way of reality :smileysad:

Your help is very much appreciated!!

Todd
BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Issue with png and img_lib on some devices

well, the pixel formats are correct, and are both 32bpp.

it's the stride that is different. 

 

If you don't know what the stride is... it's the number of physical bytes of memory needed to store one raster of the image.  This may not always be the same number as width * 4 (in a 32bpp case), as it's possible that the hardware has been optimized for raster lines to be aligned to 1024-byte boundaries, for example.

 

In that case, you may have a 32-bpp image of dimensions 200x200, but since 200*4 is 800, you would find that the first pixel of the next row is not at offset 800, but at offset 1024.  the data between 800 and 1024 is just padding to make the GPU happy.  And in fact, your 200x200 bitmap will occupy 1024x200 bytes of memory, not 800x200.

 

Cheers,

Sean