nanogui: Thread: Re: [FIX] add alpha channel into GdDrawImage software handling


[<<] [<] Page 2 of 2 [>] [>>]
Subject: Re: Re: [nanogui] Re: Re: [FIX] add alpha channel into GdDrawImage software handling
From: "Greg Haerr" ####@####.####
Date: 12 Mar 2010 16:42:28 -0000
Message-Id: <0f0701cac202$fe3e0140$6564a8c0@winXP>

Sung Joo -

It looks like you are right!  I will study your patch again,
and accept it.  Thanks alot for your suggestions and research.
The LJ article makes some pretty good points about
how C bitfields remain the same across endianness,
and it works because big endian re-numbers the
bit order as well, making bit 0 MSBit.

For testing, I am considering building a version of
the X11 screen driver for nano-X that will allow
drawing direct to framebuffer using XDGA.  In
this way, we could test framebuffer code while running
on X11 desktop.

Currently, I'm running Linux on VMWare on an iMac.
I'm looking into how to change display modes so that
we might test RGB565/555 display modes by
emulating a different display mode.

Finally, it would be interesting, (although quite slow)
to test big-endian nano-X in the same way, using
QEMU!

Regards,

Greg


> You are saying that
> struct {
> unsigned char r:5;
> };
> allocates the TOP (MSB) bits in big endian?

Yes, in case 11110000(b)=0xF0 ,  r is 0x1e.
please refer to http://www.linuxjournal.com/node/6788/print.

>  I don't think so.
> I agree it allocates the top BYTE in big endian, but the
> bits in the byte are still allocated from 0 up, not 7 down.
> This will still allocate the LOWER 5 bits in either endian,I think.
   > So the issue is that bytes are re-ordered, but NOT bits, in little vs 
big endian.


typedef union
{
      struct { unsigned char r:5 } r;
      unsigned char v;
} BF

BF c;
c.v = 0xF0; // 11110000

then,
in a big endian   c.f.r = 0x1e
in a little endian   c.f.r = 0x10

It is tested on QEMU with arm big-endian.
(  $ qemu-armeb  a.out  )

Regards,

Sung Joo 

Subject: Re: Re: Re: [nanogui] Re: Re: [FIX] add alpha channel into GdDrawImage software handling
From: "=?utf-8?B?eXV0NjE2?=" ####@####.####
Date: 13 Mar 2010 04:27:05 -0000
Message-Id: <201003131226430721270@21cn.com>

A tip:
I have ever tested x11 16bit through VNC client.
When you connect to you linux through VNC viewer, there is a option for color level.

It seems it is in RGB565.

2010-03-13 



yut616 



发件人: Greg Haerr 
发送时间: 2010-03-13  00:42:50 
收件人: Sung Joo, Byun 
抄送: ####@####.#### 
主题: Re: Re: [nanogui] Re: Re: [FIX] add alpha channel into GdDrawImage software handling 
 
Sung Joo -
It looks like you are right!  I will study your patch again,
and accept it.  Thanks alot for your suggestions and research.
The LJ article makes some pretty good points about
how C bitfields remain the same across endianness,
and it works because big endian re-numbers the
bit order as well, making bit 0 MSBit.
For testing, I am considering building a version of
the X11 screen driver for nano-X that will allow
drawing direct to framebuffer using XDGA.  In
this way, we could test framebuffer code while running
on X11 desktop.
Currently, I'm running Linux on VMWare on an iMac.
I'm looking into how to change display modes so that
we might test RGB565/555 display modes by
emulating a different display mode.
Finally, it would be interesting, (although quite slow)
to test big-endian nano-X in the same way, using
QEMU!
Regards,
Greg
> You are saying that
> struct {
> unsigned char r:5;
> };
> allocates the TOP (MSB) bits in big endian?
Yes, in case 11110000(b)=0xF0 ,  r is 0x1e.
please refer to http://www.linuxjournal.com/node/6788/print.
>  I don't think so.
> I agree it allocates the top BYTE in big endian, but the
> bits in the byte are still allocated from 0 up, not 7 down.
> This will still allocate the LOWER 5 bits in either endian,I think.
   > So the issue is that bytes are re-ordered, but NOT bits, in little vs 
big endian.
typedef union
{
      struct { unsigned char r:5 } r;
      unsigned char v;
} BF
BF c;
c.v = 0xF0; // 11110000
then,
in a big endian   c.f.r = 0x1e
in a little endian   c.f.r = 0x10
It is tested on QEMU with arm big-endian.
(  $ qemu-armeb  a.out  )
Regards,
Sung Joo 
---------------------------------------------------------------------
To unsubscribe, e-mail: ####@####.####
For additional commands, e-mail: ####@####.####
Subject: Re: Re: [nanogui] Re: Re: [FIX] add alpha channel into GdDrawImage software handling
From: "Greg Haerr" ####@####.####
Date: 18 Mar 2010 18:51:59 -0000
Message-Id: <0df701cac6cc$06d59890$0300a8c0@RDP>

I am continuing my study of bit-endianness, and have
studied your patch as well as the interesting LJ article.

However, in the section "Endianess of IP", a
recommendation is given to
reverse the bitfield declarations of two 4-bit
fields, based on the value of an include file
constant in asm/byteorder.h: __BIG_ENDIAN_BITFIELDS.

Your code assumes the same order for declaration
of the unsigned char r:5, g:6, b:5 structure.
Shouldn't we have to look at the __BIG or
__LITTLE_ENDIAN_BITFIELDS define in
asm/byteorder.h?  What is the setting for the
armeb system you tested?

Regards,

Greg


: Endian confuse me. I am studing again.
: > You are saying that
: > struct {
: > unsigned char r:5;
: > };
: > allocates the TOP (MSB) bits in big endian?
:
: Yes, in case 11110000(b)=0xF0 , r is 0x1e.
: please refer to http://www.linuxjournal.com/node/6788/print.
:
: > I don't think so.
: > I agree it allocates the top BYTE in big endian, but the
: > bits in the byte are still allocated from 0 up, not 7 down.
: > This will still allocate the LOWER 5 bits in either endian,I think.
: > So the issue is that bytes are re-ordered, but NOT bits, in little vs 
big endian.
:
: typedef union
: {
: struct { unsigned char r:5 } r;
: unsigned char v;
: } BF
:
: BF c;
: c.v = 0xF0; // 11110000
:
: then,
: in a big endian c.f.r = 0x1e
: in a little endian c.f.r = 0x10
: It is tested on QEMU with arm big-endian.
: ( $ qemu-armeb a.out )
: Regards,
: Sung Joo
: 

Subject: Re: Re: [nanogui] Re: Re: [FIX] add alpha channel into GdDrawImage software handling
From: "Greg Haerr" ####@####.####
Date: 18 Mar 2010 19:47:53 -0000
Message-Id: <0e9101cac6d3$d58961b0$0300a8c0@RDP>

: Your code assumes the same order for declaration
: of the unsigned char r:5, g:6, b:5 structure.

Actually I understand now, we'll just use the
MW_CPU_BIG_ENDIAN flag and assume
that the C bitfields are allocated MSB->LSB
in the big endian case, which works without
requiring a later byte swap.

I'll apply your patch later this evening!

Regards,

Greg

Subject: RE: Re: Re: [nanogui] Re: Re: [FIX] add alpha channel into GdDrawImage software handling
From: ####@####.####
Date: 19 Mar 2010 01:18:54 -0000
Message-Id: <98fda1cf26ac6ea03f78d1e9eefda942@a51048>

Mr Haerr.
 
I agree to use MW_CPU_BIG_ENDIAN.
Because, the microwindow can support various toolchain.
 
My tested code might be applicable only for arm-linux-gcc.
 
 
I had tested the following for BIG ENDIAN case.
1) compile with -D__ARMEB__ option.
2) #include 
3) conditional compile statement is
 #if __BYTE_ORDER == __LITTLE_ENDIAN
// littile endian part
#elif __BYTE_ORDER == __BIG_ENDIAN
// big endian part
#endif
 
My ARM toolchain has "include/endian.h", "incude/bits/endian.h".
"include/bits/endian.h"'s content is the following.
 
#ifdef __ARMEB__
#define __BYTE_ORDER __BIG_ENDIAN
#else
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
Regards,
 
Sung Joo
 
 
-----Original Message-----
From: "Greg ####@####.#### 
To: "Sung Joo, ####@####.####
Cc: ####@####.####
Sent: 10-03-19(금) 04:47:25
Subject: Re: Re: [nanogui] Re: Re: [FIX] add alpha channel into GdDrawImage software handling
: Your code assumes the same order for declaration
: of the unsigned char r:5, g:6, b:5 structure.
Actually I understand now, we'll just use the
MW_CPU_BIG_ENDIAN flag and assume
that the C bitfields are allocated MSB->LSB
in the big endian case, which works without
requiring a later byte swap.
I'll apply your patch later this evening!
Regards,
Greg
Subject: Re: Re: Re: [nanogui] Re: Re: [FIX] add alpha channel into GdDrawImage software handling
From: "Greg Haerr" ####@####.####
Date: 19 Mar 2010 02:24:11 -0000
Message-Id: <040201cac70b$3f83cb50$6564a8c0@winXP>

I've added your patch to git, thanks!

However, BYTE_ORDER is not always guaranteed
the same as BITFIELD_ORDER.  That was my
point in the previous email.  Nano-X only checks
BIGENDIAN  or not in the config file, and for
now we will assume that the bitfield order also
reverses in each case.  This is not assumed with
the compiler and linux header files.  See
include/linux/byteorder/big_endian.h.

We could move to automatically determining the
byte endianness by examining include files,
but that would break some ports for the time being.
For v0.92 I think we'll leave as is.

Regards,

Greg


: I agree to use MW_CPU_BIG_ENDIAN.
: Because, the microwindow can support various toolchain.
:
: My tested code might be applicable only for arm-linux-gcc.
:
:
: I had tested the following for BIG ENDIAN case.
: 1) compile with -D__ARMEB__ option.
: 2) #include
: 3) conditional compile statement is
: #if __BYTE_ORDER == __LITTLE_ENDIAN
: // littile endian part
: #elif __BYTE_ORDER == __BIG_ENDIAN
: // big endian part
: #endif
:
: My ARM toolchain has "include/endian.h", "incude/bits/endian.h".
: "include/bits/endian.h"'s content is the following.
:
: #ifdef __ARMEB__
: #define __BYTE_ORDER __BIG_ENDIAN
: #else
: #define __BYTE_ORDER __LITTLE_ENDIAN
: #endif
: Regards,
:
: Sung Joo
:
:
: -----Original Message-----
: From: "Greg ####@####.####
: To: "Sung Joo, ####@####.####
: Cc: ####@####.####
: Sent: 10-03-19(금) 04:47:25
: Subject: Re: Re: [nanogui] Re: Re: [FIX] add alpha channel into 
GdDrawImage software handling
:: Your code assumes the same order for declaration
:: of the unsigned char r:5, g:6, b:5 structure.
: Actually I understand now, we'll just use the
: MW_CPU_BIG_ENDIAN flag and assume
: that the C bitfields are allocated MSB->LSB
: in the big endian case, which works without
: requiring a later byte swap.
: I'll apply your patch later this evening!
: Regards,
: Greg
: 

Subject: Re: [nanogui] Re: Re: [FIX] add alpha channel into GdDrawImage software handling
From: "Greg Haerr" ####@####.####
Date: 22 Mar 2010 22:38:50 -0000
Message-Id: <0a1c01caca10$6f7c3920$6564a8c0@winXP>

> Why? I can see no value in beeing accurate here, because:
> a) The error of dividing by 256 instead of 255 gives you an
>    amplitude error of 0,4%. Nobody will see this - never.
>
> b) You are not accurate at all. You are doing integer division,
>    without rounding. This will give you another 0,2% (max).

Wolfgang - thanks for your excellent comments!

In looking much further into alpha blending and optimizations,
I agree with you.  The original integer alpha blend contained
two multiplies and one divide:

bg = (a*fg + (255-a)*bg)/255;

This can be rearranged algebraically without loss of any accuracy to
one multiply and one divide:

bg = ((a*(fg-bg))/255 + bg;

Finally, the divide can be replaced by an increment and
shift, providing 92% accuracy, and still exact at alpha 0
and 255.  This is very fast and accurate for the fully
translucent and opaque cases:

bg = ((a*(fg-bg+1))>>8 + bg;

I have tested all the above, and developed a macro
for the alpha blend using:

#define muldiv255(a,b)    (((a)*(b)/255)    /* slow divide*/
#define muldiv255(a,b)    (((a)*(b+1))>>8) /* fast, 92% accurate*/

allowing the alpha blend to take a very fast form:

bg += muldiv255(a, fg-bg);


> If accuracy is a problem, why not doing:
> alpha *= 257; // alpha == 0..65535
> color = (alpha * fg + (65535-alpha) * bg) >> 16;

Good idea.  However, the above muldiv255 is faster with one
less multiply.  All these methods, including yours, are
compared in an interesting article:

http://my.opera.com/Vorlath/blog/2006/12/20/project-v-advanced-alpha-blending


> An optimized loop will look very different, with very much code 
> duplication....

Agreed.

Regards,

Greg


[<<] [<] Page 2 of 2 [>] [>>]


Powered by ezmlm-browse 0.20.