9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: andrey mirtchovski <mirtchovski@gmail.com>
To: Fans of the OS Plan 9 from Bell Labs <9fans@9fans.net>
Subject: Re: [9fans] Porter-Duff alpha blending
Date: Wed,  4 Mar 2009 14:18:15 -0700	[thread overview]
Message-ID: <14ec7b180903041318r63d40ef5g4d0fc8a712e759f8@mail.gmail.com> (raw)
In-Reply-To: <49B01A8D.6040308@proweb.co.uk>

[-- Attachment #1: Type: text/plain, Size: 2550 bytes --]

that's quite interesting, and i suspect you've discovered a bug.
actually two bugs, maybe. one has to deal with drawing alpha-blended
images, the other with drawing using RGBA32...

the simplest way to trigger the second bug, which may or may not be
related to the first, is to draw using black, RGBA32 channel and full
alpha:

the following draws fine on the screen:
b = allocimage(display, Rect(0, 0, Dx(screen->r), Dy(screen->r)),
ARGB32, 0, DBlack);
draw(screen, screen->r, b, nil, ZP);

but the following draws incorrectly as blue:
allocimage(display, Rect(0, 0, Dx(screen->r), Dy(screen->r)), RGBA32,
0, DBlack);
draw(screen, screen->r, b, nil, ZP);

at this point i would suspect an endianness issue. setalpha doesn't
care about endianness, but libmemdraw does.

to add a bit more information i've taken the liberty of modifying your
program. the code attached exhibits all sorts of issues with alpha
blending and illustrates them more fully (i've also used a few of the
tricks in /sys/src/libdraw/arith.c to show the correct usage of Pt(),
ZP, color names and the like)

in this example everything is drawn over a black screen image to avoid
any effects of conversion to the real bpp of the screen. the base
image's channel type is fixed at ABGR32 because this particular
channel does not exhibit the behaviour of switching from black to blue
described at the beginning of this email. i've included a screencap
with the black image using RGBA32 so you can see the difference.

the program shows 4 different columns of 256 lines with varying levels
of alpha-blendedness (from 0xFF on top to 0x00 on bottom). the first
column draws white, second red, third green and fourth blue.

below the column a single line is drawn twice: once on the black
screen and once on the display screen directly. in the two attached
snapshots the line (created with ARGB23) is drawn correctly both on
the black image and on the display when the black image is ARGB32, but
if we switch to RGBA32 for the black image the first line gets mangled
when the whole image is displayed.

i'll leave the bit/byte swap analysis to the readers :)

ps: are you using this on native terminal? it would be very
interesting to test the program there for different values of ARGB32,
RGBA32 and ABGR32 (there's no BGRA32) and possibly under display depth
of 32bpp. i only have 9vx and drawterm to test with, unfortunately,
although i will try with osx's drawterm when i get home: that one runs
in 32bpp at all times.

cheers!

[-- Attachment #2: t.c --]
[-- Type: text/x-csrc, Size: 1223 bytes --]

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <cursor.h>

Image *col;
Image *black;

void
main(void) {
	int i;
	ulong type = ARGB32;

	newwindow("-r 0 0 800 400");
	if(initdraw(nil, nil, "tri") < 0)
		exits("initdraw");

	black = allocimage(display, Rect(0, 0, Dx(screen->r), Dy(screen->r)), ARGB32, 0, DBlack);

	for(i = 0; i < 0xff; i++) {
		col = allocimage(display, Rect(0,0,1,1), type, 1, setalpha(DWhite, 0xff-i));
		draw(black, Rect(0,i,200,i+1), col, nil, ZP);
		freeimage(col);

		col = allocimage(display, Rect(0,0,1,1), type, 1, setalpha(DRed, 0xff-i));
		draw(black, Rect(200,i,400,i+1), col, nil, ZP);
		freeimage(col);
		col = allocimage(display, Rect(0,0,1,1), type, 1, setalpha(DGreen, 0xff-i));
		draw(black, Rect(400,i,600,i+1), col, nil, ZP);
		freeimage(col);
		col = allocimage(display, Rect(0,0,1,1), type, 1, setalpha(DBlue, 0xff-i));
		draw(black, Rect(600,i,800,i+1), col, nil, ZP);
		freeimage(col);	
	}
	col = allocimage(display, Rect(0, 0, 1, 1), type, 1, DBlack);
	draw(black, Rect(0, 260, 800, 300), col, nil, ZP);
	draw(screen, screen->r, black, nil, ZP);

	draw(screen, Rect(0, 360, 800, 400), col, nil, ZP);


	flushimage(display, 1);
	sleep(10000);
	closedisplay(display);
}

[-- Attachment #3: RGBA32.png --]
[-- Type: image/png, Size: 3371 bytes --]

[-- Attachment #4: ARGB32.png --]
[-- Type: image/png, Size: 3229 bytes --]

  reply	other threads:[~2009-03-04 21:18 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-05 18:31 maht
2009-03-04 21:18 ` andrey mirtchovski [this message]
2009-03-04 23:24 ` Russ Cox
  -- strict thread matches above, loose matches on Subject: below --
2009-03-04 21:53 erik quanstrom
2009-03-04 22:01 ` andrey mirtchovski
2009-03-04 21:32 erik quanstrom
2009-03-04 21:37 ` andrey mirtchovski
2009-03-04 21:42   ` andrey mirtchovski
2009-03-04 21:44   ` erik quanstrom
2009-03-04 21:53     ` andrey mirtchovski
2009-03-04 22:03       ` erik quanstrom
2009-03-04 22:21         ` andrey mirtchovski
2009-03-04 22:22         ` Devon H. O'Dell
2009-03-04 22:45           ` andrey mirtchovski
2009-03-04 22:59             ` erik quanstrom
2009-03-04 23:05               ` andrey mirtchovski
2009-03-04 23:58             ` Charles Forsyth
2009-03-05  1:04               ` erik quanstrom
2009-03-05  1:29               ` andrey mirtchovski
2009-03-05  2:07                 ` andrey mirtchovski
2009-03-05  2:22                   ` erik quanstrom
2009-03-06  3:21                     ` andrey mirtchovski
2009-03-06 20:48                       ` Russ Cox
2009-03-06 21:42                         ` andrey mirtchovski
2009-03-08 22:33                           ` Jeff Sickel
2009-03-09 15:28                             ` Michaelian Ennis
2009-03-09 16:40                               ` Jeff Sickel
2009-03-09 14:00                         ` erik quanstrom
2009-03-09 15:32                           ` yy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=14ec7b180903041318r63d40ef5g4d0fc8a712e759f8@mail.gmail.com \
    --to=mirtchovski@gmail.com \
    --cc=9fans@9fans.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).