After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 660188 - Color corruption with software rendering at 30-bit color depth
Color corruption with software rendering at 30-bit color depth
Status: RESOLVED FIXED
Product: cogl
Classification: Platform
Component: GLX
git master
Other Linux
: Normal normal
: ---
Assigned To: Cogl maintainer(s)
Cogl maintainer(s)
Depends on:
Blocks:
 
 
Reported: 2011-09-26 22:36 UTC by Damien Leone
Modified: 2012-02-20 23:30 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Obtained result (8.07 KB, image/png)
2011-09-26 22:36 UTC, Damien Leone
  Details
Expected result (4.13 KB, image/png)
2011-09-26 22:36 UTC, Damien Leone
  Details
Rename POPCOUNTL() to _cogl_util_popcountl() and move it to cogl-util.h (3.14 KB, patch)
2011-10-22 01:56 UTC, Damien Leone
none Details | Review
cogl-types: add 30-bit color depth pixel formats X101010 and 2101010 (3.09 KB, patch)
2011-10-22 01:57 UTC, Damien Leone
reviewed Details | Review
Improve pixel format detection for fallback OpenGL rendering (6.26 KB, patch)
2011-10-22 01:57 UTC, Damien Leone
none Details | Review
Add support for X101010 and 2101010 pixel formats to fallback OpenGL rendering (2.11 KB, patch)
2011-10-22 01:58 UTC, Damien Leone
none Details | Review
cogl-types: add 30-bit color depth pixel formats X101010 and 2101010 (2.87 KB, patch)
2011-10-24 20:10 UTC, Damien Leone
none Details | Review
cogl-types: add 30-bit color depth pixel formats X101010 and 2101010 (4.05 KB, patch)
2011-10-24 20:44 UTC, Damien Leone
none Details | Review
Add 30-bit color depth pixel formats X101010 and 2101010 (5.14 KB, patch)
2011-11-21 23:49 UTC, Damien Leone
none Details | Review
Improve pixel format detection for fallback OpenGL rendering (6.31 KB, patch)
2011-11-21 23:50 UTC, Damien Leone
none Details | Review
Add support for X101010 and 2101010 pixel formats to fallback OpenGL rendering (2.11 KB, patch)
2011-11-21 23:50 UTC, Damien Leone
none Details | Review

Description Damien Leone 2011-09-26 22:36:11 UTC
Created attachment 197528 [details]
Obtained result

Overview:

Colors are not rendered correctly at 30-bit color depth (formats A2BGR10 and X2BGR10) when using software rendering. Software rendering is used as a fallback when GLX TFP could not be initialized (see bug 660181).

Steps to Reproduce:

1. Get hardware compatible with 30-bit color depth
2. startx -- -depth 30
3. Run any X client (see bug 660184 to prevent a segfault)

Actual Results:

Window decorations are corrupted. It looks like it interprets 24-bit color depth as 30-bit color depth. See attachments.
Comment 1 Damien Leone 2011-09-26 22:36:41 UTC
Created attachment 197529 [details]
Expected result
Comment 2 Robert Bragg 2011-10-01 16:32:33 UTC
Right, Cogl doesn't currently have a CoglPixelFormat for A2BGR10 or X2BGR10 and cogl-texture-pixmap-x11.c:_cogl_texture_pixmap_x11_update_image_texture is currently overly simplistic in that it only expects to handle three formats, RGB_888, RGBA_8888_PRE and 565 and it selects those solely on the bit depth.

In addition our _cogl_texture_driver_pixel_format_to_gl code would need updating to be able to convert from a new CoglPixelFormat to the equivalent GL texture format - assuming you have an extension for that? Without a corresponding GL texture format then we'd need to add some cogl-bitmap-fallback.c code for being able to do a format conversion.

I can try to help out if you are interested in adding support for this, though I don't have hardware I can test with myself.
Comment 3 Damien Leone 2011-10-03 21:20:12 UTC
Yes, I am interested in adding support for this. I have already dug a bit into the code and I would indeed appreciate some pointers.

Thanks.
Comment 4 Damien Leone 2011-10-22 01:55:41 UTC
Here is a set of patches that should fix pixel format detection on the fallback OpenGL rendering path and add support for 30-bit color depth. Input is welcome.

I am aware that I removed code for 16-bit color depth detection without re-adding it. This is because I don't seem to be able to start X at depth 16, so I couldn't test this code path:

Clutter-CRITICAL **: Unable to initialize Clutter: Unable to find suitable fbconfig for the GLX context: Failed to find any compatible fbconfigs

I will investigate this further.

Thanks.
Comment 5 Damien Leone 2011-10-22 01:56:47 UTC
Created attachment 199712 [details] [review]
Rename POPCOUNTL() to _cogl_util_popcountl() and move it to cogl-util.h

Since this function might be useful in some other parts of the code,
this commit renames it according to Cogl's naming convention and moves
it to the utilities files.
Comment 6 Damien Leone 2011-10-22 01:57:27 UTC
Created attachment 199713 [details] [review]
cogl-types: add 30-bit color depth pixel formats X101010 and 2101010

These new pixel formats are defined by setting the COGL_DEPTH_30_BIT
bit to 1 in CoglPixelFormat.

Since definitions of CoglPixelFormat have changed, projects linked
against Cogl (such as Clutter or Mutter) must be recompiled to use the
new headers.
Comment 7 Damien Leone 2011-10-22 01:57:50 UTC
Created attachment 199714 [details] [review]
Improve pixel format detection for fallback OpenGL rendering

The previous detection was based on bits per pixel only and would
consider bpp >= 24 as X888 or 8888 24-bit color depth formats.

This commit adds a utility function that returns a CoglPixelFormat
according to channel masks and color depth. This helps to add support
for more pixel formats.
Comment 8 Damien Leone 2011-10-22 01:58:04 UTC
Created attachment 199715 [details] [review]
Add support for X101010 and 2101010 pixel formats to fallback OpenGL rendering
Comment 9 Emmanuele Bassi (:ebassi) 2011-10-22 10:05:42 UTC
Review of attachment 199713 [details] [review]:

::: cogl/cogl-types.h
@@ +173,3 @@
 #define COGL_AFIRST_BIT         (1 << 6)
+#define COGL_DEPTH_30_BIT       (1 << 7)
+#define COGL_PREMULT_BIT        (1 << 8)

no, this is not possible: Cogl is API and ABI stable unless explicitly stated, and changing the meaning and value of a definition is an API break.

why can't COGL_DEPTH_30_BIT be set to 1 << 8?
Comment 10 Damien Leone 2011-10-22 17:30:55 UTC
Ok, that makes sense. That was what I did first but in that case COGL_UNPREMULT_MASK must be changed to ~COGL_PREMULT_BIT so that it covers all the bit spectrum.

I will provide a fix.

Thanks.
Comment 11 Damien Leone 2011-10-24 20:10:04 UTC
Created attachment 199862 [details] [review]
cogl-types: add 30-bit color depth pixel formats X101010 and 2101010

These new pixel formats are defined by setting the COGL_DEPTH_30_BIT
bit to 1 in CoglPixelFormat.

https://bugzilla.gnome.org/show_bug.cgi?id=660188
Comment 12 Damien Leone 2011-10-24 20:44:47 UTC
Created attachment 199865 [details] [review]
cogl-types: add 30-bit color depth pixel formats X101010 and 2101010

These new pixel formats are defined by setting the COGL_DEPTH_30_BIT
bit to 1 in CoglPixelFormat.
Comment 13 Robert Bragg 2011-11-01 20:51:01 UTC
sorry for taking quite a while to get back to you on this.

One thing I'm concerned about is that CoglPixelFormat has got into a bit of a spaghetti mess with the number of flags we now have. Having a few flags to be able to quickly answer a few common questions is quite nice (like does this have an alpha component) but I don't see much value in the _BGR flag for example and I'm not really sure we need a flag to categorize 30_BIT formats.

I think I'd like to see most new pixel formats that can't be represented uniquely with our existing flags simply be enumerated with sequential values and avoid adding more flags. We could claim the most significant byte as an enum byte like this...
                                
  enum        unused            4 bits for the bytes-per-pixel
|------| |---------------|     |--|
00000000 xxxxxxxx xxxxxxxx PFBA0000
                           ^ premult
                            ^ alpha first
                             ^ bgr order
                              ^ has alpha

In the future we can either dedicate unused bytes to more enum space or flags

New enums would be allocated (starting at 1?) for any new formats that can't uniquely be described using the existing flags.

Note: although I marked the least significant nibble as "for the bytes-per-pixel" technically that's not what they are used for exactly but it is relatively straight forward to extract a bytes-per-pixel from here and we can try to be more consistent going forward. Currently we can map the value here to bytes-per-pixel in the following way:

1 or 8   = 1 byte
2        = 3 bytes
3        = 4 bytes
4,5 or 6 = 2 bytes
7        = undefined

even though it's not a very clean mapping it's still probably good that we can extract the bytes-per-pixel from the format without needing an exhaustive switch for all the possible formats.

Actually now I come to look at this one other thing we may want to distinguish easily for all formats is which ones depend on the machine endianness and which don't. (e.g. RGBA_8888 depends on the endianness but RGB_565 doesn't). Currently we can also extract this fairly easily from the least significant nibble since the only cases that aren't endian dependent will have a value of 4, 5 or 6 in this nibble.

So in more detail the values in the lowest nibble currently mean:
1 or 8   = 1 byte
2        = 3 bytes and endianness dependent
3        = 4 bytes and endianness dependent
4,5 or 6 = 2 bytes and endianness independent
7        = undefined

That suggests to me that we could allocate three new values here:
9        = 2 bytes and endianness dependent
10       = 3 bytes and endianess independent
11       = 4 bytes and endianess independent

So (hoping you follow me so far :-)) for your new formats you could put 11 in the lowest nibble because they are 4bytes per pixel but the components aren't byte aligned so they must be independent of endianess

I think in your case because nothing is going to currently conflict if you put 11 in the lowest nibble you can even get away with not allocating any enum value out of the highest byte.

You could have:
COGL_PIXEL_FORMAT_RGB_101010 = 11,
COGL_PIXEL_FORMAT_BGR_101010 = 11 | COGL_BGR_BIT,
COGL_PIXEL_FORMAT_ARGB_2101010 = 11 | COGL_A_BIT | COGL_AFIRST_BIT,
COGL_PIXEL_FORMAT_ABGR_2101010  = 11 | COGL_A_BIT | COGL_AFIRST_BIT | COGL_BGR_BIT,

+ the _PRE formats

ok that's my current thoughts for how we can define the new pixel formats. I'll also try and chat with Neil Roberts about this to see if he has any further thoughts. Sorry to be fussy here, we haven't added new CoglPixelFormats in a while and want to make sure we have a clear approach that will continue to be able to support more formats in the future as consistently as possible.

I'll follow up with other feedback in a separate comment, possibly tomorrow now, since it's getting late here :-) thanks again for looking a this.
Comment 14 Neil Roberts 2011-11-02 16:15:02 UTC
Rob's comments look good to me however I think we should be careful with the terminology here and say "the components aren't byte aligned" instead of "endianness independent". We might want to one day add an enum for uploading data and specify the order of the components within the word instead of specifying the order within memory. This is technically then "endianness independent" but it's not really a new pixel format so we wouldn't set the flag. Ie, it would more just be like this:

#if G_BYTE_ORDER == G_BIG_ENDIAN
#define COGL_PIXEL_FORMAT_ARGB_ENDIAN_INDEPENDENT COGL_PIXEL_FORMAT_ARGB_8888
#else
#define COGL_PIXEL_FORMAT_ARGB_ENDIAN_INDEPENDENT COGL_PIXEL_FORMAT_BGRA_8888
#endif

With the formats we currently have, this "components aren't byte aligned" value is coincidentally represented by bit 2 of the format. I wonder if we should try to preserve this in case we want to quickly check that value at some point. Unfortunately it doesn't work out that the three other bits of the lowest nibble are enough to distinguish the number of bytes. But I think it would make sense to pick values for the two new non-byte-aligned formats that also have bit 2 set anyway and make sure any new byte-aligned types don't have it set.
Comment 15 Neil Roberts 2011-11-16 16:57:59 UTC
Comment on attachment 199712 [details] [review]
Rename POPCOUNTL() to _cogl_util_popcountl() and move it to cogl-util.h

Marking the popcount patch as obsolete because an equivalent patch has been pushed to master as 037c0aa88cb8eb
Comment 16 Damien Leone 2011-11-21 23:45:43 UTC
Thanks a lot for your feedback and sorry for this delayed reply.

I have re-worked my patches according to your comments. Please let me know how it looks like now.
Comment 17 Damien Leone 2011-11-21 23:49:40 UTC
Created attachment 201889 [details] [review]
Add 30-bit color depth pixel formats X101010 and 2101010

30-bit color depth formats are defined by using value 11 in the least
significant nibble of the pixel format enumeration. This nibble
encodes bytes-per-pixel and byte alignment.

The _cogl_get_format_bpp() function is updated accordingly to support
these new formats.
Comment 18 Damien Leone 2011-11-21 23:50:16 UTC
Created attachment 201890 [details] [review]
Improve pixel format detection for fallback OpenGL rendering

The previous detection was based on bits per pixel only and would
consider bpp >= 24 as X888 or 8888 24-bit color depth formats.

This commit adds a utility function that returns a CoglPixelFormat
according to channel masks and color depth. This helps to add support
for more pixel formats.
Comment 19 Damien Leone 2011-11-21 23:50:46 UTC
Created attachment 201891 [details] [review]
Add support for X101010 and 2101010 pixel formats to fallback OpenGL rendering
Comment 20 Robert Bragg 2011-12-13 14:59:59 UTC
just wanted to apologise that I haven't had time to follow up on this. I'm currently a bit snowed under. I'm on holiday next week, so hopefully I'll get a chance then to take a look.
Comment 21 Damien Leone 2012-02-08 21:59:21 UTC
Ping. Any news about that?
Comment 22 Robert Bragg 2012-02-18 00:08:14 UTC
ok, hey, yep we're still alive :-)

I'd really like to see this stuff integrated so in the last week I've been chipping a way at this and think I have a branch ready to land. I did have to edit some of your patches so I've updated the commit messages to reflect what I tweaked but still kept the attribution for your patches.

One part that I ended up reworking quite heavily though was the _cogl_util_pixel_format_from_masks() function so you'll see I have a separate commit for that now, with some of your patches rebased on top of that.

I've pushed my branch to wip/pixel-format-2101010 if you'd like to take a look; it's a bit much to attach the patches here I think.

The branch makes some clean up commits to remove the COGL_UNPREMULT_MASK, COGL_UNORDERED_MASK and COGL_PIXEL_FORMAT_{24,32} defines since these were undocumented and being miss used in Cogl.

On that branch you can ignore the patches before "moves and renames _cogl_get_format_bpp"

Although I now have a graphics card I can test this with, I'm not currently in a good position to do that so for now it would be good if you would be able to test the branch works for you if that's not too much trouble.

My hope is that next week Neil will be able to review the branch and we can land it.

- Regards
Comment 23 Robert Bragg 2012-02-20 23:30:29 UTC
Ok Neil has reviewed the patches and flagged a couple of things that I fixed and so I've now landed the patches in master.

Thanks for pushing for this.